/** * Invoke the given callback on all fields in the target class, going up the * class hierarchy to get all declared fields. * * @param targetClass the target class to analyze * @param fc the callback to invoke for each field */ public static void doWithFields(final Class<?> targetClass, final FieldCallback fc) throws IllegalArgumentException { doWithFields(targetClass, fc, null); }
/** * Perform the given callback operation on all matching methods of the given * class and superclasses. * <p> * The same named method occurring on subclass and superclass will appear * twice, unless excluded by a {@link MethodFilter}. * * @param targetClass class to start looking at * @param mc the callback to invoke for each method * @see #doWithMethods(Class, MethodCallback, MethodFilter) */ public static void doWithMethods(final Class<?> targetClass, final MethodCallback mc) throws IllegalArgumentException { doWithMethods(targetClass, mc, null); }
/** * Attempt to find a {@link Field field} on the supplied {@link Class} with * the supplied <code>name</code>. Searches all superclasses up to * {@link Object}. * * @param clazz the class to introspect * @param name the name of the field * @return the corresponding Field object, or <code>null</code> if not found */ public static Field findField(final Class<?> clazz, final String name) { return findField(clazz, name, null); }
/** * Handle the given reflection 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 an * InvocationTargetException with such a root cause. Throws an * IllegalStateException with an appropriate message else. * * @param ex the reflection exception to handle */ public static void handleReflectionException(final Exception ex) { if (ex instanceof NoSuchMethodException) { throw new IllegalStateException("Method not found: " + ex.getMessage()); } if (ex instanceof IllegalAccessException) { throw new IllegalStateException("Could not access method: " + ex.getMessage()); } if (ex instanceof InvocationTargetException) { handleInvocationTargetException((InvocationTargetException) ex); } if (ex instanceof RuntimeException) { throw (RuntimeException) ex; } handleUnexpectedException(ex); }
/** * Invoke the specified JDBC API {@link Method} against the supplied target * object with the supplied arguments. * * @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 * @throws SQLException the JDBC API SQLException to rethrow (if any) * @see #invokeMethod(java.lang.reflect.Method, Object, Object[]) */ public static Object invokeJdbcMethod(final Method method, final Object target, final Object[] args) throws SQLException { try { return method.invoke(target, args); } catch (final IllegalAccessException ex) { handleReflectionException(ex); } catch (final InvocationTargetException ex) { if (ex.getTargetException() instanceof SQLException) { throw (SQLException) ex.getTargetException(); } handleInvocationTargetException(ex); } throw new IllegalStateException("Should never get here"); }
/** * 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> * 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 */ public static Object invokeMethod(final Method method, final Object target, final Object[] args) { try { return method.invoke(target, args); } catch (final Exception ex) { handleReflectionException(ex); } throw new IllegalStateException("Should never get here"); }
/** * Rethrow the given {@link Throwable exception}, which is presumably the * <em>target exception</em> of an {@link InvocationTargetException}. Should * only be called if no checked exception is expected to be thrown by the * target method. * <p> * Rethrows the underlying exception cast to an {@link Exception} or * {@link Error} if appropriate; otherwise, throws an * {@link IllegalStateException}. * * @param ex the exception to rethrow * @throws Exception the rethrown exception (in case of a checked exception) */ public static void rethrowException(final Throwable ex) throws Exception { if (ex instanceof Exception) { throw (Exception) ex; } if (ex instanceof Error) { throw (Error) ex; } handleUnexpectedException(ex); }
/** * Invoke the specified JDBC API {@link Method} against the supplied target * object with no arguments. * * @param method the method to invoke * @param target the target object to invoke the method on * @return the invocation result, if any * @throws SQLException the JDBC API SQLException to rethrow (if any) * @see #invokeJdbcMethod(java.lang.reflect.Method, Object, Object[]) */ public static Object invokeJdbcMethod(final Method method, final Object target) throws SQLException { return invokeJdbcMethod(method, target, null); }
/** * Attempt to find a {@link Method} on the supplied class with the supplied * name and no parameters. Searches all superclasses up to * <code>Object</code>. * <p> * Returns <code>null</code> if no {@link Method} can be found. * * @param clazz the class to introspect * @param name the name of the method * @return the Method object, or <code>null</code> if none found */ public static Method findMethod(final Class<?> clazz, final String name) { return findMethod(clazz, name, new Class[0]); }
/** * 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> * 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(final Method method, final Object target) { return invokeMethod(method, target, null); }
public void doWith(final Field field) throws IllegalArgumentException, IllegalAccessException { makeAccessible(field); final Object srcValue = field.get(src); field.set(dest, srcValue); } }, COPYABLE_FIELDS);
/** * Get the field represented by the supplied {@link Field field object} on * the specified {@link Object target object}. In accordance with * {@link Field#get(Object)} semantics, the returned value is automatically * wrapped if the underlying field has a primitive type. * <p> * Thrown exceptions are handled via a call to * {@link #handleReflectionException(Exception)}. * * @param field the field to get * @param target the target object from which to get the field * @return the field's current value */ public static Object getField(final Field field, final Object target) { try { return field.get(target); } catch (final IllegalAccessException ex) { handleReflectionException(ex); throw new IllegalStateException("Unexpected reflection exception - " + ex.getClass().getName() + ": " + ex.getMessage()); } }
/** * Rethrow the given {@link Throwable exception}, which is presumably the * <em>target exception</em> of an {@link InvocationTargetException}. Should * only be called if no checked exception is expected to be thrown by the * target method. * <p> * Rethrows the underlying exception cast to an {@link RuntimeException} or * {@link Error} if appropriate; otherwise, throws an * {@link IllegalStateException}. * * @param ex the exception to rethrow * @throws RuntimeException the rethrown exception */ public static void rethrowRuntimeException(final Throwable ex) { if (ex instanceof RuntimeException) { throw (RuntimeException) ex; } if (ex instanceof Error) { throw (Error) ex; } handleUnexpectedException(ex); }
/** * Set the field represented by the supplied {@link Field field object} on * the specified {@link Object target object} to the specified * <code>value</code>. In accordance with {@link Field#set(Object, Object)} * semantics, the new value is automatically unwrapped if the underlying * field has a primitive type. * <p> * Thrown exceptions are handled via a call to * {@link #handleReflectionException(Exception)}. * * @param field the field to set * @param target the target object on which to set the field * @param value the value to set; may be <code>null</code> */ public static void setField(final Field field, final Object target, final Object value) { try { field.set(target, value); } catch (final IllegalAccessException ex) { handleReflectionException(ex); throw new IllegalStateException("Unexpected reflection exception - " + ex.getClass().getName() + ": " + ex.getMessage()); } }
/** * Given the source object and the destination, which must be the same class * or a subclass, copy all fields, including inherited fields. Designed to * work on objects with public no-arg constructors. * * @throws IllegalArgumentException if the arguments are incompatible */ public static void shallowCopyFieldState(final Object src, final Object dest) throws IllegalArgumentException { if (src == null) { throw new IllegalArgumentException("Source for field copy cannot be null"); } if (dest == null) { throw new IllegalArgumentException("Destination for field copy cannot be null"); } if (!src.getClass().isAssignableFrom(dest.getClass())) { throw new IllegalArgumentException("Destination class [" + dest.getClass().getName() + "] must be same or subclass as source class [" + src.getClass().getName() + "]"); } doWithFields(src.getClass(), new FieldCallback() { public void doWith(final Field field) throws IllegalArgumentException, IllegalAccessException { makeAccessible(field); final Object srcValue = field.get(src); field.set(dest, srcValue); } }, COPYABLE_FIELDS); } }
/** * Get all declared methods on the leaf class and all superclasses. Leaf * class methods are included first. */ public static Method[] getAllDeclaredMethods(final Class<?> leafClass) throws IllegalArgumentException { final List<Method> methods = new ArrayList<Method>(32); doWithMethods(leafClass, new MethodCallback() { public void doWith(final Method method) { methods.add(method); } }); return methods.toArray(new Method[methods.size()]); }