001package systems.dmx.webservice.provider; 002 003import systems.dmx.core.osgi.CoreActivator; 004import systems.dmx.core.util.JavaUtils; 005 006import org.codehaus.jettison.json.JSONObject; 007 008import java.io.InputStream; 009import java.io.IOException; 010import java.lang.annotation.Annotation; 011import java.lang.reflect.Constructor; 012import java.lang.reflect.Method; 013import java.lang.reflect.Type; 014import java.util.logging.Logger; 015 016import javax.ws.rs.WebApplicationException; 017import javax.ws.rs.core.MediaType; 018import javax.ws.rs.core.MultivaluedMap; 019import javax.ws.rs.ext.MessageBodyReader; 020import javax.ws.rs.ext.Provider; 021 022 023 024@Provider 025public class ObjectProvider implements MessageBodyReader<Object> { 026 027 // ---------------------------------------------------------------------------------------------- Instance Variables 028 029 private Logger logger = Logger.getLogger(getClass().getName()); 030 031 // -------------------------------------------------------------------------------------------------- Public Methods 032 033 // *** MessageBodyReader Implementation *** 034 035 @Override 036 public boolean isReadable(Class<?> type, Type genericType, Annotation[] annotations, MediaType mediaType) { 037 // Note: unlike equals() isCompatible() ignores parameters like "charset" in "application/json;charset=UTF-8" 038 return (getFactoryMethod(type) != null || getJSONConstructor(type) != null) && 039 mediaType.isCompatible(MediaType.APPLICATION_JSON_TYPE); 040 } 041 042 @Override 043 public Object readFrom(Class<Object> type, Type genericType, Annotation[] annotations, MediaType mediaType, 044 MultivaluedMap<String, String> httpHeaders, InputStream entityStream) 045 throws IOException, WebApplicationException { 046 try { 047 JSONObject json = new JSONObject(JavaUtils.readText(entityStream)); 048 Method method = getFactoryMethod(type); 049 if (method != null) { 050 return method.invoke(CoreActivator.getModelFactory(), json); 051 } else { 052 return getJSONConstructor(type).newInstance(json); 053 } 054 } catch (Exception e) { 055 throw new RuntimeException("Deserializing a " + type.getName() + " object failed", e); 056 } 057 } 058 059 // ------------------------------------------------------------------------------------------------- Private Methods 060 061 private Method getFactoryMethod(Class<?> type) { 062 try { 063 String methodName = "new" + type.getSimpleName(); 064 return CoreActivator.getModelFactory().getClass().getDeclaredMethod(methodName, JSONObject.class); 065 } catch (NoSuchMethodException e) { 066 return null; 067 } 068 } 069 070 private Constructor<?> getJSONConstructor(Class<?> type) { 071 try { 072 return type.getDeclaredConstructor(JSONObject.class); 073 } catch (NoSuchMethodException e) { 074 return null; 075 } 076 } 077}