Now parameterizing with <?> where appropriate.
This commit is contained in:
parent
6327b3484b
commit
d3af831334
|
|
@ -29,9 +29,9 @@ import java.util.List;
|
||||||
/**
|
/**
|
||||||
* Simple utility class for working with the reflection API and handling
|
* Simple utility class for working with the reflection API and handling
|
||||||
* reflection exceptions.
|
* reflection exceptions.
|
||||||
*
|
* <p>
|
||||||
* <p>Only intended for internal use.
|
* Only intended for internal use.
|
||||||
*
|
*
|
||||||
* @author Juergen Hoeller
|
* @author Juergen Hoeller
|
||||||
* @author Rob Harrop
|
* @author Rob Harrop
|
||||||
* @author Rod Johnson
|
* @author Rod Johnson
|
||||||
|
|
@ -43,12 +43,14 @@ public abstract class ReflectionUtils {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Attempt to find a {@link Field field} on the supplied {@link Class} with
|
* 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}.
|
* the supplied <code>name</code>. Searches all superclasses up to
|
||||||
|
* {@link Object}.
|
||||||
|
*
|
||||||
* @param clazz the class to introspect
|
* @param clazz the class to introspect
|
||||||
* @param name the name of the field
|
* @param name the name of the field
|
||||||
* @return the corresponding Field object, or <code>null</code> if not found
|
* @return the corresponding Field object, or <code>null</code> if not found
|
||||||
*/
|
*/
|
||||||
public static Field findField(Class clazz, String name) {
|
public static Field findField(Class<?> clazz, String name) {
|
||||||
return findField(clazz, name, null);
|
return findField(clazz, name, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -56,20 +58,22 @@ public abstract class ReflectionUtils {
|
||||||
* Attempt to find a {@link Field field} on the supplied {@link Class} with
|
* Attempt to find a {@link Field field} on the supplied {@link Class} with
|
||||||
* the supplied <code>name</code> and/or {@link Class type}. Searches all
|
* the supplied <code>name</code> and/or {@link Class type}. Searches all
|
||||||
* superclasses up to {@link Object}.
|
* superclasses up to {@link Object}.
|
||||||
|
*
|
||||||
* @param clazz the class to introspect
|
* @param clazz the class to introspect
|
||||||
* @param name the name of the field (may be <code>null</code> if type is specified)
|
* @param name the name of the field (may be <code>null</code> if type is
|
||||||
* @param type the type of the field (may be <code>null</code> if name is specified)
|
* specified)
|
||||||
|
* @param type the type of the field (may be <code>null</code> if name is
|
||||||
|
* specified)
|
||||||
* @return the corresponding Field object, or <code>null</code> if not found
|
* @return the corresponding Field object, or <code>null</code> if not found
|
||||||
*/
|
*/
|
||||||
public static Field findField(Class clazz, String name, Class type) {
|
public static Field findField(Class<?> clazz, String name, Class<?> type) {
|
||||||
Assert.notNull(clazz, "Class must not be null");
|
Assert.notNull(clazz, "Class must not be null");
|
||||||
Assert.isTrue(name != null || type != null, "Either name or type of the field must be specified");
|
Assert.isTrue(name != null || type != null, "Either name or type of the field must be specified");
|
||||||
Class searchType = clazz;
|
Class<?> searchType = clazz;
|
||||||
while (!Object.class.equals(searchType) && searchType != null) {
|
while (!Object.class.equals(searchType) && searchType != null) {
|
||||||
Field[] fields = searchType.getDeclaredFields();
|
Field[] fields = searchType.getDeclaredFields();
|
||||||
for (Field field : fields) {
|
for (Field field : fields) {
|
||||||
if ((name == null || name.equals(field.getName())) &&
|
if ((name == null || name.equals(field.getName())) && (type == null || type.equals(field.getType()))) {
|
||||||
(type == null || type.equals(field.getType()))) {
|
|
||||||
return field;
|
return field;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -81,11 +85,13 @@ public abstract class ReflectionUtils {
|
||||||
/**
|
/**
|
||||||
* Set the field represented by the supplied {@link Field field object} on
|
* Set the field represented by the supplied {@link Field field object} on
|
||||||
* the specified {@link Object target object} to the specified
|
* the specified {@link Object target object} to the specified
|
||||||
* <code>value</code>. In accordance with
|
* <code>value</code>. In accordance with {@link Field#set(Object, Object)}
|
||||||
* {@link Field#set(Object, Object)} semantics, the new value is
|
* semantics, the new value is automatically unwrapped if the underlying
|
||||||
* automatically unwrapped if the underlying field has a primitive type.
|
* field has a primitive type.
|
||||||
* <p>Thrown exceptions are handled via a call to
|
* <p>
|
||||||
|
* Thrown exceptions are handled via a call to
|
||||||
* {@link #handleReflectionException(Exception)}.
|
* {@link #handleReflectionException(Exception)}.
|
||||||
|
*
|
||||||
* @param field the field to set
|
* @param field the field to set
|
||||||
* @param target the target object on which to set the field
|
* @param target the target object on which to set the field
|
||||||
* @param value the value to set; may be <code>null</code>
|
* @param value the value to set; may be <code>null</code>
|
||||||
|
|
@ -96,18 +102,20 @@ public abstract class ReflectionUtils {
|
||||||
}
|
}
|
||||||
catch (IllegalAccessException ex) {
|
catch (IllegalAccessException ex) {
|
||||||
handleReflectionException(ex);
|
handleReflectionException(ex);
|
||||||
throw new IllegalStateException(
|
throw new IllegalStateException("Unexpected reflection exception - " + ex.getClass().getName() + ": "
|
||||||
"Unexpected reflection exception - " + ex.getClass().getName() + ": " + ex.getMessage());
|
+ ex.getMessage());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the field represented by the supplied {@link Field field object} on
|
* Get the field represented by the supplied {@link Field field object} on
|
||||||
* the specified {@link Object target object}. In accordance with
|
* the specified {@link Object target object}. In accordance with
|
||||||
* {@link Field#get(Object)} semantics, the returned value is
|
* {@link Field#get(Object)} semantics, the returned value is automatically
|
||||||
* automatically wrapped if the underlying field has a primitive type.
|
* wrapped if the underlying field has a primitive type.
|
||||||
* <p>Thrown exceptions are handled via a call to
|
* <p>
|
||||||
|
* Thrown exceptions are handled via a call to
|
||||||
* {@link #handleReflectionException(Exception)}.
|
* {@link #handleReflectionException(Exception)}.
|
||||||
|
*
|
||||||
* @param field the field to get
|
* @param field the field to get
|
||||||
* @param target the target object from which to get the field
|
* @param target the target object from which to get the field
|
||||||
* @return the field's current value
|
* @return the field's current value
|
||||||
|
|
@ -118,42 +126,48 @@ public abstract class ReflectionUtils {
|
||||||
}
|
}
|
||||||
catch (IllegalAccessException ex) {
|
catch (IllegalAccessException ex) {
|
||||||
handleReflectionException(ex);
|
handleReflectionException(ex);
|
||||||
throw new IllegalStateException(
|
throw new IllegalStateException("Unexpected reflection exception - " + ex.getClass().getName() + ": "
|
||||||
"Unexpected reflection exception - " + ex.getClass().getName() + ": " + ex.getMessage());
|
+ ex.getMessage());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Attempt to find a {@link Method} on the supplied class with the supplied name
|
* Attempt to find a {@link Method} on the supplied class with the supplied
|
||||||
* and no parameters. Searches all superclasses up to <code>Object</code>.
|
* name and no parameters. Searches all superclasses up to
|
||||||
* <p>Returns <code>null</code> if no {@link Method} can be found.
|
* <code>Object</code>.
|
||||||
|
* <p>
|
||||||
|
* Returns <code>null</code> if no {@link Method} can be found.
|
||||||
|
*
|
||||||
* @param clazz the class to introspect
|
* @param clazz the class to introspect
|
||||||
* @param name the name of the method
|
* @param name the name of the method
|
||||||
* @return the Method object, or <code>null</code> if none found
|
* @return the Method object, or <code>null</code> if none found
|
||||||
*/
|
*/
|
||||||
public static Method findMethod(Class clazz, String name) {
|
public static Method findMethod(Class<?> clazz, String name) {
|
||||||
return findMethod(clazz, name, new Class[0]);
|
return findMethod(clazz, name, new Class[0]);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Attempt to find a {@link Method} on the supplied class with the supplied name
|
* Attempt to find a {@link Method} on the supplied class with the supplied
|
||||||
* and parameter types. Searches all superclasses up to <code>Object</code>.
|
* name and parameter types. Searches all superclasses up to
|
||||||
* <p>Returns <code>null</code> if no {@link Method} can be found.
|
* <code>Object</code>.
|
||||||
|
* <p>
|
||||||
|
* Returns <code>null</code> if no {@link Method} can be found.
|
||||||
|
*
|
||||||
* @param clazz the class to introspect
|
* @param clazz the class to introspect
|
||||||
* @param name the name of the method
|
* @param name the name of the method
|
||||||
* @param paramTypes the parameter types of the method
|
* @param paramTypes the parameter types of the method (may be
|
||||||
* (may be <code>null</code> to indicate any signature)
|
* <code>null</code> to indicate any signature)
|
||||||
* @return the Method object, or <code>null</code> if none found
|
* @return the Method object, or <code>null</code> if none found
|
||||||
*/
|
*/
|
||||||
public static Method findMethod(Class clazz, String name, Class... paramTypes) {
|
public static Method findMethod(Class<?> clazz, String name, Class<?>... paramTypes) {
|
||||||
Assert.notNull(clazz, "Class must not be null");
|
Assert.notNull(clazz, "Class must not be null");
|
||||||
Assert.notNull(name, "Method name must not be null");
|
Assert.notNull(name, "Method name must not be null");
|
||||||
Class searchType = clazz;
|
Class<?> searchType = clazz;
|
||||||
while (searchType != null) {
|
while (searchType != null) {
|
||||||
Method[] methods = (searchType.isInterface() ? searchType.getMethods() : searchType.getDeclaredMethods());
|
Method[] methods = (searchType.isInterface() ? searchType.getMethods() : searchType.getDeclaredMethods());
|
||||||
for (Method method : methods) {
|
for (Method method : methods) {
|
||||||
if (name.equals(method.getName()) &&
|
if (name.equals(method.getName())
|
||||||
(paramTypes == null || Arrays.equals(paramTypes, method.getParameterTypes()))) {
|
&& (paramTypes == null || Arrays.equals(paramTypes, method.getParameterTypes()))) {
|
||||||
return method;
|
return method;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -166,7 +180,10 @@ public abstract class ReflectionUtils {
|
||||||
* Invoke the specified {@link Method} against the supplied target object
|
* Invoke the specified {@link Method} against the supplied target object
|
||||||
* with no arguments. The target object can be <code>null</code> when
|
* with no arguments. The target object can be <code>null</code> when
|
||||||
* invoking a static {@link Method}.
|
* invoking a static {@link Method}.
|
||||||
* <p>Thrown exceptions are handled via a call to {@link #handleReflectionException}.
|
* <p>
|
||||||
|
* Thrown exceptions are handled via a call to
|
||||||
|
* {@link #handleReflectionException}.
|
||||||
|
*
|
||||||
* @param method the method to invoke
|
* @param method the method to invoke
|
||||||
* @param target the target object to invoke the method on
|
* @param target the target object to invoke the method on
|
||||||
* @return the invocation result, if any
|
* @return the invocation result, if any
|
||||||
|
|
@ -180,7 +197,10 @@ public abstract class ReflectionUtils {
|
||||||
* Invoke the specified {@link Method} against the supplied target object
|
* Invoke the specified {@link Method} against the supplied target object
|
||||||
* with the supplied arguments. The target object can be <code>null</code>
|
* with the supplied arguments. The target object can be <code>null</code>
|
||||||
* when invoking a static {@link Method}.
|
* when invoking a static {@link Method}.
|
||||||
* <p>Thrown exceptions are handled via a call to {@link #handleReflectionException}.
|
* <p>
|
||||||
|
* Thrown exceptions are handled via a call to
|
||||||
|
* {@link #handleReflectionException}.
|
||||||
|
*
|
||||||
* @param method the method to invoke
|
* @param method the method to invoke
|
||||||
* @param target the target object to invoke the method on
|
* @param target the target object to invoke the method on
|
||||||
* @param args the invocation arguments (may be <code>null</code>)
|
* @param args the invocation arguments (may be <code>null</code>)
|
||||||
|
|
@ -197,8 +217,9 @@ public abstract class ReflectionUtils {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Invoke the specified JDBC API {@link Method} against the supplied
|
* Invoke the specified JDBC API {@link Method} against the supplied target
|
||||||
* target object with no arguments.
|
* object with no arguments.
|
||||||
|
*
|
||||||
* @param method the method to invoke
|
* @param method the method to invoke
|
||||||
* @param target the target object to invoke the method on
|
* @param target the target object to invoke the method on
|
||||||
* @return the invocation result, if any
|
* @return the invocation result, if any
|
||||||
|
|
@ -210,8 +231,9 @@ public abstract class ReflectionUtils {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Invoke the specified JDBC API {@link Method} against the supplied
|
* Invoke the specified JDBC API {@link Method} against the supplied target
|
||||||
* target object with the supplied arguments.
|
* object with the supplied arguments.
|
||||||
|
*
|
||||||
* @param method the method to invoke
|
* @param method the method to invoke
|
||||||
* @param target the target object to invoke the method on
|
* @param target the target object to invoke the method on
|
||||||
* @param args the invocation arguments (may be <code>null</code>)
|
* @param args the invocation arguments (may be <code>null</code>)
|
||||||
|
|
@ -236,11 +258,13 @@ public abstract class ReflectionUtils {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Handle the given reflection exception. Should only be called if
|
* Handle the given reflection exception. Should only be called if no
|
||||||
* no checked exception is expected to be thrown by the target method.
|
* checked exception is expected to be thrown by the target method.
|
||||||
* <p>Throws the underlying RuntimeException or Error in case of an
|
* <p>
|
||||||
|
* Throws the underlying RuntimeException or Error in case of an
|
||||||
* InvocationTargetException with such a root cause. Throws an
|
* InvocationTargetException with such a root cause. Throws an
|
||||||
* IllegalStateException with an appropriate message else.
|
* IllegalStateException with an appropriate message else.
|
||||||
|
*
|
||||||
* @param ex the reflection exception to handle
|
* @param ex the reflection exception to handle
|
||||||
*/
|
*/
|
||||||
public static void handleReflectionException(Exception ex) {
|
public static void handleReflectionException(Exception ex) {
|
||||||
|
|
@ -260,10 +284,12 @@ public abstract class ReflectionUtils {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Handle the given invocation target exception. Should only be called if
|
* Handle the given invocation target exception. Should only be called if no
|
||||||
* no checked exception is expected to be thrown by the target method.
|
* checked exception is expected to be thrown by the target method.
|
||||||
* <p>Throws the underlying RuntimeException or Error in case of such
|
* <p>
|
||||||
* a root cause. Throws an IllegalStateException else.
|
* Throws the underlying RuntimeException or Error in case of such a root
|
||||||
|
* cause. Throws an IllegalStateException else.
|
||||||
|
*
|
||||||
* @param ex the invocation target exception to handle
|
* @param ex the invocation target exception to handle
|
||||||
*/
|
*/
|
||||||
public static void handleInvocationTargetException(InvocationTargetException ex) {
|
public static void handleInvocationTargetException(InvocationTargetException ex) {
|
||||||
|
|
@ -272,12 +298,14 @@ public abstract class ReflectionUtils {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Rethrow the given {@link Throwable exception}, which is presumably the
|
* Rethrow the given {@link Throwable exception}, which is presumably the
|
||||||
* <em>target exception</em> of an {@link InvocationTargetException}.
|
* <em>target exception</em> of an {@link InvocationTargetException}. Should
|
||||||
* Should only be called if no checked exception is expected to be thrown by
|
* only be called if no checked exception is expected to be thrown by the
|
||||||
* the target method.
|
* target method.
|
||||||
* <p>Rethrows the underlying exception cast to an {@link RuntimeException}
|
* <p>
|
||||||
* or {@link Error} if appropriate; otherwise, throws an
|
* Rethrows the underlying exception cast to an {@link RuntimeException} or
|
||||||
|
* {@link Error} if appropriate; otherwise, throws an
|
||||||
* {@link IllegalStateException}.
|
* {@link IllegalStateException}.
|
||||||
|
*
|
||||||
* @param ex the exception to rethrow
|
* @param ex the exception to rethrow
|
||||||
* @throws RuntimeException the rethrown exception
|
* @throws RuntimeException the rethrown exception
|
||||||
*/
|
*/
|
||||||
|
|
@ -293,12 +321,14 @@ public abstract class ReflectionUtils {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Rethrow the given {@link Throwable exception}, which is presumably the
|
* Rethrow the given {@link Throwable exception}, which is presumably the
|
||||||
* <em>target exception</em> of an {@link InvocationTargetException}.
|
* <em>target exception</em> of an {@link InvocationTargetException}. Should
|
||||||
* Should only be called if no checked exception is expected to be thrown by
|
* only be called if no checked exception is expected to be thrown by the
|
||||||
* the target method.
|
* target method.
|
||||||
* <p>Rethrows the underlying exception cast to an {@link Exception} or
|
* <p>
|
||||||
|
* Rethrows the underlying exception cast to an {@link Exception} or
|
||||||
* {@link Error} if appropriate; otherwise, throws an
|
* {@link Error} if appropriate; otherwise, throws an
|
||||||
* {@link IllegalStateException}.
|
* {@link IllegalStateException}.
|
||||||
|
*
|
||||||
* @param ex the exception to rethrow
|
* @param ex the exception to rethrow
|
||||||
* @throws Exception the rethrown exception (in case of a checked exception)
|
* @throws Exception the rethrown exception (in case of a checked exception)
|
||||||
*/
|
*/
|
||||||
|
|
@ -314,6 +344,7 @@ public abstract class ReflectionUtils {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Throws an IllegalStateException with the given exception as root cause.
|
* Throws an IllegalStateException with the given exception as root cause.
|
||||||
|
*
|
||||||
* @param ex the unexpected exception
|
* @param ex the unexpected exception
|
||||||
*/
|
*/
|
||||||
private static void handleUnexpectedException(Throwable ex) {
|
private static void handleUnexpectedException(Throwable ex) {
|
||||||
|
|
@ -321,18 +352,19 @@ public abstract class ReflectionUtils {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Determine whether the given method explicitly declares the given exception
|
* Determine whether the given method explicitly declares the given
|
||||||
* or one of its superclasses, which means that an exception of that type
|
* exception or one of its superclasses, which means that an exception of
|
||||||
* can be propagated as-is within a reflective invocation.
|
* that type can be propagated as-is within a reflective invocation.
|
||||||
|
*
|
||||||
* @param method the declaring method
|
* @param method the declaring method
|
||||||
* @param exceptionType the exception to throw
|
* @param exceptionType the exception to throw
|
||||||
* @return <code>true</code> if the exception can be thrown as-is;
|
* @return <code>true</code> if the exception can be thrown as-is;
|
||||||
* <code>false</code> if it needs to be wrapped
|
* <code>false</code> if it needs to be wrapped
|
||||||
*/
|
*/
|
||||||
public static boolean declaresException(Method method, Class exceptionType) {
|
public static boolean declaresException(Method method, Class<?> exceptionType) {
|
||||||
Assert.notNull(method, "Method must not be null");
|
Assert.notNull(method, "Method must not be null");
|
||||||
Class[] declaredExceptions = method.getExceptionTypes();
|
Class<?>[] declaredExceptions = method.getExceptionTypes();
|
||||||
for (Class declaredException : declaredExceptions) {
|
for (Class<?> declaredException : declaredExceptions) {
|
||||||
if (declaredException.isAssignableFrom(exceptionType)) {
|
if (declaredException.isAssignableFrom(exceptionType)) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
@ -340,9 +372,9 @@ public abstract class ReflectionUtils {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Determine whether the given field is a "public static final" constant.
|
* Determine whether the given field is a "public static final" constant.
|
||||||
|
*
|
||||||
* @param field the field to check
|
* @param field the field to check
|
||||||
*/
|
*/
|
||||||
public static boolean isPublicStaticFinal(Field field) {
|
public static boolean isPublicStaticFinal(Field field) {
|
||||||
|
|
@ -352,101 +384,107 @@ public abstract class ReflectionUtils {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Determine whether the given method is an "equals" method.
|
* Determine whether the given method is an "equals" method.
|
||||||
|
*
|
||||||
* @see java.lang.Object#equals
|
* @see java.lang.Object#equals
|
||||||
*/
|
*/
|
||||||
public static boolean isEqualsMethod(Method method) {
|
public static boolean isEqualsMethod(Method method) {
|
||||||
if (method == null || !method.getName().equals("equals")) {
|
if (method == null || !method.getName().equals("equals")) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
Class[] paramTypes = method.getParameterTypes();
|
Class<?>[] paramTypes = method.getParameterTypes();
|
||||||
return (paramTypes.length == 1 && paramTypes[0] == Object.class);
|
return (paramTypes.length == 1 && paramTypes[0] == Object.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Determine whether the given method is a "hashCode" method.
|
* Determine whether the given method is a "hashCode" method.
|
||||||
|
*
|
||||||
* @see java.lang.Object#hashCode
|
* @see java.lang.Object#hashCode
|
||||||
*/
|
*/
|
||||||
public static boolean isHashCodeMethod(Method method) {
|
public static boolean isHashCodeMethod(Method method) {
|
||||||
return (method != null && method.getName().equals("hashCode") &&
|
return (method != null && method.getName().equals("hashCode") && method.getParameterTypes().length == 0);
|
||||||
method.getParameterTypes().length == 0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Determine whether the given method is a "toString" method.
|
* Determine whether the given method is a "toString" method.
|
||||||
|
*
|
||||||
* @see java.lang.Object#toString()
|
* @see java.lang.Object#toString()
|
||||||
*/
|
*/
|
||||||
public static boolean isToStringMethod(Method method) {
|
public static boolean isToStringMethod(Method method) {
|
||||||
return (method != null && method.getName().equals("toString") &&
|
return (method != null && method.getName().equals("toString") && method.getParameterTypes().length == 0);
|
||||||
method.getParameterTypes().length == 0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Make the given field accessible, explicitly setting it accessible if necessary.
|
* Make the given field accessible, explicitly setting it accessible if
|
||||||
* The <code>setAccessible(true)</code> method is only called when actually necessary,
|
* necessary. The <code>setAccessible(true)</code> method is only called
|
||||||
* to avoid unnecessary conflicts with a JVM SecurityManager (if active).
|
* when actually necessary, to avoid unnecessary conflicts with a JVM
|
||||||
|
* SecurityManager (if active).
|
||||||
|
*
|
||||||
* @param field the field to make accessible
|
* @param field the field to make accessible
|
||||||
* @see java.lang.reflect.Field#setAccessible
|
* @see java.lang.reflect.Field#setAccessible
|
||||||
*/
|
*/
|
||||||
public static void makeAccessible(Field field) {
|
public static void makeAccessible(Field field) {
|
||||||
if (!Modifier.isPublic(field.getModifiers()) ||
|
if (!Modifier.isPublic(field.getModifiers()) || !Modifier.isPublic(field.getDeclaringClass().getModifiers())) {
|
||||||
!Modifier.isPublic(field.getDeclaringClass().getModifiers())) {
|
|
||||||
field.setAccessible(true);
|
field.setAccessible(true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Make the given method accessible, explicitly setting it accessible if necessary.
|
* Make the given method accessible, explicitly setting it accessible if
|
||||||
* The <code>setAccessible(true)</code> method is only called when actually necessary,
|
* necessary. The <code>setAccessible(true)</code> method is only called
|
||||||
* to avoid unnecessary conflicts with a JVM SecurityManager (if active).
|
* when actually necessary, to avoid unnecessary conflicts with a JVM
|
||||||
|
* SecurityManager (if active).
|
||||||
|
*
|
||||||
* @param method the method to make accessible
|
* @param method the method to make accessible
|
||||||
* @see java.lang.reflect.Method#setAccessible
|
* @see java.lang.reflect.Method#setAccessible
|
||||||
*/
|
*/
|
||||||
public static void makeAccessible(Method method) {
|
public static void makeAccessible(Method method) {
|
||||||
if (!Modifier.isPublic(method.getModifiers()) ||
|
if (!Modifier.isPublic(method.getModifiers()) || !Modifier.isPublic(method.getDeclaringClass().getModifiers())) {
|
||||||
!Modifier.isPublic(method.getDeclaringClass().getModifiers())) {
|
|
||||||
method.setAccessible(true);
|
method.setAccessible(true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Make the given constructor accessible, explicitly setting it accessible if necessary.
|
* Make the given constructor accessible, explicitly setting it accessible
|
||||||
* The <code>setAccessible(true)</code> method is only called when actually necessary,
|
* if necessary. The <code>setAccessible(true)</code> method is only called
|
||||||
* to avoid unnecessary conflicts with a JVM SecurityManager (if active).
|
* when actually necessary, to avoid unnecessary conflicts with a JVM
|
||||||
|
* SecurityManager (if active).
|
||||||
|
*
|
||||||
* @param ctor the constructor to make accessible
|
* @param ctor the constructor to make accessible
|
||||||
* @see java.lang.reflect.Constructor#setAccessible
|
* @see java.lang.reflect.Constructor#setAccessible
|
||||||
*/
|
*/
|
||||||
public static void makeAccessible(Constructor ctor) {
|
public static void makeAccessible(Constructor<?> ctor) {
|
||||||
if (!Modifier.isPublic(ctor.getModifiers()) ||
|
if (!Modifier.isPublic(ctor.getModifiers()) || !Modifier.isPublic(ctor.getDeclaringClass().getModifiers())) {
|
||||||
!Modifier.isPublic(ctor.getDeclaringClass().getModifiers())) {
|
|
||||||
ctor.setAccessible(true);
|
ctor.setAccessible(true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Perform the given callback operation on all matching methods of the
|
* Perform the given callback operation on all matching methods of the given
|
||||||
* given class and superclasses.
|
* class and superclasses.
|
||||||
* <p>The same named method occurring on subclass and superclass will
|
* <p>
|
||||||
* appear twice, unless excluded by a {@link MethodFilter}.
|
* 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 targetClass class to start looking at
|
||||||
* @param mc the callback to invoke for each method
|
* @param mc the callback to invoke for each method
|
||||||
* @see #doWithMethods(Class, MethodCallback, MethodFilter)
|
* @see #doWithMethods(Class, MethodCallback, MethodFilter)
|
||||||
*/
|
*/
|
||||||
public static void doWithMethods(Class targetClass, MethodCallback mc) throws IllegalArgumentException {
|
public static void doWithMethods(Class<?> targetClass, MethodCallback mc) throws IllegalArgumentException {
|
||||||
doWithMethods(targetClass, mc, null);
|
doWithMethods(targetClass, mc, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Perform the given callback operation on all matching methods of the
|
* Perform the given callback operation on all matching methods of the given
|
||||||
* given class and superclasses.
|
* class and superclasses.
|
||||||
* <p>The same named method occurring on subclass and superclass will
|
* <p>
|
||||||
* appear twice, unless excluded by the specified {@link MethodFilter}.
|
* The same named method occurring on subclass and superclass will appear
|
||||||
|
* twice, unless excluded by the specified {@link MethodFilter}.
|
||||||
|
*
|
||||||
* @param targetClass class to start looking at
|
* @param targetClass class to start looking at
|
||||||
* @param mc the callback to invoke for each method
|
* @param mc the callback to invoke for each method
|
||||||
* @param mf the filter that determines the methods to apply the callback to
|
* @param mf the filter that determines the methods to apply the callback to
|
||||||
*/
|
*/
|
||||||
public static void doWithMethods(Class targetClass, MethodCallback mc, MethodFilter mf)
|
public static void doWithMethods(Class<?> targetClass, MethodCallback mc, MethodFilter mf)
|
||||||
throws IllegalArgumentException {
|
throws IllegalArgumentException {
|
||||||
|
|
||||||
// Keep backing up the inheritance hierarchy.
|
// Keep backing up the inheritance hierarchy.
|
||||||
|
|
@ -460,22 +498,22 @@ public abstract class ReflectionUtils {
|
||||||
mc.doWith(method);
|
mc.doWith(method);
|
||||||
}
|
}
|
||||||
catch (IllegalAccessException ex) {
|
catch (IllegalAccessException ex) {
|
||||||
throw new IllegalStateException(
|
throw new IllegalStateException("Shouldn't be illegal to access method '" + method.getName()
|
||||||
"Shouldn't be illegal to access method '" + method.getName() + "': " + ex);
|
+ "': " + ex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
targetClass = targetClass.getSuperclass();
|
targetClass = targetClass.getSuperclass();
|
||||||
}
|
} while (targetClass != null);
|
||||||
while (targetClass != null);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get all declared methods on the leaf class and all superclasses.
|
* Get all declared methods on the leaf class and all superclasses. Leaf
|
||||||
* Leaf class methods are included first.
|
* class methods are included first.
|
||||||
*/
|
*/
|
||||||
public static Method[] getAllDeclaredMethods(Class leafClass) throws IllegalArgumentException {
|
public static Method[] getAllDeclaredMethods(Class<?> leafClass) throws IllegalArgumentException {
|
||||||
final List<Method> methods = new ArrayList<Method>(32);
|
final List<Method> methods = new ArrayList<Method>(32);
|
||||||
doWithMethods(leafClass, new MethodCallback() {
|
doWithMethods(leafClass, new MethodCallback() {
|
||||||
|
|
||||||
public void doWith(Method method) {
|
public void doWith(Method method) {
|
||||||
methods.add(method);
|
methods.add(method);
|
||||||
}
|
}
|
||||||
|
|
@ -483,25 +521,26 @@ public abstract class ReflectionUtils {
|
||||||
return methods.toArray(new Method[methods.size()]);
|
return methods.toArray(new Method[methods.size()]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Invoke the given callback on all fields in the target class,
|
* Invoke the given callback on all fields in the target class, going up the
|
||||||
* going up the class hierarchy to get all declared fields.
|
* class hierarchy to get all declared fields.
|
||||||
|
*
|
||||||
* @param targetClass the target class to analyze
|
* @param targetClass the target class to analyze
|
||||||
* @param fc the callback to invoke for each field
|
* @param fc the callback to invoke for each field
|
||||||
*/
|
*/
|
||||||
public static void doWithFields(Class targetClass, FieldCallback fc) throws IllegalArgumentException {
|
public static void doWithFields(Class<?> targetClass, FieldCallback fc) throws IllegalArgumentException {
|
||||||
doWithFields(targetClass, fc, null);
|
doWithFields(targetClass, fc, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Invoke the given callback on all fields in the target class,
|
* Invoke the given callback on all fields in the target class, going up the
|
||||||
* going up the class hierarchy to get all declared fields.
|
* class hierarchy to get all declared fields.
|
||||||
|
*
|
||||||
* @param targetClass the target class to analyze
|
* @param targetClass the target class to analyze
|
||||||
* @param fc the callback to invoke for each field
|
* @param fc the callback to invoke for each field
|
||||||
* @param ff the filter that determines the fields to apply the callback to
|
* @param ff the filter that determines the fields to apply the callback to
|
||||||
*/
|
*/
|
||||||
public static void doWithFields(Class targetClass, FieldCallback fc, FieldFilter ff)
|
public static void doWithFields(Class<?> targetClass, FieldCallback fc, FieldFilter ff)
|
||||||
throws IllegalArgumentException {
|
throws IllegalArgumentException {
|
||||||
|
|
||||||
// Keep backing up the inheritance hierarchy.
|
// Keep backing up the inheritance hierarchy.
|
||||||
|
|
@ -517,19 +556,19 @@ public abstract class ReflectionUtils {
|
||||||
fc.doWith(field);
|
fc.doWith(field);
|
||||||
}
|
}
|
||||||
catch (IllegalAccessException ex) {
|
catch (IllegalAccessException ex) {
|
||||||
throw new IllegalStateException(
|
throw new IllegalStateException("Shouldn't be illegal to access field '" + field.getName() + "': "
|
||||||
"Shouldn't be illegal to access field '" + field.getName() + "': " + ex);
|
+ ex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
targetClass = targetClass.getSuperclass();
|
targetClass = targetClass.getSuperclass();
|
||||||
}
|
} while (targetClass != null && targetClass != Object.class);
|
||||||
while (targetClass != null && targetClass != Object.class);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Given the source object and the destination, which must be the same class
|
* Given the source object and the destination, which must be the same class
|
||||||
* or a subclass, copy all fields, including inherited fields. Designed to
|
* or a subclass, copy all fields, including inherited fields. Designed to
|
||||||
* work on objects with public no-arg constructors.
|
* work on objects with public no-arg constructors.
|
||||||
|
*
|
||||||
* @throws IllegalArgumentException if the arguments are incompatible
|
* @throws IllegalArgumentException if the arguments are incompatible
|
||||||
*/
|
*/
|
||||||
public static void shallowCopyFieldState(final Object src, final Object dest) throws IllegalArgumentException {
|
public static void shallowCopyFieldState(final Object src, final Object dest) throws IllegalArgumentException {
|
||||||
|
|
@ -540,10 +579,11 @@ public abstract class ReflectionUtils {
|
||||||
throw new IllegalArgumentException("Destination for field copy cannot be null");
|
throw new IllegalArgumentException("Destination for field copy cannot be null");
|
||||||
}
|
}
|
||||||
if (!src.getClass().isAssignableFrom(dest.getClass())) {
|
if (!src.getClass().isAssignableFrom(dest.getClass())) {
|
||||||
throw new IllegalArgumentException("Destination class [" + dest.getClass().getName() +
|
throw new IllegalArgumentException("Destination class [" + dest.getClass().getName()
|
||||||
"] must be same or subclass as source class [" + src.getClass().getName() + "]");
|
+ "] must be same or subclass as source class [" + src.getClass().getName() + "]");
|
||||||
}
|
}
|
||||||
doWithFields(src.getClass(), new FieldCallback() {
|
doWithFields(src.getClass(), new FieldCallback() {
|
||||||
|
|
||||||
public void doWith(Field field) throws IllegalArgumentException, IllegalAccessException {
|
public void doWith(Field field) throws IllegalArgumentException, IllegalAccessException {
|
||||||
makeAccessible(field);
|
makeAccessible(field);
|
||||||
Object srcValue = field.get(src);
|
Object srcValue = field.get(src);
|
||||||
|
|
@ -560,25 +600,26 @@ public abstract class ReflectionUtils {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Perform an operation using the given method.
|
* Perform an operation using the given method.
|
||||||
|
*
|
||||||
* @param method the method to operate on
|
* @param method the method to operate on
|
||||||
*/
|
*/
|
||||||
void doWith(Method method) throws IllegalArgumentException, IllegalAccessException;
|
void doWith(Method method) throws IllegalArgumentException, IllegalAccessException;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Callback optionally used to method fields to be operated on by a method callback.
|
* Callback optionally used to method fields to be operated on by a method
|
||||||
|
* callback.
|
||||||
*/
|
*/
|
||||||
public static interface MethodFilter {
|
public static interface MethodFilter {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Determine whether the given method matches.
|
* Determine whether the given method matches.
|
||||||
|
*
|
||||||
* @param method the method to check
|
* @param method the method to check
|
||||||
*/
|
*/
|
||||||
boolean matches(Method method);
|
boolean matches(Method method);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Callback interface invoked on each field in the hierarchy.
|
* Callback interface invoked on each field in the hierarchy.
|
||||||
*/
|
*/
|
||||||
|
|
@ -586,19 +627,21 @@ public abstract class ReflectionUtils {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Perform an operation using the given field.
|
* Perform an operation using the given field.
|
||||||
|
*
|
||||||
* @param field the field to operate on
|
* @param field the field to operate on
|
||||||
*/
|
*/
|
||||||
void doWith(Field field) throws IllegalArgumentException, IllegalAccessException;
|
void doWith(Field field) throws IllegalArgumentException, IllegalAccessException;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Callback optionally used to filter fields to be operated on by a field callback.
|
* Callback optionally used to filter fields to be operated on by a field
|
||||||
|
* callback.
|
||||||
*/
|
*/
|
||||||
public static interface FieldFilter {
|
public static interface FieldFilter {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Determine whether the given field matches.
|
* Determine whether the given field matches.
|
||||||
|
*
|
||||||
* @param field the field to check
|
* @param field the field to check
|
||||||
*/
|
*/
|
||||||
boolean matches(Field field);
|
boolean matches(Field field);
|
||||||
|
|
@ -609,9 +652,9 @@ public abstract class ReflectionUtils {
|
||||||
* Pre-built FieldFilter that matches all non-static, non-final fields.
|
* Pre-built FieldFilter that matches all non-static, non-final fields.
|
||||||
*/
|
*/
|
||||||
public static FieldFilter COPYABLE_FIELDS = new FieldFilter() {
|
public static FieldFilter COPYABLE_FIELDS = new FieldFilter() {
|
||||||
|
|
||||||
public boolean matches(Field field) {
|
public boolean matches(Field field) {
|
||||||
return !(Modifier.isStatic(field.getModifiers()) ||
|
return !(Modifier.isStatic(field.getModifiers()) || Modifier.isFinal(field.getModifiers()));
|
||||||
Modifier.isFinal(field.getModifiers()));
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright 2002-2008 the original author or authors.
|
* Copyright 2002-2009 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
|
|
@ -21,7 +21,6 @@ import java.lang.reflect.Method;
|
||||||
|
|
||||||
import org.apache.commons.logging.Log;
|
import org.apache.commons.logging.Log;
|
||||||
import org.apache.commons.logging.LogFactory;
|
import org.apache.commons.logging.LogFactory;
|
||||||
|
|
||||||
import org.springframework.util.Assert;
|
import org.springframework.util.Assert;
|
||||||
import org.springframework.util.ReflectionUtils;
|
import org.springframework.util.ReflectionUtils;
|
||||||
import org.springframework.util.StringUtils;
|
import org.springframework.util.StringUtils;
|
||||||
|
|
@ -33,8 +32,8 @@ import org.springframework.util.StringUtils;
|
||||||
* </p>
|
* </p>
|
||||||
* <p>
|
* <p>
|
||||||
* There are often situations in which it would be beneficial to be able to set
|
* There are often situations in which it would be beneficial to be able to set
|
||||||
* a non-<code>public</code> field or invoke a non-<code>public</code>
|
* a non-<code>public</code> field or invoke a non-<code>public</code> setter
|
||||||
* setter method when testing code involving, for example:
|
* method when testing code involving, for example:
|
||||||
* </p>
|
* </p>
|
||||||
* <ul>
|
* <ul>
|
||||||
* <li>ORM frameworks such as JPA and Hibernate which condone the usage of
|
* <li>ORM frameworks such as JPA and Hibernate which condone the usage of
|
||||||
|
|
@ -43,10 +42,10 @@ import org.springframework.util.StringUtils;
|
||||||
* <li>Spring's support for annotations such as
|
* <li>Spring's support for annotations such as
|
||||||
* {@link org.springframework.beans.factory.annotation.Autowired @Autowired} and
|
* {@link org.springframework.beans.factory.annotation.Autowired @Autowired} and
|
||||||
* {@link javax.annotation.Resource @Resource} which provides dependency
|
* {@link javax.annotation.Resource @Resource} which provides dependency
|
||||||
* injection for <code>private</code> or <code>protected</code> fields,
|
* injection for <code>private</code> or <code>protected</code> fields, setter
|
||||||
* setter methods, and configuration methods.</li>
|
* methods, and configuration methods.</li>
|
||||||
* </ul>
|
* </ul>
|
||||||
*
|
*
|
||||||
* @author Sam Brannen
|
* @author Sam Brannen
|
||||||
* @author Juergen Hoeller
|
* @author Juergen Hoeller
|
||||||
* @since 2.5
|
* @since 2.5
|
||||||
|
|
@ -64,11 +63,13 @@ public class ReflectionTestUtils {
|
||||||
/**
|
/**
|
||||||
* Set the {@link Field field} with the given <code>name</code> on the
|
* Set the {@link Field field} with the given <code>name</code> on the
|
||||||
* provided {@link Object target object} to the supplied <code>value</code>.
|
* provided {@link Object target object} to the supplied <code>value</code>.
|
||||||
* <p>This method traverses the class hierarchy in search of the desired field.
|
* <p>
|
||||||
|
* This method traverses the class hierarchy in search of the desired field.
|
||||||
* In addition, an attempt will be made to make non-<code>public</code>
|
* In addition, an attempt will be made to make non-<code>public</code>
|
||||||
* fields <em>accessible</em>, thus allowing one to set
|
* fields <em>accessible</em>, thus allowing one to set
|
||||||
* <code>protected</code>, <code>private</code>, and
|
* <code>protected</code>, <code>private</code>, and
|
||||||
* <em>package-private</em> fields.
|
* <em>package-private</em> fields.
|
||||||
|
*
|
||||||
* @param target the target object on which to set the field
|
* @param target the target object on which to set the field
|
||||||
* @param name the name of the field to set
|
* @param name the name of the field to set
|
||||||
* @param value the value to set
|
* @param value the value to set
|
||||||
|
|
@ -83,11 +84,13 @@ public class ReflectionTestUtils {
|
||||||
/**
|
/**
|
||||||
* Set the {@link Field field} with the given <code>name</code> on the
|
* Set the {@link Field field} with the given <code>name</code> on the
|
||||||
* provided {@link Object target object} to the supplied <code>value</code>.
|
* provided {@link Object target object} to the supplied <code>value</code>.
|
||||||
* <p>This method traverses the class hierarchy in search of the desired field.
|
* <p>
|
||||||
|
* This method traverses the class hierarchy in search of the desired field.
|
||||||
* In addition, an attempt will be made to make non-<code>public</code>
|
* In addition, an attempt will be made to make non-<code>public</code>
|
||||||
* fields <em>accessible</em>, thus allowing one to set
|
* fields <em>accessible</em>, thus allowing one to set
|
||||||
* <code>protected</code>, <code>private</code>, and
|
* <code>protected</code>, <code>private</code>, and
|
||||||
* <em>package-private</em> fields.
|
* <em>package-private</em> fields.
|
||||||
|
*
|
||||||
* @param target the target object on which to set the field
|
* @param target the target object on which to set the field
|
||||||
* @param name the name of the field to set
|
* @param name the name of the field to set
|
||||||
* @param value the value to set
|
* @param value the value to set
|
||||||
|
|
@ -96,7 +99,7 @@ public class ReflectionTestUtils {
|
||||||
* @see ReflectionUtils#makeAccessible(Field)
|
* @see ReflectionUtils#makeAccessible(Field)
|
||||||
* @see ReflectionUtils#setField(Field, Object, Object)
|
* @see ReflectionUtils#setField(Field, Object, Object)
|
||||||
*/
|
*/
|
||||||
public static void setField(Object target, String name, Object value, Class type) {
|
public static void setField(Object target, String name, Object value, Class<?> type) {
|
||||||
Assert.notNull(target, "Target object must not be null");
|
Assert.notNull(target, "Target object must not be null");
|
||||||
Field field = ReflectionUtils.findField(target.getClass(), name, type);
|
Field field = ReflectionUtils.findField(target.getClass(), name, type);
|
||||||
if (field == null) {
|
if (field == null) {
|
||||||
|
|
@ -111,12 +114,15 @@ public class ReflectionTestUtils {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the field with the given <code>name</code> from the provided
|
* Get the field with the given <code>name</code> from the provided target
|
||||||
* target object.
|
* object.
|
||||||
* <p>This method traverses the class hierarchy in search of the desired field.
|
* <p>
|
||||||
* In addition, an attempt will be made to make non-<code>public</code> fields
|
* This method traverses the class hierarchy in search of the desired field.
|
||||||
* <em>accessible</em>, thus allowing one to get <code>protected</code>,
|
* In addition, an attempt will be made to make non-<code>public</code>
|
||||||
* <code>private</code>, and <em>package-private</em> fields.
|
* fields <em>accessible</em>, thus allowing one to get
|
||||||
|
* <code>protected</code>, <code>private</code>, and
|
||||||
|
* <em>package-private</em> fields.
|
||||||
|
*
|
||||||
* @param target the target object on which to set the field
|
* @param target the target object on which to set the field
|
||||||
* @param name the name of the field to get
|
* @param name the name of the field to get
|
||||||
* @return the field's current value
|
* @return the field's current value
|
||||||
|
|
@ -141,16 +147,22 @@ public class ReflectionTestUtils {
|
||||||
/**
|
/**
|
||||||
* Invoke the setter method with the given <code>name</code> on the supplied
|
* Invoke the setter method with the given <code>name</code> on the supplied
|
||||||
* target object with the supplied <code>value</code>.
|
* target object with the supplied <code>value</code>.
|
||||||
* <p>This method traverses the class hierarchy in search of the desired
|
* <p>
|
||||||
* method. In addition, an attempt will be made to make non-<code>public</code>
|
* This method traverses the class hierarchy in search of the desired
|
||||||
* methods <em>accessible</em>, thus allowing one to invoke <code>protected</code>,
|
* method. In addition, an attempt will be made to make non-
|
||||||
* <code>private</code>, and <em>package-private</em> setter methods.
|
* <code>public</code> methods <em>accessible</em>, thus allowing one to
|
||||||
* <p>In addition, this method supports JavaBean-style <em>property</em>
|
* invoke <code>protected</code>, <code>private</code>, and
|
||||||
* names. For example, if you wish to set the <code>name</code> property
|
* <em>package-private</em> setter methods.
|
||||||
* on the target object, you may pass either "name" or
|
* <p>
|
||||||
|
* In addition, this method supports JavaBean-style <em>property</em> names.
|
||||||
|
* For example, if you wish to set the <code>name</code> property on the
|
||||||
|
* target object, you may pass either "name" or
|
||||||
* "setName" as the method name.
|
* "setName" as the method name.
|
||||||
* @param target the target object on which to invoke the specified setter method
|
*
|
||||||
* @param name the name of the setter method to invoke or the corresponding property name
|
* @param target the target object on which to invoke the specified setter
|
||||||
|
* method
|
||||||
|
* @param name the name of the setter method to invoke or the corresponding
|
||||||
|
* property name
|
||||||
* @param value the value to provide to the setter method
|
* @param value the value to provide to the setter method
|
||||||
* @see ReflectionUtils#findMethod(Class, String, Class[])
|
* @see ReflectionUtils#findMethod(Class, String, Class[])
|
||||||
* @see ReflectionUtils#makeAccessible(Method)
|
* @see ReflectionUtils#makeAccessible(Method)
|
||||||
|
|
@ -163,26 +175,32 @@ public class ReflectionTestUtils {
|
||||||
/**
|
/**
|
||||||
* Invoke the setter method with the given <code>name</code> on the supplied
|
* Invoke the setter method with the given <code>name</code> on the supplied
|
||||||
* target object with the supplied <code>value</code>.
|
* target object with the supplied <code>value</code>.
|
||||||
* <p>This method traverses the class hierarchy in search of the desired
|
* <p>
|
||||||
* method. In addition, an attempt will be made to make non-<code>public</code>
|
* This method traverses the class hierarchy in search of the desired
|
||||||
* methods <em>accessible</em>, thus allowing one to invoke <code>protected</code>,
|
* method. In addition, an attempt will be made to make non-
|
||||||
* <code>private</code>, and <em>package-private</em> setter methods.
|
* <code>public</code> methods <em>accessible</em>, thus allowing one to
|
||||||
* <p>In addition, this method supports JavaBean-style <em>property</em>
|
* invoke <code>protected</code>, <code>private</code>, and
|
||||||
* names. For example, if you wish to set the <code>name</code> property
|
* <em>package-private</em> setter methods.
|
||||||
* on the target object, you may pass either "name" or
|
* <p>
|
||||||
|
* In addition, this method supports JavaBean-style <em>property</em> names.
|
||||||
|
* For example, if you wish to set the <code>name</code> property on the
|
||||||
|
* target object, you may pass either "name" or
|
||||||
* "setName" as the method name.
|
* "setName" as the method name.
|
||||||
* @param target the target object on which to invoke the specified setter method
|
*
|
||||||
* @param name the name of the setter method to invoke or the corresponding property name
|
* @param target the target object on which to invoke the specified setter
|
||||||
|
* method
|
||||||
|
* @param name the name of the setter method to invoke or the corresponding
|
||||||
|
* property name
|
||||||
* @param value the value to provide to the setter method
|
* @param value the value to provide to the setter method
|
||||||
* @param type the formal parameter type declared by the setter method
|
* @param type the formal parameter type declared by the setter method
|
||||||
* @see ReflectionUtils#findMethod(Class, String, Class[])
|
* @see ReflectionUtils#findMethod(Class, String, Class[])
|
||||||
* @see ReflectionUtils#makeAccessible(Method)
|
* @see ReflectionUtils#makeAccessible(Method)
|
||||||
* @see ReflectionUtils#invokeMethod(Method, Object, Object[])
|
* @see ReflectionUtils#invokeMethod(Method, Object, Object[])
|
||||||
*/
|
*/
|
||||||
public static void invokeSetterMethod(Object target, String name, Object value, Class type) {
|
public static void invokeSetterMethod(Object target, String name, Object value, Class<?> type) {
|
||||||
Assert.notNull(target, "Target object must not be null");
|
Assert.notNull(target, "Target object must not be null");
|
||||||
Assert.notNull(name, "Method name must not be empty");
|
Assert.notNull(name, "Method name must not be empty");
|
||||||
Class[] paramTypes = (type != null ? new Class[] {type} : null);
|
Class<?>[] paramTypes = (type != null ? new Class<?>[] { type } : null);
|
||||||
|
|
||||||
String setterMethodName = name;
|
String setterMethodName = name;
|
||||||
if (!name.startsWith(SETTER_PREFIX)) {
|
if (!name.startsWith(SETTER_PREFIX)) {
|
||||||
|
|
@ -194,30 +212,36 @@ public class ReflectionTestUtils {
|
||||||
method = ReflectionUtils.findMethod(target.getClass(), setterMethodName, paramTypes);
|
method = ReflectionUtils.findMethod(target.getClass(), setterMethodName, paramTypes);
|
||||||
}
|
}
|
||||||
if (method == null) {
|
if (method == null) {
|
||||||
throw new IllegalArgumentException("Could not find setter method [" + setterMethodName +
|
throw new IllegalArgumentException("Could not find setter method [" + setterMethodName + "] on target ["
|
||||||
"] on target [" + target + "] with parameter type [" + type + "]");
|
+ target + "] with parameter type [" + type + "]");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (logger.isDebugEnabled()) {
|
if (logger.isDebugEnabled()) {
|
||||||
logger.debug("Invoking setter method [" + setterMethodName + "] on target [" + target + "]");
|
logger.debug("Invoking setter method [" + setterMethodName + "] on target [" + target + "]");
|
||||||
}
|
}
|
||||||
ReflectionUtils.makeAccessible(method);
|
ReflectionUtils.makeAccessible(method);
|
||||||
ReflectionUtils.invokeMethod(method, target, new Object[] {value});
|
ReflectionUtils.invokeMethod(method, target, new Object[] { value });
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Invoke the getter method with the given <code>name</code> on the supplied
|
* Invoke the getter method with the given <code>name</code> on the supplied
|
||||||
* target object with the supplied <code>value</code>.
|
* target object with the supplied <code>value</code>.
|
||||||
* <p>This method traverses the class hierarchy in search of the desired
|
* <p>
|
||||||
* method. In addition, an attempt will be made to make non-<code>public</code>
|
* This method traverses the class hierarchy in search of the desired
|
||||||
* methods <em>accessible</em>, thus allowing one to invoke <code>protected</code>,
|
* method. In addition, an attempt will be made to make non-
|
||||||
* <code>private</code>, and <em>package-private</em> getter methods.
|
* <code>public</code> methods <em>accessible</em>, thus allowing one to
|
||||||
* <p>In addition, this method supports JavaBean-style <em>property</em>
|
* invoke <code>protected</code>, <code>private</code>, and
|
||||||
* names. For example, if you wish to get the <code>name</code> property
|
* <em>package-private</em> getter methods.
|
||||||
* on the target object, you may pass either "name" or
|
* <p>
|
||||||
|
* In addition, this method supports JavaBean-style <em>property</em> names.
|
||||||
|
* For example, if you wish to get the <code>name</code> property on the
|
||||||
|
* target object, you may pass either "name" or
|
||||||
* "getName" as the method name.
|
* "getName" as the method name.
|
||||||
* @param target the target object on which to invoke the specified getter method
|
*
|
||||||
* @param name the name of the getter method to invoke or the corresponding property name
|
* @param target the target object on which to invoke the specified getter
|
||||||
|
* method
|
||||||
|
* @param name the name of the getter method to invoke or the corresponding
|
||||||
|
* property name
|
||||||
* @return the value returned from the invocation
|
* @return the value returned from the invocation
|
||||||
* @see ReflectionUtils#findMethod(Class, String, Class[])
|
* @see ReflectionUtils#findMethod(Class, String, Class[])
|
||||||
* @see ReflectionUtils#makeAccessible(Method)
|
* @see ReflectionUtils#makeAccessible(Method)
|
||||||
|
|
@ -237,8 +261,8 @@ public class ReflectionTestUtils {
|
||||||
method = ReflectionUtils.findMethod(target.getClass(), getterMethodName);
|
method = ReflectionUtils.findMethod(target.getClass(), getterMethodName);
|
||||||
}
|
}
|
||||||
if (method == null) {
|
if (method == null) {
|
||||||
throw new IllegalArgumentException("Could not find getter method [" + getterMethodName +
|
throw new IllegalArgumentException("Could not find getter method [" + getterMethodName + "] on target ["
|
||||||
"] on target [" + target + "]");
|
+ target + "]");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (logger.isDebugEnabled()) {
|
if (logger.isDebugEnabled()) {
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue