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}