001package systems.dmx.webservice.provider;
002
003import systems.dmx.core.util.JavaUtils;
004import systems.dmx.core.util.DMXUtils;
005
006import org.codehaus.jettison.json.JSONArray;
007
008import java.io.BufferedWriter;
009import java.io.InputStream;
010import java.io.IOException;
011import java.io.OutputStream;
012import java.io.OutputStreamWriter;
013import java.lang.annotation.Annotation;
014import java.lang.reflect.ParameterizedType;
015import java.lang.reflect.Type;
016import java.util.Collection;
017import java.util.List;
018import java.util.logging.Logger;
019
020import javax.ws.rs.WebApplicationException;
021import javax.ws.rs.core.MediaType;
022import javax.ws.rs.core.MultivaluedMap;
023import javax.ws.rs.ext.MessageBodyReader;
024import javax.ws.rs.ext.MessageBodyWriter;
025import javax.ws.rs.ext.Provider;
026
027
028
029@Provider
030public class StringCollectionProvider implements MessageBodyReader<List<String>>,
031                                                 MessageBodyWriter<Collection<String>> {
032
033    // ---------------------------------------------------------------------------------------------- Instance Variables
034
035    private Logger logger = Logger.getLogger(getClass().getName());
036
037    // -------------------------------------------------------------------------------------------------- Public Methods
038
039    // *** MessageBodyReader Implementation ***
040
041    @Override
042    public boolean isReadable(Class<?> type, Type genericType, Annotation[] annotations, MediaType mediaType) {
043        if (genericType instanceof ParameterizedType) {
044            Type[] typeArgs = ((ParameterizedType) genericType).getActualTypeArguments();
045            if (type == List.class && typeArgs.length == 1 && typeArgs[0] == String.class) {
046                // Note: unlike equals() isCompatible() ignores parameters
047                // like "charset" in "application/json;charset=UTF-8"
048                if (mediaType.isCompatible(MediaType.APPLICATION_JSON_TYPE)) {
049                    return true;
050                }
051            }
052        }
053        return false;
054    }
055
056    @Override
057    public List<String> readFrom(Class<List<String>> type, Type genericType, Annotation[] annotations,
058            MediaType mediaType, MultivaluedMap<String, String> httpHeaders, InputStream entityStream)
059                                                                throws IOException, WebApplicationException {
060        try {
061            String json = JavaUtils.readText(entityStream);
062            return DMXUtils.toList(new JSONArray(json));
063        } catch (Exception e) {
064            throw new RuntimeException("Deserializing a List<String> object failed", e);
065        }
066    }
067
068    // *** MessageBodyWriter Implementation ***
069
070    @Override
071    public boolean isWriteable(Class<?> type, Type genericType, Annotation[] annotations, MediaType mediaType) {
072        if (genericType instanceof ParameterizedType) {
073            Type[] typeArgs = ((ParameterizedType) genericType).getActualTypeArguments();
074            if (Collection.class.isAssignableFrom(type) && typeArgs.length == 1 && typeArgs[0] == String.class) {
075                // Note: unlike equals() isCompatible() ignores parameters
076                // like "charset" in "application/json;charset=UTF-8"
077                if (mediaType.isCompatible(MediaType.APPLICATION_JSON_TYPE)) {
078                    return true;
079                }
080            }
081        }
082        return false;
083    }
084
085    @Override
086    public long getSize(Collection<String> strings, Class<?> type, Type genericType, Annotation[] annotations,
087                        MediaType mediaType) {
088        return -1;
089    }
090
091    @Override
092    public void writeTo(Collection<String> strings, Class<?> type, Type genericType, Annotation[] annotations,
093                        MediaType mediaType, MultivaluedMap<String, Object> httpHeaders, OutputStream entityStream)
094                        throws IOException, WebApplicationException {
095        try {
096            BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(entityStream));
097            new JSONArray(strings).write(writer);
098            writer.flush();
099        } catch (Exception e) {
100            throw new RuntimeException("Writing message body failed (" + strings + ")", e);
101        }
102    }
103}