/* You may freely copy, distribute, modify and use this class as long as the original author attribution remains intact. See message below. Copyright (C) 2003 Christian Pesch. All Rights Reserved. */ package slash.metamusic.util; import sun.reflect.ReflectionFactory; import java.lang.reflect.Constructor; import java.lang.reflect.Field; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.security.AccessController; /** * With the help of reflection allows to * <ul> * <li>create objects without default constructor</li> * <li>get non-public fields</li> * <li>get non-public methods</li> * </ul> * * @author Christian Pesch * @version $Id: ReflectionHelper.java 439 2004-12-08 19:19:17Z cpesch $ */ public class ReflectionHelper { /** * reflection factory for obtaining serialization constructors */ private static ReflectionFactory reflectionFactory = (ReflectionFactory) AccessController.doPrivileged(new ReflectionFactory.GetReflectionFactoryAction()); /** * To create objects without a constructor */ public static Object newInstance(Class clazz) throws NoSuchMethodException, InstantiationException, InvocationTargetException, IllegalAccessException { Class initCl = Object.class; Constructor cons = initCl.getDeclaredConstructor(new Class[0]); cons = reflectionFactory.newConstructorForSerialization(clazz, cons); cons.setAccessible(true); return cons.newInstance(new Object[0]); } /** * Returns private and superclass fields */ public static Field getNonPublicField(Class clazz, String fieldName) throws NoSuchFieldException { Field field = getShadowedField(fieldName); if (field == null) { do { try { field = clazz.getDeclaredField(fieldName); } catch (NoSuchFieldException e) { } catch (Exception e) { throw new NoSuchFieldException("No such field '" + fieldName + "' in '" + clazz + "': " + e.getMessage()); } } while (field == null && (clazz = clazz.getSuperclass()) != Object.class); } if (field == null) throw new NoSuchFieldException("No such field '" + fieldName + "' in '" + clazz + "'"); return field; } /** * Returns shadowed fields */ public static Field getShadowedField(String fieldName) throws NoSuchFieldException { int index = fieldName.lastIndexOf('.'); if (index == -1) return null; String classQualifier = fieldName.substring(0, index); String fieldQualifier = fieldName.substring(index + 1); try { Class clazz = Class.forName(classQualifier); return clazz.getDeclaredField(fieldQualifier); } catch (ClassNotFoundException e) { return null; } } /** * Returns private and superclass methods */ public static Method getNonPublicMethod(Class clazz, String methodName, Class[] parameterTypes) throws NoSuchMethodException { Method method = getShadowedMethod(methodName, parameterTypes); if (method == null) { do { try { method = clazz.getDeclaredMethod(methodName, parameterTypes); } catch (NoSuchMethodException e) { } catch (Exception e) { throw new NoSuchMethodException("No such method '" + methodName + "' in '" + clazz + "': " + e.getMessage()); } } while (method == null && (clazz = clazz.getSuperclass()) != Object.class); } if (method == null) throw new NoSuchMethodException("No such method '" + methodName + "' in '" + clazz + "'"); return method; } /** * Returns shadowed methods */ public static Method getShadowedMethod(String methodName, Class[] parameterTypes) throws NoSuchMethodException { int index = methodName.lastIndexOf('.'); if (index == -1) return null; String classQualifier = methodName.substring(0, index); String methodQualifier = methodName.substring(index + 1); try { Class clazz = Class.forName(classQualifier); return clazz.getDeclaredMethod(methodQualifier, parameterTypes); } catch (ClassNotFoundException e) { return null; } } }