All Downloads are FREE. Search and download functionalities are using the official Maven repository.

io.muserver.rest.StringEntityProviders Maven / Gradle / Ivy

There is a newer version: 2.0.3
Show newest version
package io.muserver.rest;

import io.muserver.Mutils;
import io.netty.handler.codec.http.QueryStringDecoder;
import io.netty.handler.codec.http.QueryStringEncoder;

import javax.ws.rs.Consumes;
import javax.ws.rs.Produces;
import javax.ws.rs.WebApplicationException;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.MultivaluedHashMap;
import javax.ws.rs.core.MultivaluedMap;
import javax.ws.rs.ext.MessageBodyReader;
import javax.ws.rs.ext.MessageBodyWriter;
import java.io.*;
import java.lang.annotation.Annotation;
import java.lang.reflect.Type;
import java.nio.ByteBuffer;
import java.nio.CharBuffer;
import java.util.Arrays;
import java.util.List;
import java.util.Map;

import static java.util.Arrays.asList;

class StringEntityProviders {

    static final List stringEntityReaders = asList(
        StringMessageReaderWriter.INSTANCE, new FormUrlEncodedReader(), new ReaderEntityReader(), CharArrayReaderWriter.INSTANCE
    );
    static final List stringEntityWriters = asList(
        StringMessageReaderWriter.INSTANCE, CharArrayReaderWriter.INSTANCE, new FormUrlEncodedWriter()
    );


    @Produces({"text/plain", "*/*"})
    @Consumes({"text/plain", "*/*"})
    static class StringMessageReaderWriter implements MessageBodyWriter, MessageBodyReader {
        private StringMessageReaderWriter() {}
        static final StringMessageReaderWriter INSTANCE = new StringMessageReaderWriter();

        public boolean isWriteable(Class type, Type genericType, Annotation[] annotations, MediaType mediaType) {
            return String.class.equals(type);
        }

        public long getSize(String s, Class type, Type genericType, Annotation[] annotations, MediaType mediaType) {
            return s.length();
        }

        public void writeTo(String s, Class type, Type genericType, Annotation[] annotations, MediaType mediaType, MultivaluedMap httpHeaders, OutputStream entityStream) throws IOException, WebApplicationException {
            entityStream.write(s.getBytes(EntityProviders.charsetFor(mediaType)));
        }

        public boolean isReadable(Class type, Type genericType, Annotation[] annotations, MediaType mediaType) {
            return String.class.equals(type);
        }

        public String readFrom(Class type, Type genericType, Annotation[] annotations, MediaType mediaType, MultivaluedMap httpHeaders, InputStream entityStream) throws IOException, WebApplicationException {
            if (!EntityProviders.requestHasContent(httpHeaders)) {
                return "";
            }
            return new String(Mutils.toByteArray(entityStream, 2048), EntityProviders.charsetFor(mediaType));
        }
    }

    @Produces({"text/plain", "*/*"})
    @Consumes({"text/plain", "*/*"})
    static class CharArrayReaderWriter implements MessageBodyWriter, MessageBodyReader {
        private CharArrayReaderWriter() {}
        static final CharArrayReaderWriter INSTANCE = new CharArrayReaderWriter();


        @Override
        public boolean isReadable(Class type, Type genericType, Annotation[] annotations, MediaType mediaType) {
            return type.isArray() && type.getComponentType().equals(char.class);
        }

        @Override
        public char[] readFrom(Class type, Type genericType, Annotation[] annotations, MediaType mediaType, MultivaluedMap httpHeaders, InputStream entityStream) throws IOException, WebApplicationException {
            if (!EntityProviders.requestHasContent(httpHeaders)) {
                return new char[0];
            }
            InputStreamReader reader = new InputStreamReader(entityStream, EntityProviders.charsetFor(mediaType));
            CharArrayWriter charArrayWriter = new CharArrayWriter();
            char[] buffer = new char[2048];
            int read;
            while ((read = reader.read(buffer)) > -1) {
                charArrayWriter.write(buffer, 0, read);
            }
            return charArrayWriter.toCharArray();
        }

        @Override
        public boolean isWriteable(Class type, Type genericType, Annotation[] annotations, MediaType mediaType) {
            return type.isArray() && type.getComponentType().equals(char.class);
        }

        @Override
        public long getSize(char[] chars, Class type, Type genericType, Annotation[] annotations, MediaType mediaType) {
            return chars.length;
        }

        @Override
        public void writeTo(char[] chars, Class type, Type genericType, Annotation[] annotations, MediaType mediaType, MultivaluedMap httpHeaders, OutputStream entityStream) throws IOException, WebApplicationException {
            ByteBuffer bb = EntityProviders.charsetFor(mediaType).encode(CharBuffer.wrap(chars));
            byte[] bytes = new byte[bb.remaining()];
            bb.get(bytes);
            entityStream.write(bytes);
            Arrays.fill(bb.array(), (byte)0); // if returning char[] arrays, it might be because it's a password etc, so blank it out
        }
    }

    @Consumes("*/*")
    static class ReaderEntityReader implements MessageBodyReader {
        public boolean isReadable(Class type, Type genericType, Annotation[] annotations, MediaType mediaType) {
            return Reader.class.isAssignableFrom(type);
        }
        public Reader readFrom(Class type, Type genericType, Annotation[] annotations, MediaType mediaType, MultivaluedMap httpHeaders, InputStream entityStream) throws IOException, WebApplicationException {
            return new InputStreamReader(entityStream, EntityProviders.charsetFor(mediaType));
        }
    }

    @Consumes("application/x-www-form-urlencoded")
    static class FormUrlEncodedReader implements MessageBodyReader> {

        @Override
        public boolean isReadable(Class type, Type genericType, Annotation[] annotations, MediaType mediaType) {
            return MultivaluedMap.class.isAssignableFrom(type);
        }

        @Override
        public MultivaluedMap readFrom(Class> type, Type genericType, Annotation[] annotations, MediaType mediaType, MultivaluedMap httpHeaders, InputStream entityStream) throws IOException, WebApplicationException {
            if (!EntityProviders.requestHasContent(httpHeaders)) {
                return new MultivaluedHashMap<>();
            }
            String body = new String(Mutils.toByteArray(entityStream, 2048), EntityProviders.charsetFor(mediaType));
            QueryStringDecoder formDecoder = new QueryStringDecoder(body, false);
            Map> parameters = formDecoder.parameters();
            MultivaluedHashMap form = new MultivaluedHashMap<>();
            for (Map.Entry> entry : parameters.entrySet()) {
                form.put(entry.getKey(), entry.getValue());
            }
            return form;
        }
    }

    @Produces("application/x-www-form-urlencoded")
    static class FormUrlEncodedWriter implements MessageBodyWriter> {
        @Override
        public boolean isWriteable(Class type, Type genericType, Annotation[] annotations, MediaType mediaType) {
            return MultivaluedMap.class.isAssignableFrom(type);
        }

        @Override
        public long getSize(MultivaluedMap stringStringMultivaluedMap, Class type, Type genericType, Annotation[] annotations, MediaType mediaType) {
            return -1;
        }

        @Override
        public void writeTo(MultivaluedMap form, Class type, Type genericType, Annotation[] annotations, MediaType mediaType, MultivaluedMap httpHeaders, OutputStream entityStream) throws IOException, WebApplicationException {
            QueryStringEncoder encoder = new QueryStringEncoder("");
            for (Map.Entry> entry : form.entrySet()) {
                for (String value : entry.getValue()) {
                    encoder.addParam(entry.getKey(), value);
                }
            }
            entityStream.write(encoder.toString().substring(1).getBytes(EntityProviders.charsetFor(mediaType)));
        }
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy