rdonkin 2002/11/20 13:45:47
Modified: lang/src/java/org/apache/commons/lang/reflect
MethodUtils.java ReflectionUtils.java
lang/src/test/org/apache/commons/lang/reflect
PrimitiveBean.java ReflectionUtilsTestCase.java
Log:
Moved isAssignmentCompatable method from MethodUtils into ReflectionUtils and
renamed it. Enhanced existing isCompatible so that widening of primitives is allowed.
Created test case for moved method.
Revision Changes Path
1.5 +3 -52
jakarta-commons/lang/src/java/org/apache/commons/lang/reflect/MethodUtils.java
Index: MethodUtils.java
===================================================================
RCS file:
/home/cvs/jakarta-commons/lang/src/java/org/apache/commons/lang/reflect/MethodUtils.java,v
retrieving revision 1.4
retrieving revision 1.5
diff -u -r1.4 -r1.5
--- MethodUtils.java 18 Nov 2002 23:00:26 -0000 1.4
+++ MethodUtils.java 20 Nov 2002 21:45:47 -0000 1.5
@@ -570,7 +570,7 @@
log("Param=" + parameterTypes[n].getName());
log("Method=" + methodsParams[n].getName());
}
- if (!isAssignmentCompatible(methodsParams[n],
parameterTypes[n])) {
+ if (!ReflectionUtils.isCompatable(parameterTypes[n],
methodsParams[n])) {
if (debug) {
log(methodsParams[n] + " is not assignable from "
+ parameterTypes[n]);
@@ -613,56 +613,7 @@
// didn't find a match
log("No match found.");
return null;
- }
-
-
- /**
- * <p>Determine whether a type can be used as a parameter in a method
invocation.
- * This method handles primitive conversions correctly.</p>
- *
- * <p>In order words, it will match a <code>Boolean</code> to a
<code>boolean</code>,
- * a <code>Long</code> to a <code>long</code>,
- * a <code>Float</code> to a <code>float</code>,
- * a <code>Integer</code> to a <code>int</code>,
- * and a <code>Double</code> to a <code>double</code>.
- * Now logic widening matches are allowed.
- * For example, a <code>Long</code> will not match a <code>int</code>.
- *
- * @param parameterType the type of parameter accepted by the method
- * @param parameterization the type of parameter being tested
- *
- * @return true if the assignement is compatible.
- */
- private static final boolean isAssignmentCompatible(Class parameterType, Class
parameterization) {
- // try plain assignment
- if (parameterType.isAssignableFrom(parameterization)) {
- return true;
- }
-
- if (parameterType.isPrimitive()) {
- // does anyone know a better strategy than comparing names?
- // also, this method does *not* do widening - you must specify exactly
- // is this the right behaviour?
- if (boolean.class.equals(parameterType)) {
- return Boolean.class.equals(parameterization);
- }
- if (float.class.equals(parameterType)) {
- return Float.class.equals(parameterization);
- }
- if (long.class.equals(parameterType)) {
- return Long.class.equals(parameterization);
- }
- if (int.class.equals(parameterType)) {
- return Integer.class.equals(parameterization);
- }
- if (double.class.equals(parameterType)) {
- return Double.class.equals(parameterization);
- }
- }
-
- return false;
- }
-
+ }
private static void log(Object o) {
if (debug) {
1.3 +83 -3
jakarta-commons/lang/src/java/org/apache/commons/lang/reflect/ReflectionUtils.java
Index: ReflectionUtils.java
===================================================================
RCS file:
/home/cvs/jakarta-commons/lang/src/java/org/apache/commons/lang/reflect/ReflectionUtils.java,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -r1.2 -r1.3
--- ReflectionUtils.java 18 Nov 2002 23:01:36 -0000 1.2
+++ ReflectionUtils.java 20 Nov 2002 21:45:47 -0000 1.3
@@ -197,7 +197,10 @@
* Primitive classes are handled correctly .
* <p>
* In other words, a <code>boolean</code> Class will be converted to
- * a <code>Boolean</code> Class and so on.
+ * a <code>Boolean</code> Class and so on.</p>
+ *
+ * <p>This method also handles widening for primitives as given in section
5.1.2 of the
+ * <em><a href="http://java.sun.com/docs/books/jls/">The Java Language
Specification</a></em>.
*
* @param requestedTypes the class array requested
* @param paramTypes the actual class array for the method
@@ -214,12 +217,89 @@
paramTypes = ArrayUtils.EMPTY_CLASS_ARRAY;
}
for (int i = 0; i < requestedTypes.length; i++) {
- if (ClassUtils.isAssignable(requestedTypes[i], paramTypes[i]) == false)
{
+ if (isCompatable(requestedTypes[i], paramTypes[i]) == false) {
return false;
}
}
return true;
}
+
+
+ /**
+ * <p>Determine whether a type can be used as a parameter in a method
invocation.
+ * This method handles primitive conversions correctly.</p>
+ *
+ * <p>This method also handles widening for primitives as given in section
5.1.2 of the
+ * <em><a href="http://java.sun.com/docs/books/jls/">The Java Language
Specification</a></em>.
+ *
+ * @param parameterType the type of parameter accepted by the method
+ * @param requestedType the type of parameter being requested
+ *
+ * @return true if the assignement is compatible.
+ */
+ public static boolean isCompatable(Class requestedType, Class parameterType) {
+ // try plain assignment
+ if (ClassUtils.isAssignable(requestedType, parameterType)) {
+ return true;
+ }
+
+ if (parameterType.isPrimitive()) {
+ // also, this method does *not* do widening - you must specify exactly
+ // is this the right behaviour?
+ if (boolean.class.equals(parameterType)) {
+ return Boolean.class.equals(requestedType);
+ }
+
+ if (byte.class.equals(parameterType)) {
+ return Byte.class.equals(requestedType);
+ }
+
+ if (short.class.equals(parameterType)) {
+ return (Short.class.equals(requestedType)
+ || Byte.class.equals(requestedType));
+ }
+
+ if (char.class.equals(parameterType)) {
+ return Character.class.equals(requestedType);
+ }
+
+ if (int.class.equals(parameterType)) {
+ return (Integer.class.equals(requestedType)
+ || Character.class.equals(requestedType)
+ || Short.class.equals(requestedType)
+ || Byte.class.equals(requestedType));
+ }
+ if (long.class.equals(parameterType)) {
+ return (Long.class.equals(requestedType)
+ || Integer.class.equals(requestedType)
+ || Character.class.equals(requestedType)
+ || Short.class.equals(requestedType)
+ || Byte.class.equals(requestedType));
+ }
+
+ if (float.class.equals(parameterType)) {
+ return (Float.class.equals(requestedType)
+ || Long.class.equals(requestedType)
+ || Integer.class.equals(requestedType)
+ || Character.class.equals(requestedType)
+ || Short.class.equals(requestedType)
+ || Byte.class.equals(requestedType));
+ }
+
+ if (double.class.equals(parameterType)) {
+ return (Double.class.equals(requestedType)
+ || Float.class.equals(requestedType)
+ || Long.class.equals(requestedType)
+ || Integer.class.equals(requestedType)
+ || Character.class.equals(requestedType)
+ || Short.class.equals(requestedType)
+ || Byte.class.equals(requestedType));
+ }
+ }
+
+ return false;
+ }
+
/**
* Converts a primitive class to its matching object class.
1.2 +9 -0
jakarta-commons/lang/src/test/org/apache/commons/lang/reflect/PrimitiveBean.java
Index: PrimitiveBean.java
===================================================================
RCS file:
/home/cvs/jakarta-commons/lang/src/test/org/apache/commons/lang/reflect/PrimitiveBean.java,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- PrimitiveBean.java 14 Nov 2002 18:53:36 -0000 1.1
+++ PrimitiveBean.java 20 Nov 2002 21:45:47 -0000 1.2
@@ -67,6 +67,15 @@
private boolean _boolean;
private long _long;
private int _int;
+ private short _short;
+
+ public short getShort() {
+ return _short;
+ }
+
+ public void setShort(short _short) {
+ this._short = _short;
+ }
public float getFloat() {
return _float;
1.2 +83 -0
jakarta-commons/lang/src/test/org/apache/commons/lang/reflect/ReflectionUtilsTestCase.java
Index: ReflectionUtilsTestCase.java
===================================================================
RCS file:
/home/cvs/jakarta-commons/lang/src/test/org/apache/commons/lang/reflect/ReflectionUtilsTestCase.java,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- ReflectionUtilsTestCase.java 18 Nov 2002 23:01:36 -0000 1.1
+++ ReflectionUtilsTestCase.java 20 Nov 2002 21:45:47 -0000 1.2
@@ -202,4 +202,87 @@
assertEquals("Static scope (method) [isPublicScope]", true,
ReflectionUtils.isPublicScope(method));
assertEquals("Static scope (method) [isStatic]", true,
ReflectionUtils.isStatic(method));
}
+
+ public void testWidening() throws Exception
+ {
+ // test byte conversions
+ assertEquals("byte -> char", ReflectionUtils.isCompatable(Byte.class,
char.class), false);
+ assertEquals("byte -> byte", ReflectionUtils.isCompatable(Byte.class,
byte.class), true);
+ assertEquals("byte -> short", ReflectionUtils.isCompatable(Byte.class,
short.class), true);
+ assertEquals("byte -> int", ReflectionUtils.isCompatable(Byte.class,
int.class), true);
+ assertEquals("byte -> long", ReflectionUtils.isCompatable(Byte.class,
long.class), true);
+ assertEquals("byte -> float", ReflectionUtils.isCompatable(Byte.class,
float.class), true);
+ assertEquals("byte -> double", ReflectionUtils.isCompatable(Byte.class,
double.class), true);
+ assertEquals("byte -> boolean", ReflectionUtils.isCompatable(Byte.class,
boolean.class), false);
+
+ // test short conversions
+ assertEquals("short -> char", ReflectionUtils.isCompatable(Short.class,
char.class), false);
+ assertEquals("short -> byte", ReflectionUtils.isCompatable(Short.class,
byte.class), false);
+ assertEquals("short -> short", ReflectionUtils.isCompatable(Short.class,
short.class), true);
+ assertEquals("short -> int", ReflectionUtils.isCompatable(Short.class,
int.class), true);
+ assertEquals("short -> long", ReflectionUtils.isCompatable(Short.class,
long.class), true);
+ assertEquals("short -> float", ReflectionUtils.isCompatable(Short.class,
float.class), true);
+ assertEquals("short -> double", ReflectionUtils.isCompatable(Short.class,
double.class), true);
+ assertEquals("short -> boolean", ReflectionUtils.isCompatable(Short.class,
boolean.class), false);
+
+ // test char conversions
+ assertEquals("char -> char", ReflectionUtils.isCompatable(Character.class,
char.class), true);
+ assertEquals("char -> byte", ReflectionUtils.isCompatable(Character.class,
byte.class), false);
+ assertEquals("char -> short", ReflectionUtils.isCompatable(Character.class,
short.class), false);
+ assertEquals("char -> int", ReflectionUtils.isCompatable(Character.class,
int.class), true);
+ assertEquals("char -> long", ReflectionUtils.isCompatable(Character.class,
long.class), true);
+ assertEquals("char -> float", ReflectionUtils.isCompatable(Character.class,
float.class), true);
+ assertEquals("char -> double",
ReflectionUtils.isCompatable(Character.class, double.class), true);
+ assertEquals("char -> boolean",
ReflectionUtils.isCompatable(Character.class, boolean.class), false);
+
+ // test int conversions
+ assertEquals("int -> char", ReflectionUtils.isCompatable(Integer.class,
char.class), false);
+ assertEquals("int -> byte", ReflectionUtils.isCompatable(Integer.class,
byte.class), false);
+ assertEquals("int -> short", ReflectionUtils.isCompatable(Integer.class,
short.class), false);
+ assertEquals("int -> int", ReflectionUtils.isCompatable(Integer.class,
int.class), true);
+ assertEquals("int -> long", ReflectionUtils.isCompatable(Integer.class,
long.class), true);
+ assertEquals("int -> float", ReflectionUtils.isCompatable(Integer.class,
float.class), true);
+ assertEquals("int -> double", ReflectionUtils.isCompatable(Integer.class,
double.class), true);
+ assertEquals("int -> boolean", ReflectionUtils.isCompatable(Integer.class,
boolean.class), false);
+
+ // test long conversions
+ assertEquals("long -> char", ReflectionUtils.isCompatable(Long.class,
char.class), false);
+ assertEquals("long -> byte", ReflectionUtils.isCompatable(Long.class,
byte.class), false);
+ assertEquals("long -> short", ReflectionUtils.isCompatable(Long.class,
short.class), false);
+ assertEquals("long -> int", ReflectionUtils.isCompatable(Long.class,
int.class), false);
+ assertEquals("long -> long", ReflectionUtils.isCompatable(Long.class,
long.class), true);
+ assertEquals("long -> float", ReflectionUtils.isCompatable(Long.class,
float.class), true);
+ assertEquals("long -> double", ReflectionUtils.isCompatable(Long.class,
double.class), true);
+ assertEquals("long -> boolean", ReflectionUtils.isCompatable(Long.class,
boolean.class), false);
+
+ // test float conversions
+ assertEquals("float -> char", ReflectionUtils.isCompatable(Float.class,
char.class), false);
+ assertEquals("float -> byte", ReflectionUtils.isCompatable(Float.class,
byte.class), false);
+ assertEquals("float -> short", ReflectionUtils.isCompatable(Float.class,
short.class), false);
+ assertEquals("float -> int", ReflectionUtils.isCompatable(Float.class,
int.class), false);
+ assertEquals("float -> long", ReflectionUtils.isCompatable(Float.class,
long.class), false);
+ assertEquals("float -> float", ReflectionUtils.isCompatable(Float.class,
float.class), true);
+ assertEquals("float -> double", ReflectionUtils.isCompatable(Float.class,
double.class), true);
+ assertEquals("float -> boolean", ReflectionUtils.isCompatable(Float.class,
boolean.class), false);
+
+ // test float conversions
+ assertEquals("double -> char", ReflectionUtils.isCompatable(Double.class,
char.class), false);
+ assertEquals("double -> byte", ReflectionUtils.isCompatable(Double.class,
byte.class), false);
+ assertEquals("double -> short", ReflectionUtils.isCompatable(Double.class,
short.class), false);
+ assertEquals("double -> int", ReflectionUtils.isCompatable(Double.class,
int.class), false);
+ assertEquals("double -> long", ReflectionUtils.isCompatable(Double.class,
long.class), false);
+ assertEquals("double -> float", ReflectionUtils.isCompatable(Double.class,
float.class), false);
+ assertEquals("double -> double", ReflectionUtils.isCompatable(Double.class,
double.class), true);
+ assertEquals("double -> boolean",
ReflectionUtils.isCompatable(Double.class, boolean.class), false);
+
+ // test float conversions
+ assertEquals("boolean -> char", ReflectionUtils.isCompatable(Boolean.class,
char.class), false);
+ assertEquals("boolean -> byte", ReflectionUtils.isCompatable(Boolean.class,
byte.class), false);
+ assertEquals("boolean -> short",
ReflectionUtils.isCompatable(Boolean.class, short.class), false);
+ assertEquals("boolean -> int", ReflectionUtils.isCompatable(Boolean.class,
int.class), false);
+ assertEquals("boolean -> long", ReflectionUtils.isCompatable(Boolean.class,
long.class), false);
+ assertEquals("boolean -> float",
ReflectionUtils.isCompatable(Boolean.class, float.class), false);
+ assertEquals("boolean -> double",
ReflectionUtils.isCompatable(Boolean.class, double.class), false);
+ assertEquals("boolean -> boolean",
ReflectionUtils.isCompatable(Boolean.class, boolean.class), true);
+ }
}
--
To unsubscribe, e-mail: <mailto:[EMAIL PROTECTED]>
For additional commands, e-mail: <mailto:[EMAIL PROTECTED]>