package ecologylab.generic; import java.lang.reflect.Constructor; import java.lang.reflect.Field; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.lang.reflect.ParameterizedType; import java.lang.reflect.Type; /** * Utility routines for working with reflection. * * @author andruid */ public class ReflectionTools extends Debug { /** * Get the Field object with name fieldName, in thatClass. * * @param thatClass * @param fieldName * * @return The Field object in thatClass, or null if there is none accessible. */ public static Field getField(Class thatClass, String fieldName) { Field result = null; try { result = thatClass.getField(fieldName); } catch (SecurityException e) { } catch (NoSuchFieldException e) { } return result; } /** * Get the Field object with name fieldName, in thatClass. * * @param thatClass * @param fieldName * * @return The Field object in thatClass, or null if there is none accessible. */ public static Field getDeclaredField(Class thatClass, String fieldName) { Field result = null; try { result = thatClass.getDeclaredField(fieldName); } catch (SecurityException e) { } catch (NoSuchFieldException e) { } return result; } public static final Object BAD_ACCESS = new Object(); /** * Return the value of the Field in the Object, or BAD_ACCESS if it can't be accessed. * * @param that * @param field * @return */ public static Object getFieldValue(Object that, Field field) { Object result = null; try { result = field.get(that); } catch (IllegalArgumentException e) { result = BAD_ACCESS; e.printStackTrace(); } catch (IllegalAccessException e) { result = BAD_ACCESS; e.printStackTrace(); } return result; } /** * Set a reference type Field to a value. * * @param that Object that the field is in. * @param field Reference type field within that object. * @param value Value to set the reference field to. * * @return true if the set succeeds. */ public static boolean setFieldValue(Object that, Field field, Object value) { boolean result = false; try { field.set(that, value); result = true; } catch (IllegalArgumentException e) { e.printStackTrace(); } catch (IllegalAccessException e) { e.printStackTrace(); } return true; } /** * Wraps the no argument getInstance() method. * Checks to see if the class object passed in is null, or if * any exceptions are thrown by newInstance(). * * @param thatClass * @return An instance of an object of the specified class, or null if the Class object was null or * an InstantiationException or IllegalAccessException was thrown in the attempt to instantiate. */ public static<T> T getInstance(Class<T> thatClass) { T result = null; if (thatClass != null) { try { result = thatClass.newInstance(); } catch (InstantiationException e) { e.printStackTrace(); } catch (IllegalAccessException e) { e.printStackTrace(); } } return result; } /** * Wraps the no argument getInstance() method. * Checks to see if the class object passed in is null, or if * any exceptions are thrown by newInstance(). * * @param thatClass * @return An instance of an object of the specified class, or null if the Class object was null or * an InstantiationException or IllegalAccessException was thrown in the attempt to instantiate. */ public static<T> T getInstance(Class<T> thatClass, Class[] parameterTypes, Object[] args) { T result = null; if (thatClass != null) { try { Constructor<T> constructor = thatClass.getDeclaredConstructor(parameterTypes); if (constructor != null) result = constructor.newInstance(args); } catch (SecurityException e1) { e1.printStackTrace(); } catch (NoSuchMethodException e1) { e1.printStackTrace(); println(thatClass.getName() + " | ReflectionTools.getInstance() NoSuchMethodException: getDeclaredConstructor"); } catch (IllegalArgumentException e) { e.printStackTrace(); } catch (InstantiationException e) { e.printStackTrace(); } catch (IllegalAccessException e) { e.printStackTrace(); } catch (InvocationTargetException e) { Throwable cause = e.getCause(); cause.printStackTrace(); e.printStackTrace(); } } return result; } /** * Find a Method object if there is one in the context class, or return null if not. * * @param context Class to find the Method in. * @param name Name of the method. * @param types Array of Class objects indicating parameter types. * * @return The associated Method object, or null if non is accessible. */ public static Method getMethod(Class context, String name, Class[] types) { Method result = null; try { result = context.getMethod(name, types); } catch (SecurityException e) { } catch (NoSuchMethodException e) { } return result; } /** * See if the Field has the annotation in its declaration. * * @param field * @param annotationClass * @return */ public static boolean isAnnotationPresent(Field field, Class annotationClass) { return field.isAnnotationPresent(annotationClass); } /** * Get the parameterized type tokens that the generic Field was declared with. * * @param reflectType * @return */ public static Type[] getParameterizedTypeTokens(Field field) { Type reflectType = field.getGenericType(); return getParameterizedTypeTokens(reflectType); } private static Type[] getParameterizedTypeTokens(Type reflectType) { Type[] result = null; if (reflectType instanceof ParameterizedType) { ParameterizedType pType = (ParameterizedType) reflectType; result = pType.getActualTypeArguments(); } else if (reflectType instanceof Class) { Type superType = ((Class) reflectType).getGenericSuperclass(); return getParameterizedTypeTokens(superType); } return result; } /** * Invoke a method with return type void and a single argument. * * @param method * @param arg */ public static void invoke(Method method, Object context, Object arg) { Object[] args = {arg}; try { method.invoke(context, args); } catch (IllegalArgumentException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (IllegalAccessException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (InvocationTargetException e) { // TODO Auto-generated catch block e.printStackTrace(); } } public static void copyObject(final Object source,Object destination) // get the metadata class { Class cls = source.getClass(); // get all the fields of that class Field[] fields = cls.getDeclaredFields(); // iterate over that field for(int i=0;i<fields.length;i++) { Field field = fields[i]; String fieldName = field.getName(); field.setAccessible(true); // get the field value Object value = ReflectionTools.getFieldValue(source, field); if(value!=null) { // set the field value ReflectionTools.setFieldValue(destination, field, value); } } } }