001    package de.deepamehta.plugins.webservice.provider;
002    
003    import de.deepamehta.core.util.JavaUtils;
004    import de.deepamehta.core.util.DeepaMehtaUtils;
005    
006    import org.codehaus.jettison.json.JSONArray;
007    
008    import java.io.BufferedWriter;
009    import java.io.InputStream;
010    import java.io.IOException;
011    import java.io.OutputStream;
012    import java.io.OutputStreamWriter;
013    import java.lang.annotation.Annotation;
014    import java.lang.reflect.ParameterizedType;
015    import java.lang.reflect.Type;
016    import java.util.Collection;
017    import java.util.List;
018    import java.util.logging.Logger;
019    
020    import javax.ws.rs.WebApplicationException;
021    import javax.ws.rs.core.MediaType;
022    import javax.ws.rs.core.MultivaluedMap;
023    import javax.ws.rs.ext.MessageBodyReader;
024    import javax.ws.rs.ext.MessageBodyWriter;
025    import javax.ws.rs.ext.Provider;
026    
027    
028    
029    @Provider
030    public 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 DeepaMehtaUtils.toList(new JSONArray(json));
063            } catch (Exception e) {
064                throw new RuntimeException("Creating a List<String> from message body 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                DeepaMehtaUtils.stringsToJson(strings).write(writer);
098                writer.flush();
099            } catch (Exception e) {
100                throw new RuntimeException("Writing message body failed (" + strings + ")", e);
101            }
102        }
103    }