/* * Copyright 2008-2009 LinkedIn, Inc * * Licensed under the Apache License, Version 2.0 (the "License"); you may not * use this file except in compliance with the License. You may obtain a copy of * the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the * License for the specific language governing permissions and limitations under * the License. */ package voldemort.utils; import java.lang.reflect.Constructor; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; /** * Utilities for reflection * * */ public class ReflectUtils { /** * Get the property name of a method name. For example the property name of * setSomeValue would be someValue. Names not beginning with set or get are * not changed. * * @param name The name to process * @return The property name */ public static String getPropertyName(String name) { if(name != null && (name.startsWith("get") || name.startsWith("set"))) { StringBuilder b = new StringBuilder(name); b.delete(0, 3); b.setCharAt(0, Character.toLowerCase(b.charAt(0))); return b.toString(); } else { return name; } } /** * Load the given class using the default constructor * * @param className The name of the class * @return The class object */ public static Class<?> loadClass(String className) { try { return Class.forName(className); } catch(ClassNotFoundException e) { throw new IllegalArgumentException(e); } } /** * Load the given class using a specific class loader. * * @param className The name of the class * @param cl The Class Loader to be used for finding the class. * @return The class object */ public static Class<?> loadClass(String className, ClassLoader cl) { try { return Class.forName(className, false, cl); } catch(ClassNotFoundException e) { throw new IllegalArgumentException(e); } } /** * Call the no-arg constructor for the given class * * @param <T> The type of the thing to construct * @param klass The class * @return The constructed thing */ public static <T> T callConstructor(Class<T> klass) { return callConstructor(klass, new Class<?>[0], new Object[0]); } /** * Call the constructor for the given class, inferring the correct types for * the arguments. This could be confusing if there are multiple constructors * with the same number of arguments and the values themselves don't * disambiguate. * * @param klass The class to construct * @param args The arguments * @return The constructed value */ public static <T> T callConstructor(Class<T> klass, Object[] args) { Class<?>[] klasses = new Class[args.length]; for(int i = 0; i < args.length; i++) klasses[i] = args[i].getClass(); return callConstructor(klass, klasses, args); } /** * Call the class constructor with the given arguments * * @param c The class * @param args The arguments * @return The constructed object */ public static <T> T callConstructor(Class<T> c, Class<?>[] argTypes, Object[] args) { try { Constructor<T> cons = c.getConstructor(argTypes); return cons.newInstance(args); } catch(InvocationTargetException e) { throw getCause(e); } catch(IllegalAccessException e) { throw new IllegalStateException(e); } catch(NoSuchMethodException e) { throw new IllegalArgumentException(e); } catch(InstantiationException e) { throw new IllegalArgumentException(e); } } /** * Call the named method * * @param obj The object to call the method on * @param c The class of the object * @param name The name of the method * @param args The method arguments * @return The result of the method */ public static <T> Object callMethod(Object obj, Class<T> c, String name, Class<?>[] classes, Object[] args) { try { Method m = getMethod(c, name, classes); return m.invoke(obj, args); } catch(InvocationTargetException e) { throw getCause(e); } catch(IllegalAccessException e) { throw new IllegalStateException(e); } } /** * Get the named method from the class * * @param c The class to get the method from * @param name The method name * @param argTypes The argument types * @return The method */ public static <T> Method getMethod(Class<T> c, String name, Class<?>... argTypes) { try { return c.getMethod(name, argTypes); } catch(NoSuchMethodException e) { throw new IllegalArgumentException(e); } } /** * Get the root cause of the Exception * * @param e The Exception * @return The root cause of the Exception */ private static RuntimeException getCause(InvocationTargetException e) { Throwable cause = e.getCause(); if(cause instanceof RuntimeException) throw (RuntimeException) cause; else throw new IllegalArgumentException(e.getCause()); } }