package jas2.util;

import java.lang.reflect.*;

	/**
	 * The object factory is just a convenience class for creating
	 * objects from thier Class pointer. It hides some of the messiness
	 * of the java.lang.relect.* classes.
	 */

public class ObjectFactory
{

	/**
	 * Create an ObjectFactory capable of creating objects of a specific class.
	 *
	 * @param c  The class of objects to be created.
	 */

	public ObjectFactory(Class c)
	{
		m_c = c;
	}
	
	/**
	 *  Creates an object from the specified arguments
	 */

	public Object create() throws ObjectFactoryException
	{
		Object[] arg = new Object[0];
		return create(arg);
	}
	
	/**
	 *  Creates an object from the specified arguments
	 */

	public Object create(Object a1) throws ObjectFactoryException
	{
		Object[] arg = new Object[1];
		arg[0] = a1;
		return create(arg);
	}
	
	/**
	 *  Creates an object from the specified arguments
	 */

	public Object create(Object a1,Object a2) throws ObjectFactoryException
	{
		Object[] arg = new Object[2];
		arg[0] = a1;
		arg[1] = a2;
		return create(arg);
	}
	
	/**
	 *  Creates an object from the specified arguments
	 */

	public Object create(Object a1,Object a2,Object a3) throws ObjectFactoryException
	{
		Object[] arg = new Object[3];
		arg[0] = a1;
		arg[1] = a2;
		arg[2] = a3;
		return create(arg);
	}
	
	/**
	 * Checks that the class is declared public.
	 */

	public boolean checkAccess()
	{
		return Modifier.isPublic(m_c.getModifiers());
	}

	/**
	 * Checks that the class inherits from baseClass
	 */

	public boolean inheritsFrom(Class baseClass)
	{
		return baseClass.isAssignableFrom(m_c);
	}

	/**
	 *  Creates an object from the specified arguments
	 */

	public Object create(Object a1,Object a2,Object a3,Object a4) throws ObjectFactoryException
	{
		Object[] arg = new Object[4];
		arg[0] = a1;
		arg[1] = a2;
		arg[2] = a3;
		arg[3] = a4;
		return create(arg);
	}

	/**
	 *  Creates an object from the specified arguments
	 */

	public Object create(Object[] args) throws ObjectFactoryException
	{
		Class[] argc = argClass(args);
		try
		{
			Constructor x = findConstructor(argc);
			return x.newInstance(args);
		}
		catch (NoSuchMethodException e)
		{
			throw new ObjectFactoryException("Error creating object of class "+m_c,e);
		}
		catch (IllegalAccessException e)
		{
			throw new ObjectFactoryException("Error creating object of class "+m_c,e);
		}
		catch (InstantiationException e)
		{
			throw new ObjectFactoryException("Error creating object of class "+m_c,e);
		}
		catch (InvocationTargetException e)
		{
			throw new ObjectFactoryException(
				"Invocation Target Exception for class"+m_c,e.getTargetException());
		}
	}

	/**
	 *  Determines if object can be constrcted from the specified types of arguments
	 */

	public boolean canBeCreatedFrom()
	{
		Class[] argc = new Class[0];
		return canBeCreatedFrom(argc);
	}

	/**
	 *  Determines if object can be constrcted from the specified types of arguments
	 */

	public boolean canBeCreatedFrom(Class c1)
	{
		Class[] argc = new Class[1];
		argc[0] = c1;
		return canBeCreatedFrom(argc);
	}

	/**
	 *  Determines if object can be constrcted from the specified types of arguments
	 */

	public boolean canBeCreatedFrom(Class c1, Class c2)
	{
		Class[] argc = new Class[2];
		argc[0] = c1;
		argc[1] = c2;
		return canBeCreatedFrom(argc);
	}

	/**
	 *  Determines if object can be constrcted from the specified types of arguments
	 */

	public boolean canBeCreatedFrom(Class c1, Class c2, Class c3)
	{
		Class[] argc = new Class[3];
		argc[0] = c1;
		argc[1] = c2;
		argc[2] = c3;
		return canBeCreatedFrom(argc);
	}

	/**
	 *  Determines if object can be constrcted from the specified types of arguments
	 */

	public boolean canBeCreatedFrom(Class c1, Class c2, Class c3, Class c4)
	{
		Class[] argc = new Class[4];
		argc[0] = c1;
		argc[1] = c2;
		argc[2] = c3;
		argc[3] = c4;
		return canBeCreatedFrom(argc);
	}

	/** 
	 * Determines if object can be constrcted from the specified types of arguments
	 */
	
	public boolean canBeCreatedFrom(Class[] argc)
	{
		try
		{
			findConstructor(argc);
			return true;
		}
		catch (NoSuchMethodException e)
		{
			return false;
		}
	}
		
	/** 
	 * Construct a list of argument classes from a list of arguments
	 */
	
	private Class[] argClass(Object[] args)
	{
		Class[] result = new Class[args.length];

		for (int i=0; i 

Ads help maintain this website.