package org.rhq.enterprise.server.util; import java.lang.reflect.Constructor; import java.lang.reflect.InvocationTargetException; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; /** * A simple class that assists with method invocation. We should just use * the jakarta-commons MethodUtils class, but that class can't deal with * static methods, so it is useless to us. * @version $Rev$ */ public class MethodUtil { private static final Log log = LogFactory.getLog(MethodUtil.class); /** * Private constructore */ private MethodUtil() { } /* This is insanity itself, but the reflection APIs ignore inheritance. * So, if you ask for a method that accepts (Integer, HashMap, HashMap), * and the class only has (Integer, Map, Map), you won't find the method. * This method uses Class.isAssignableFrom to solve this problem. */ private static boolean isCompatible(Class[] declaredParams, Object[] params) { if (params.length != declaredParams.length) { return false; } for (int i = 0; i < params.length; i++) { if (!declaredParams[i].isInstance(params[i])) { return false; } } return true; } /** * Return the classname from the config. Useful if you want to configure a different * class to be returned in specific instances. * @param className to check for overridden value. * @return className from config or the className from parameter if not found */ public static Object getClassFromSystemProperty(String className, Object... args) { if (System.getProperties().containsKey(className)) { String overridename = System.getProperty(className); return callNewMethod(overridename, args); } return callNewMethod(className, args); } /** * Create a new instance of the classname passed in. * * @param className * @return instance of class passed in. */ private static Object callNewMethod(String className, Object... args) { Object retval = null; try { Class clazz = Thread.currentThread().getContextClassLoader().loadClass(className); if (args == null || args.length == 0) { retval = clazz.newInstance(); } else { try { Constructor[] ctors = clazz.getConstructors(); for (Constructor ctor : ctors) { if (isCompatible(ctor.getParameterTypes(), args)) { return ctor.newInstance(args); } } } catch (IllegalArgumentException e) { throw new RuntimeException(e); } catch (InvocationTargetException e) { throw new RuntimeException(e); } } } catch (InstantiationException e) { throw new RuntimeException(e); } catch (IllegalAccessException e) { throw new RuntimeException(e); } catch (ClassNotFoundException e) { throw new RuntimeException(e); } return retval; } }