package com.ttdev.wicketpagetest; import java.lang.reflect.Constructor; import java.util.HashMap; import java.util.Map; /** * This class helps you create instances of a Class object, with constructor * argument values. * * @author Kent Tong * */ public class ObjectFactory { private static final Map<Class<?>, Class<?>> PRIMITIVE_TO_WRAPPER; static { PRIMITIVE_TO_WRAPPER = new HashMap<Class<?>, Class<?>>(); PRIMITIVE_TO_WRAPPER.put(byte.class, Byte.class); PRIMITIVE_TO_WRAPPER.put(short.class, Short.class); PRIMITIVE_TO_WRAPPER.put(int.class, Integer.class); PRIMITIVE_TO_WRAPPER.put(long.class, Long.class); PRIMITIVE_TO_WRAPPER.put(float.class, Float.class); PRIMITIVE_TO_WRAPPER.put(double.class, Double.class); PRIMITIVE_TO_WRAPPER.put(char.class, Character.class); PRIMITIVE_TO_WRAPPER.put(boolean.class, Boolean.class); } /** * Create an instance of the specified class, using the specified * constructor arguments. It will try to find a constructor that is * compatible. However, it will only use the first one that is compatible. * It will NOT find the best fit. * * @param <T> * The type of the class * @param objClass * The class from which to create instances * @param constructorArgs * The constructor arguments * @return The instance created */ @SuppressWarnings("unchecked") public <T> T create(Class<T> objClass, Object... constructorArgs) { for (Constructor<?> c : objClass.getConstructors()) { Constructor<T> ctor = (Constructor<T>) c; Class<?>[] types = ctor.getParameterTypes(); if (typesMatchingArgs(types, constructorArgs)) { try { return ctor.newInstance(constructorArgs); } catch (Exception e) { throw new RuntimeException(e); } } } throw new IllegalArgumentException( "Not matching constructor found in class: " + objClass.getName()); } private boolean typesMatchingArgs(Class<?>[] types, Object[] constructorArgs) { if (types.length != constructorArgs.length) { return false; } for (int i = 0; i < types.length; i++) { if (!isAssignableFrom(types[i], constructorArgs[i].getClass())) { return false; } } return true; } private boolean isAssignableFrom(Class<?> to, Class<?> from) { if (PRIMITIVE_TO_WRAPPER.get(from) == to || PRIMITIVE_TO_WRAPPER.get(to) == from) { return true; } return to.isAssignableFrom(from); } }