/* * * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you 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 org.apache.qpid.test.utils; import java.lang.reflect.Constructor; import java.lang.reflect.Field; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; /** * Provides helper methods for operating on classes and methods using reflection. Reflection methods tend to return * a lot of checked exception so writing code to use them can be tedious and harder to read, especially when such errors * are not expected to occur. This class always works with {@link ReflectionUtilsException}, which is a runtime exception, * to wrap the checked exceptions raised by the standard Java reflection methods. Code using it does not normally * expect these errors to occur, usually does not have a recovery mechanism for them when they do, but is cleaner, * quicker to write and easier to read in the majority of cases. * *

*
CRC Card
Responsibilities Collaborations *
Look up Classes by name. *
Instantiate Classes by no-arg constructor. *
*/ public class ReflectionUtils { /** * Gets the Class object for a named class. * * @param className The class to get the Class object for. * * @return The Class object for the named class. */ public static Class forName(String className) { try { return Class.forName(className); } catch (ClassNotFoundException e) { throw new ReflectionUtilsException("ClassNotFoundException whilst finding class.", e); } } /** * Creates an instance of a Class, instantiated through its no-args constructor. * * @param cls The Class to instantiate. * @param The Class type. * * @return An instance of the class. */ public static T newInstance(Class cls) { try { return cls.newInstance(); } catch (InstantiationException e) { throw new ReflectionUtilsException("InstantiationException whilst instantiating class.", e); } catch (IllegalAccessException e) { throw new ReflectionUtilsException("IllegalAccessException whilst instantiating class.", e); } } /** * Calls a named method on an object with a specified set of parameters, any Java access modifier are overridden. * * @param o The object to call. * @param method The method name to call. * @param params The parameters to pass. * @param paramClasses The argument types. * * @return The return value from the method call. */ public static Object callMethodOverridingIllegalAccess(Object o, String method, Object[] params, Class[] paramClasses) { // Get the objects class. Class cls = o.getClass(); // Get the classes of the parameters. /*Class[] paramClasses = new Class[params.length]; for (int i = 0; i < params.length; i++) { paramClasses[i] = params[i].getClass(); }*/ try { // Try to find the matching method on the class. Method m = cls.getDeclaredMethod(method, paramClasses); // Make it accessible. m.setAccessible(true); // Invoke it with the parameters. return m.invoke(o, params); } catch (NoSuchMethodException e) { throw new ReflectionUtilsException("NoSuchMethodException.", e); } catch (IllegalAccessException e) { throw new ReflectionUtilsException("IllegalAccessException.", e); } catch (InvocationTargetException e) { throw new ReflectionUtilsException("InvocationTargetException", e); } } /** * Calls a named method on an object with a specified set of parameters. * * @param o The object to call. * @param method The method name to call. * @param params The parameters to pass. * * @return The return value from the method call. */ public static Object callMethod(Object o, String method, Object[] params) { // Get the objects class. Class cls = o.getClass(); // Get the classes of the parameters. Class[] paramClasses = new Class[params.length]; for (int i = 0; i < params.length; i++) { paramClasses[i] = params[i].getClass(); } try { // Try to find the matching method on the class. Method m = cls.getMethod(method, paramClasses); // Invoke it with the parameters. return m.invoke(o, params); } catch (NoSuchMethodException e) { throw new ReflectionUtilsException("NoSuchMethodException.", e); } catch (IllegalAccessException e) { throw new ReflectionUtilsException("IllegalAccessException", e); } catch (InvocationTargetException e) { throw new ReflectionUtilsException("InvocationTargetException", e); } } /** * Calls a constuctor witht the specified arguments. * * @param constructor The constructor. * @param args The arguments. * @param The Class type. * * @return An instance of the class that the constructor is for. */ public static T newInstance(Constructor constructor, Object[] args) { try { return constructor.newInstance(args); } catch (InstantiationException e) { throw new ReflectionUtilsException("InstantiationException", e); } catch (IllegalAccessException e) { throw new ReflectionUtilsException("IllegalAccessException", e); } catch (InvocationTargetException e) { throw new ReflectionUtilsException("InvocationTargetException", e); } } /** * Gets the constructor of a class that takes the specified set of arguments if any matches. If no matching * constructor is found then a runtime exception is raised. * * @param cls The class to get a constructor from. * @param args The arguments to match. * @param The class type. * * @return The constructor. */ public static Constructor getConstructor(Class cls, Class[] args) { try { return cls.getConstructor(args); } catch (NoSuchMethodException e) { throw new ReflectionUtilsException("NoSuchMethodException", e); } } @SuppressWarnings("unchecked") public static T getDeclaredField(final Object obj, final String fieldName) { try { final Field field = obj.getClass().getDeclaredField(fieldName); if (!field.isAccessible()) { field.setAccessible(true); } return (T) field.get(obj); } catch (NoSuchFieldException e) { throw new ReflectionUtilsException("Unable to read field " + fieldName + "from object " + obj, e); } catch (SecurityException e) { throw new ReflectionUtilsException("Unable to read field " + fieldName + "from object " + obj, e); } catch (IllegalArgumentException e) { throw new ReflectionUtilsException("Unable to read field " + fieldName + "from object " + obj, e); } catch (IllegalAccessException e) { throw new ReflectionUtilsException("Unable to read field " + fieldName + "from object " + obj, e); } } }