Browse Source

Javadoc fixes plus additional polishing

pull/838/head
Juergen Hoeller 10 years ago
parent
commit
ea2a1d33d9
  1. 22
      spring-expression/src/main/java/org/springframework/expression/spel/CodeFlow.java
  2. 86
      spring-test/src/main/java/org/springframework/test/util/ReflectionTestUtils.java
  3. 4
      spring-test/src/test/java/org/springframework/test/util/ReflectionTestUtilsTests.java

22
spring-expression/src/main/java/org/springframework/expression/spel/CodeFlow.java

@ -945,7 +945,8 @@ public class CodeFlow implements Opcodes { @@ -945,7 +945,8 @@ public class CodeFlow implements Opcodes {
// is [[I then we want [I and not [I;
if (CodeFlow.isReferenceTypeArray(arraytype)) {
mv.visitTypeInsn(ANEWARRAY, arraytype+";");
} else {
}
else {
mv.visitTypeInsn(ANEWARRAY, arraytype);
}
}
@ -956,19 +957,22 @@ public class CodeFlow implements Opcodes { @@ -956,19 +957,22 @@ public class CodeFlow implements Opcodes {
}
/**
* For use in mathematical operators, handles converting from a (possibly boxed) number on the stack to a primitive numeric type.
* For example, from a Integer to a double, just need to call 'Number.doubleValue()' but from an int to a double, need to use
* the bytecode 'i2d'.
* For use in mathematical operators, handles converting from a (possibly boxed)
* number on the stack to a primitive numeric type.
* <p>For example, from a Integer to a double, just need to call 'Number.doubleValue()'
* but from an int to a double, need to use the bytecode 'i2d'.
* @param mv the method visitor when instructions should be appended
* @param stackDescriptor a descriptor of the operand on the stack
* @param targetDescriptor a primitive type descriptor
*/
public static void insertNumericUnboxOrPrimitiveTypeCoercion(MethodVisitor mv,
String stackDescriptor, char targetDecriptor) {
public static void insertNumericUnboxOrPrimitiveTypeCoercion(
MethodVisitor mv, String stackDescriptor, char targetDescriptor) {
if (!CodeFlow.isPrimitive(stackDescriptor)) {
CodeFlow.insertUnboxNumberInsns(mv, targetDecriptor, stackDescriptor);
} else {
CodeFlow.insertAnyNecessaryTypeConversionBytecodes(mv, targetDecriptor, stackDescriptor);
CodeFlow.insertUnboxNumberInsns(mv, targetDescriptor, stackDescriptor);
}
else {
CodeFlow.insertAnyNecessaryTypeConversionBytecodes(mv, targetDescriptor, stackDescriptor);
}
}

86
spring-test/src/main/java/org/springframework/test/util/ReflectionTestUtils.java

@ -72,10 +72,8 @@ public class ReflectionTestUtils { @@ -72,10 +72,8 @@ public class ReflectionTestUtils {
/**
* Set the {@linkplain Field field} with the given {@code name} on the
* provided {@code targetObject} to the supplied {@code value}.
*
* <p>This method delegates to {@link #setField(Object, String, Object, Class)},
* supplying {@code null} for the {@code type} argument.
*
* @param targetObject the target object on which to set the field; never {@code null}
* @param name the name of the field to set; never {@code null}
* @param value the value to set
@ -87,10 +85,8 @@ public class ReflectionTestUtils { @@ -87,10 +85,8 @@ public class ReflectionTestUtils {
/**
* Set the {@linkplain Field field} with the given {@code name}/{@code type}
* on the provided {@code targetObject} to the supplied {@code value}.
*
* <p>This method delegates to {@link #setField(Object, Class, String, Object, Class)},
* supplying {@code null} for the {@code targetClass} argument.
*
* @param targetObject the target object on which to set the field; never {@code null}
* @param name the name of the field to set; may be {@code null} if
* {@code type} is specified
@ -105,10 +101,8 @@ public class ReflectionTestUtils { @@ -105,10 +101,8 @@ public class ReflectionTestUtils {
/**
* Set the static {@linkplain Field field} with the given {@code name} on
* the provided {@code targetClass} to the supplied {@code value}.
*
* <p>This method delegates to {@link #setField(Object, Class, String, Object, Class)},
* supplying {@code null} for the {@code targetObject} and {@code type} arguments.
*
* @param targetClass the target class on which to set the static field;
* never {@code null}
* @param name the name of the field to set; never {@code null}
@ -123,10 +117,8 @@ public class ReflectionTestUtils { @@ -123,10 +117,8 @@ public class ReflectionTestUtils {
* Set the static {@linkplain Field field} with the given
* {@code name}/{@code type} on the provided {@code targetClass} to
* the supplied {@code value}.
*
* <p>This method delegates to {@link #setField(Object, Class, String, Object, Class)},
* supplying {@code null} for the {@code targetObject} argument.
*
* @param targetClass the target class on which to set the static field;
* never {@code null}
* @param name the name of the field to set; may be {@code null} if
@ -144,12 +136,10 @@ public class ReflectionTestUtils { @@ -144,12 +136,10 @@ public class ReflectionTestUtils {
* Set the {@linkplain Field field} with the given {@code name}/{@code type}
* on the provided {@code targetObject}/{@code targetClass} to the supplied
* {@code value}.
*
* <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}
* fields <em>accessible</em>, thus allowing one to set {@code protected},
* {@code private}, and <em>package-private</em> fields.
*
* @param targetObject the target object on which to set the field; may be
* {@code null} if the field is static
* @param targetClass the target class on which to set the field; may
@ -171,19 +161,18 @@ public class ReflectionTestUtils { @@ -171,19 +161,18 @@ public class ReflectionTestUtils {
if (targetClass == null) {
targetClass = targetObject.getClass();
}
Field field = ReflectionUtils.findField(targetClass, name, type);
// Inline Assert.notNull() to avoid invoking toString() on a non-null target.
Field field = ReflectionUtils.findField(targetClass, name, type);
if (field == null) {
throw new IllegalArgumentException(String.format(
"Could not find field [%s] of type [%s] on target object [%s] or target class [%s]", name, type,
targetObject, targetClass));
"Could not find field '%s' of type [%s] on target object [%s] or target class [%s]", name, type,
targetObject, targetClass));
}
if (logger.isDebugEnabled()) {
logger.debug(String.format(
"Setting field [%s] of type [%s] on target object [%s] or target class [%s] to value [%s]", name, type,
targetObject, targetClass, value));
"Setting field '%s' of type [%s] on target object [%s] or target class [%s] to value [%s]", name, type,
targetObject, targetClass, value));
}
ReflectionUtils.makeAccessible(field);
ReflectionUtils.setField(field, targetObject, value);
@ -192,10 +181,8 @@ public class ReflectionTestUtils { @@ -192,10 +181,8 @@ public class ReflectionTestUtils {
/**
* Get the value of the {@linkplain Field field} with the given {@code name}
* from the provided {@code targetObject}.
*
* <p>This method delegates to {@link #getField(Object, Class, String)},
* supplying {@code null} for the {@code targetClass} argument.
*
* @param targetObject the target object from which to get the field;
* never {@code null}
* @param name the name of the field to get; never {@code null}
@ -209,16 +196,14 @@ public class ReflectionTestUtils { @@ -209,16 +196,14 @@ public class ReflectionTestUtils {
/**
* Get the value of the static {@linkplain Field field} with the given
* {@code name} from the provided {@code targetClass}.
*
* <p>This method delegates to {@link #getField(Object, Class, String)},
* supplying {@code null} for the {@code targetObject} argument.
*
* @param targetClass the target class from which to get the static field;
* never {@code null}
* @param name the name of the field to get; never {@code null}
* @return the field's current value
* @see #getField(Object, String)
* @since 4.2
* @see #getField(Object, String)
*/
public static Object getField(Class<?> targetClass, String name) {
return getField(null, targetClass, name);
@ -227,24 +212,22 @@ public class ReflectionTestUtils { @@ -227,24 +212,22 @@ public class ReflectionTestUtils {
/**
* Get the value of the {@linkplain Field field} with the given {@code name}
* from the provided {@code targetObject}/{@code targetClass}.
*
* <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}
* fields <em>accessible</em>, thus allowing one to get {@code protected},
* {@code private}, and <em>package-private</em> fields.
*
* @param targetObject the target object from which to get the field; may be
* {@code null} if the field is static
* @param targetClass the target class from which to get the field; may
* be {@code null} if the field is an instance field
* @param name the name of the field to get; never {@code null}
* @return the field's current value
* @since 4.2
* @see #getField(Object, String)
* @see #getField(Class, String)
* @see ReflectionUtils#findField(Class, String, Class)
* @see ReflectionUtils#makeAccessible(Field)
* @see ReflectionUtils#getField(Field, Object, Object)
* @since 4.2
* @see ReflectionUtils#getField(Field, Object)
*/
public static Object getField(Object targetObject, Class<?> targetClass, String name) {
Assert.isTrue(targetObject != null || targetClass != null,
@ -253,18 +236,17 @@ public class ReflectionTestUtils { @@ -253,18 +236,17 @@ public class ReflectionTestUtils {
if (targetClass == null) {
targetClass = targetObject.getClass();
}
Field field = ReflectionUtils.findField(targetClass, name);
// Inline Assert.notNull() to avoid invoking toString() on a non-null target.
Field field = ReflectionUtils.findField(targetClass, name);
if (field == null) {
throw new IllegalArgumentException(
String.format("Could not find field [%s] on target object [%s] or target class [%s]", name,
targetObject, targetClass));
String.format("Could not find field '%s' on target object [%s] or target class [%s]", name,
targetObject, targetClass));
}
if (logger.isDebugEnabled()) {
logger.debug(String.format("Getting field [%s] from target object [%s] or target class [%s]", name,
targetObject, targetClass));
logger.debug(String.format("Getting field '%s' from target object [%s] or target class [%s]", name,
targetObject, targetClass));
}
ReflectionUtils.makeAccessible(field);
return ReflectionUtils.getField(field, targetObject);
@ -273,17 +255,14 @@ public class ReflectionTestUtils { @@ -273,17 +255,14 @@ public class ReflectionTestUtils {
/**
* Invoke the setter method with the given {@code name} on the supplied
* target object with the supplied {@code value}.
*
* <p>This method traverses the class hierarchy in search of the desired
* method. In addition, an attempt will be made to make non-{@code public}
* methods <em>accessible</em>, thus allowing one to invoke {@code protected},
* {@code private}, and <em>package-private</em> setter methods.
*
* <p>In addition, this method supports JavaBean-style <em>property</em>
* names. For example, if you wish to set the {@code name} property on the
* target object, you may pass either &quot;name&quot; or
* &quot;setName&quot; 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
@ -300,17 +279,14 @@ public class ReflectionTestUtils { @@ -300,17 +279,14 @@ public class ReflectionTestUtils {
/**
* Invoke the setter method with the given {@code name} on the supplied
* target object with the supplied {@code value}.
*
* <p>This method traverses the class hierarchy in search of the desired
* method. In addition, an attempt will be made to make non-{@code public}
* methods <em>accessible</em>, thus allowing one to invoke {@code protected},
* {@code private}, and <em>package-private</em> setter methods.
*
* <p>In addition, this method supports JavaBean-style <em>property</em>
* names. For example, if you wish to set the {@code name} property on the
* target object, you may pass either &quot;name&quot; or
* &quot;setName&quot; 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
@ -324,41 +300,41 @@ public class ReflectionTestUtils { @@ -324,41 +300,41 @@ public class ReflectionTestUtils {
public static void invokeSetterMethod(Object target, String name, Object value, Class<?> type) {
Assert.notNull(target, "Target object must not be null");
Assert.hasText(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;
if (!name.startsWith(SETTER_PREFIX)) {
setterMethodName = SETTER_PREFIX + StringUtils.capitalize(name);
}
Method method = ReflectionUtils.findMethod(target.getClass(), setterMethodName, paramTypes);
if (method == null && !setterMethodName.equals(name)) {
setterMethodName = name;
method = ReflectionUtils.findMethod(target.getClass(), setterMethodName, paramTypes);
}
Assert.notNull(method, "Could not find setter method [" + setterMethodName + "] on target [" + target
+ "] with parameter type [" + type + "]");
if (method == null) {
throw new IllegalArgumentException("Could not find setter method '" + setterMethodName +
"' on target [" + target + "] with parameter type [" + type + "]");
}
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.invokeMethod(method, target, new Object[] { value });
ReflectionUtils.invokeMethod(method, target, value);
}
/**
* Invoke the getter method with the given {@code name} on the supplied
* target object with the supplied {@code value}.
*
* <p>This method traverses the class hierarchy in search of the desired
* method. In addition, an attempt will be made to make non-{@code public}
* methods <em>accessible</em>, thus allowing one to invoke {@code protected},
* {@code private}, and <em>package-private</em> getter methods.
*
* <p>In addition, this method supports JavaBean-style <em>property</em>
* names. For example, if you wish to get the {@code name} property on the
* target object, you may pass either &quot;name&quot; or
* &quot;getName&quot; 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
@ -381,10 +357,13 @@ public class ReflectionTestUtils { @@ -381,10 +357,13 @@ public class ReflectionTestUtils {
getterMethodName = name;
method = ReflectionUtils.findMethod(target.getClass(), getterMethodName);
}
Assert.notNull(method, "Could not find getter method [" + getterMethodName + "] on target [" + target + "]");
if (method == null) {
throw new IllegalArgumentException("Could not find getter method '" + getterMethodName +
"' on target [" + target + "]");
}
if (logger.isDebugEnabled()) {
logger.debug("Invoking getter method [" + getterMethodName + "] on target [" + target + "]");
logger.debug("Invoking getter method '" + getterMethodName + "' on target [" + target + "]");
}
ReflectionUtils.makeAccessible(method);
return ReflectionUtils.invokeMethod(method, target);
@ -393,12 +372,10 @@ public class ReflectionTestUtils { @@ -393,12 +372,10 @@ public class ReflectionTestUtils {
/**
* Invoke the method with the given {@code name} on the supplied target
* object with the supplied arguments.
*
* <p>This method traverses the class hierarchy in search of the desired
* method. In addition, an attempt will be made to make non-{@code public}
* methods <em>accessible</em>, thus allowing one to invoke {@code protected},
* {@code private}, and <em>package-private</em> methods.
*
* @param target the target object on which to invoke the specified method
* @param name the name of the method to invoke
* @param args the arguments to provide to the method
@ -421,17 +398,16 @@ public class ReflectionTestUtils { @@ -421,17 +398,16 @@ public class ReflectionTestUtils {
methodInvoker.prepare();
if (logger.isDebugEnabled()) {
logger.debug("Invoking method [" + name + "] on target [" + target + "] with arguments ["
+ ObjectUtils.nullSafeToString(args) + "]");
logger.debug("Invoking method '" + name + "' on target [" + target + "] with arguments [" +
ObjectUtils.nullSafeToString(args) + "]");
}
return (T) methodInvoker.invoke();
}
catch (Exception e) {
ReflectionUtils.handleReflectionException(e);
catch (Exception ex) {
ReflectionUtils.handleReflectionException(ex);
throw new IllegalStateException("Should never get here");
}
throw new IllegalStateException("Should never get here");
}
}

4
spring-test/src/test/java/org/springframework/test/util/ReflectionTestUtilsTests.java

@ -42,6 +42,7 @@ public class ReflectionTestUtilsTests { @@ -42,6 +42,7 @@ public class ReflectionTestUtilsTests {
private static final Float PI = new Float((float) 22 / 7);
private final Person person = new Person();
private final Component component = new Component();
@Rule
@ -53,6 +54,7 @@ public class ReflectionTestUtilsTests { @@ -53,6 +54,7 @@ public class ReflectionTestUtilsTests {
StaticFields.reset();
}
@Test
public void setFieldWithNullTargetObject() throws Exception {
exception.expect(IllegalArgumentException.class);
@ -91,7 +93,7 @@ public class ReflectionTestUtilsTests { @@ -91,7 +93,7 @@ public class ReflectionTestUtilsTests {
@Test
public void setFieldWithBogusName() throws Exception {
exception.expect(IllegalArgumentException.class);
exception.expectMessage(startsWith("Could not find field [bogus]"));
exception.expectMessage(startsWith("Could not find field 'bogus'"));
setField(person, "bogus", new Long(99), long.class);
}

Loading…
Cancel
Save