package com.jdroid.java.marshaller; import com.jdroid.java.collections.Lists; import com.jdroid.java.collections.Maps; import com.jdroid.java.json.JSONArray; import java.util.Collection; import java.util.List; import java.util.Map; public class MarshallerProvider { private Map<Class<?>, Marshaller<Object, Object>> marshallers = Maps.newHashMap(); private Marshaller<Object, Object> defaultMarshaller = new DefaultMarshaller(); private MarshallerTypeEvaluator marshallerTypeEvaluator = new DefaultMarshallerTypeEvaluator(); private static final MarshallerProvider INSTANCE = new MarshallerProvider(); private MarshallerProvider() { // singleton } /** * @return The instance of this provider */ public static MarshallerProvider get() { return MarshallerProvider.INSTANCE; } public Object marshall(Object object, MarshallerMode mode, Map<String, String> extras) { if (object != null) { if (object instanceof Collection<?>) { Collection<?> collection = (Collection<?>)object; List<Object> list = Lists.newArrayList(); for (Object each : collection) { list.add(innerMarshall(each, mode, extras)); } return new JSONArray(list); } else { return innerMarshall(object, mode, extras); } } else { return null; } } public Object innerMarshall(Object object, MarshallerMode mode, Map<String, String> extras) { if (object != null) { if (object instanceof Collection<?>) { Collection<?> collection = (Collection<?>)object; List<Object> list = Lists.newArrayList(); for (Object each : collection) { list.add(innerMarshall(each, mode, extras)); } return list; } else if (object instanceof Map) { Map<Object, Object> map = (Map)object; if (map.isEmpty()) { return null; } else { Map<Object, Object> marshalledMap = Maps.newHashMap(); for (Map.Entry entry : map.entrySet()) { marshalledMap.put(entry.getKey(), innerMarshall(entry.getValue(), mode, extras)); } return marshalledMap; } } else { return getMarshaller(object).marshall(object, mode, extras); } } else { return null; } } public Marshaller<Object, Object> getMarshaller(Object marshallerType) { Class<?> clazz = marshallerTypeEvaluator.evaluate(marshallerType); return marshallers.containsKey(clazz) ? marshallers.get(clazz) : defaultMarshaller; } public void setMarshallers(Map<Class<?>, Marshaller<Object, Object>> marshallers) { this.marshallers = marshallers; } @SuppressWarnings("unchecked") public void addMarshaller(Class<?> clazz, Marshaller<? extends Object, ? extends Object> marshaller) { marshallers.put(clazz, (Marshaller<Object, Object>)marshaller); } public static interface MarshallerTypeEvaluator { public Class<?> evaluate(Object marshallerType); } private class DefaultMarshallerTypeEvaluator implements MarshallerTypeEvaluator { @Override public Class<?> evaluate(Object marshallerType) { return marshallerType.getClass(); } } public void setMarshallerTypeEvaluator(MarshallerTypeEvaluator marshallerTypeEvaluator) { this.marshallerTypeEvaluator = marshallerTypeEvaluator; } public void setDefaultMarshaller(Marshaller<Object, Object> defaultMarshaller) { this.defaultMarshaller = defaultMarshaller; } }