/****************************************************************************** * Copyright (c) 2006, 2010 VMware Inc. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * and Apache License v2.0 which accompanies this distribution. * The Eclipse Public License is available at * http://www.eclipse.org/legal/epl-v10.html and the Apache License v2.0 * is available at http://www.opensource.org/licenses/apache2.0.php. * You may elect to redistribute this code under either of these licenses. * * Contributors: * VMware Inc. *****************************************************************************/ package org.eclipse.gemini.blueprint.util.internal; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; /** * Reflection related utility class. Similar to that found inside main Spring * distribution but with customizations particular to this framework. * * @see org.springframework.util.ReflectionUtils * * @author Costin Leau * */ public abstract class ReflectionUtils { /** * Runtime exception wrapper for checked exceptions thrown by invoked * methods. * * Provides a cast free method to get the actual exception. * * @author Costin Leau * */ public static class InvocationCheckedExceptionWrapper extends RuntimeException { private static final long serialVersionUID = 5496580030934775697L; public InvocationCheckedExceptionWrapper(Exception cause) { super(cause); } /** * Return the target exception. It will return a (checked) exception * rather then a {@link Throwable}. * * @return target exception */ public Exception getTargetException() { return (Exception) getCause(); } } /** * Invoke the specified {@link Method} against the supplied target object * with no arguments. The target object can be <code>null</code> when * invoking a static {@link Method}. * * <p/> This method is identical to * {@link org.springframework.util.ReflectionUtils#invokeMethod(Method, Object)} * except that if the target method throws a checked exception, the method * will throw a InvocationCheckedException. * * <p> * Thrown exceptions are handled via a call to * {@link #handleReflectionException}. * * @param method the method to invoke * @param target the target object to invoke the method on * @return the invocation result, if any * @see #invokeMethod(java.lang.reflect.Method, Object, Object[]) */ public static Object invokeMethod(Method method, Object target) { return invokeMethod(method, target, null); } /** * Invoke the specified {@link Method} against the supplied target object * with the supplied arguments. The target object can be <code>null</code> * when invoking a static {@link Method}. * * <p/> This method is identical to * {@link org.springframework.util.ReflectionUtils#invokeMethod(Method, Object)} * except that if the target method throws a checked exception, the method * will throw a InvocationCheckedException. * * <p> * Thrown exceptions are handled via a call to * {@link #handleReflectionException}. * * @param method the method to invoke * @param target the target object to invoke the method on * @param args the invocation arguments (may be <code>null</code>) * @return the invocation result, if any * @see #invokeMethod(java.lang.reflect.Method, Object, Object[]) */ public static Object invokeMethod(Method method, Object target, Object[] args) { try { return method.invoke(target, args); } catch (IllegalAccessException ex) { org.springframework.util.ReflectionUtils.handleReflectionException(ex); throw new IllegalStateException("Unexpected reflection exception - " + ex.getClass().getName() + ": " + ex.getMessage()); } catch (InvocationTargetException ex) { handleInvocationTargetException(ex); // the line above will not execute as the method above always throws // an exception return null; } } /** * Handle the given invocation target exception. Should only be called if no * checked exception is expected to be thrown by the target method. * <p> * Throws the underlying RuntimeException or Error in case of such a root * cause. Throws an InvocationCheckedException else (the main difference * from * {@link org.springframework.util.ReflectionUtils#handleInvocationTargetException(InvocationTargetException)}. * * @param ex the invocation target exception to handle */ public static void handleInvocationTargetException(InvocationTargetException ex) { Throwable cause = ex.getTargetException(); if (cause instanceof RuntimeException) { throw (RuntimeException) cause; } if (cause instanceof Error) { throw (Error) cause; } throw new InvocationCheckedExceptionWrapper((Exception) cause); } /** * Analyze the given exception and, if it's of type * {@link InvocationCheckedExceptionWrapper} then will return the actual * cause, otherwise return the original exception given. * * @param exception invocation exception * @return actual target exception, in case any wrapping took place */ public static Exception getInvocationException(Exception exception) { return (exception instanceof InvocationCheckedExceptionWrapper ? ((InvocationCheckedExceptionWrapper) exception).getTargetException() : exception); } }