package flexjson.factories; import java.lang.reflect.Constructor; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.ParameterizedType; import java.lang.reflect.Type; import java.util.Collection; import java.util.Map; import flexjson.ClassLocator; import flexjson.JSONException; import flexjson.ObjectBinder; import flexjson.ObjectFactory; public class ClassLocatorObjectFactory implements ObjectFactory { private ClassLocator locator; public ClassLocatorObjectFactory(ClassLocator locator) { this.locator= locator; } public Object instantiate(ObjectBinder context, Object value, Type targetType, Class targetClass) { Class clazz= null; try { clazz= locator.locate(context, context.getCurrentPath()); if (clazz != null) { if (Collection.class.isAssignableFrom(clazz)) { return context.bindIntoCollection((Collection) value, (Collection<Object>) createTargetObject(clazz), targetType); } else if (Map.class.isAssignableFrom(clazz)) { if (targetType instanceof ParameterizedType) { ParameterizedType ptype= (ParameterizedType) targetType; return context.bindIntoMap((Map) value, (Map<Object, Object>) createTargetObject(clazz), ptype.getActualTypeArguments()[0], ptype.getActualTypeArguments()[1]); } else { return context.bindIntoMap((Map) value, (Map<Object, Object>) createTargetObject(clazz), null, null); } } else if (value instanceof Map) { return context.bindIntoObject((Map) value, createTargetObject(clazz), clazz); } else { return context.bindPrimitive(value, clazz); } } else { return null; } } catch (ClassNotFoundException ex) { throw new JSONException(String.format("%s: Could not find class %s", context.getCurrentPath(), ex.getMessage()), ex); } catch (IllegalAccessException e) { throw new JSONException(String.format("%s: Could not instantiate class %s", context.getCurrentPath(), clazz.getName()), e); } catch (InstantiationException e) { throw new JSONException(String.format("%s: Problem while instantiating class %s", context.getCurrentPath(), clazz.getName()), e); } catch (NoSuchMethodException e) { throw new JSONException(String.format("%s: Could not find a no-arg constructor for %s", context.getCurrentPath(), clazz.getName()), e); } catch (InvocationTargetException e) { throw new JSONException(String.format("%s: Problem while invoking the no-arg constructor for %s", context.getCurrentPath(), clazz.getName()), e); } } private Object createTargetObject(Class clazz) throws NoSuchMethodException, InstantiationException, IllegalAccessException, InvocationTargetException { Constructor constructor= clazz.getDeclaredConstructor(); constructor.setAccessible(true); Object target= constructor.newInstance(); return target; } public ClassLocator getLocator() { return locator; } }