All Downloads are FREE. Search and download functionalities are using the official Maven repository.

flexjson.factories.ClassLocatorObjectFactory Maven / Gradle / Ivy

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) createTargetObject(clazz), targetType);
				}
				else if (Map.class.isAssignableFrom(clazz))
				{
					if (targetType instanceof ParameterizedType)
					{
						ParameterizedType ptype= (ParameterizedType) targetType;
						return context.bindIntoMap((Map) value, (Map) createTargetObject(clazz), ptype.getActualTypeArguments()[0], ptype.getActualTypeArguments()[1]);
					}
					else
					{
						return context.bindIntoMap((Map) value, (Map) 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;
	}
}