Author: mbenson
Date: Tue Jul 3 13:07:11 2007
New Revision: 552965
URL: http://svn.apache.org/viewvc?view=rev&rev=552965
Log:
simplify BasicTypeConverter code; add support for untreated Number types +
AtomicBoolean
Modified:
jakarta/commons/proper/jxpath/trunk/src/java/org/apache/commons/jxpath/util/BasicTypeConverter.java
jakarta/commons/proper/jxpath/trunk/src/java/org/apache/commons/jxpath/util/TypeUtils.java
Modified:
jakarta/commons/proper/jxpath/trunk/src/java/org/apache/commons/jxpath/util/BasicTypeConverter.java
URL:
http://svn.apache.org/viewvc/jakarta/commons/proper/jxpath/trunk/src/java/org/apache/commons/jxpath/util/BasicTypeConverter.java?view=diff&rev=552965&r1=552964&r2=552965
==============================================================================
---
jakarta/commons/proper/jxpath/trunk/src/java/org/apache/commons/jxpath/util/BasicTypeConverter.java
(original)
+++
jakarta/commons/proper/jxpath/trunk/src/java/org/apache/commons/jxpath/util/BasicTypeConverter.java
Tue Jul 3 13:07:11 2007
@@ -18,6 +18,8 @@
import java.lang.reflect.Array;
import java.lang.reflect.Modifier;
+import java.math.BigDecimal;
+import java.math.BigInteger;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
@@ -46,64 +48,49 @@
* Returns true if it can convert the supplied
* object to the specified class.
*/
- public boolean canConvert(Object object, Class toType) {
+ public boolean canConvert(Object object, final Class toType) {
if (object == null) {
return true;
}
-
- if (toType == Object.class) {
- return true;
- }
-
+ final Class useType = TypeUtils.wrapPrimitive(toType);
Class fromType = object.getClass();
- if (fromType.equals(toType)) {
- return true;
- }
- if (toType.isAssignableFrom(fromType)) {
+ if (useType.isAssignableFrom(fromType)) {
return true;
}
- if (toType == String.class) {
+ if (useType == String.class) {
return true;
}
if (object instanceof Boolean) {
- if (toType == boolean.class
- || Number.class.isAssignableFrom(toType)) {
+ if (Number.class.isAssignableFrom(useType)
+ || "java.util.concurrent.atomic.AtomicBoolean"
+ .equals(useType.getName())) {
return true;
}
}
if (object instanceof Number) {
- if (toType.isPrimitive()
- || Number.class.isAssignableFrom(toType)) {
- return true;
- }
- }
- if (object instanceof Character) {
- if (toType == char.class) {
+ if (Number.class.isAssignableFrom(useType) || useType ==
Boolean.class) {
return true;
}
}
if (object instanceof String) {
- if (toType.isPrimitive()) {
- return true;
- }
- if (toType == Boolean.class
- || toType == Character.class
- || toType == Byte.class
- || toType == Short.class
- || toType == Integer.class
- || toType == Long.class
- || toType == Float.class
- || toType == Double.class) {
+ if (useType == Boolean.class
+ || useType == Character.class
+ || useType == Byte.class
+ || useType == Short.class
+ || useType == Integer.class
+ || useType == Long.class
+ || useType == Float.class
+ || useType == Double.class) {
return true;
}
}
if (fromType.isArray()) {
// Collection -> array
- if (toType.isArray()) {
- Class cType = toType.getComponentType();
+ if (useType.isArray()) {
+ Class cType = useType.getComponentType();
int length = Array.getLength(object);
for (int i = 0; i < length; i++) {
Object value = Array.get(object, i);
@@ -113,19 +100,19 @@
}
return true;
}
- if (Collection.class.isAssignableFrom(toType)) {
- return canCreateCollection(toType);
+ if (Collection.class.isAssignableFrom(useType)) {
+ return canCreateCollection(useType);
}
if (Array.getLength(object) > 0) {
Object value = Array.get(object, 0);
- return canConvert(value, toType);
+ return canConvert(value, useType);
}
- return canConvert("", toType);
+ return canConvert("", useType);
}
if (object instanceof Collection) {
// Collection -> array
- if (toType.isArray()) {
- Class cType = toType.getComponentType();
+ if (useType.isArray()) {
+ Class cType = useType.getComponentType();
Iterator it = ((Collection) object).iterator();
while (it.hasNext()) {
Object value = it.next();
@@ -135,8 +122,8 @@
}
return true;
}
- if (Collection.class.isAssignableFrom(toType)) {
- return canCreateCollection(toType);
+ if (Collection.class.isAssignableFrom(useType)) {
+ return canCreateCollection(useType);
}
if (((Collection) object).size() > 0) {
Object value;
@@ -147,17 +134,17 @@
Iterator it = ((Collection) object).iterator();
value = it.next();
}
- return canConvert(value, toType);
+ return canConvert(value, useType);
}
- return canConvert("", toType);
+ return canConvert("", useType);
}
if (object instanceof NodeSet) {
- return canConvert(((NodeSet) object).getValues(), toType);
+ return canConvert(((NodeSet) object).getValues(), useType);
}
if (object instanceof Pointer) {
- return canConvert(((Pointer) object).getValue(), toType);
+ return canConvert(((Pointer) object).getValue(), useType);
}
- return ConvertUtils.lookup(toType) != null;
+ return ConvertUtils.lookup(useType) != null;
}
/**
@@ -165,7 +152,7 @@
* type. Throws a runtime exception if the conversion is
* not possible.
*/
- public Object convert(Object object, Class toType) {
+ public Object convert(Object object, final Class toType) {
if (object == null) {
return toType.isPrimitive() ? convertNullToPrimitive(toType) :
null;
}
@@ -179,16 +166,17 @@
}
return object;
}
-
+ final Class useType = TypeUtils.wrapPrimitive(toType);
Class fromType = object.getClass();
- if (fromType.equals(toType) || toType.isAssignableFrom(fromType)) {
+
+ if (useType.isAssignableFrom(fromType)) {
return object;
}
if (fromType.isArray()) {
int length = Array.getLength(object);
- if (toType.isArray()) {
- Class cType = toType.getComponentType();
+ if (useType.isArray()) {
+ Class cType = useType.getComponentType();
Object array = Array.newInstance(cType, length);
for (int i = 0; i < length; i++) {
@@ -197,8 +185,8 @@
}
return array;
}
- if (Collection.class.isAssignableFrom(toType)) {
- Collection collection = allocateCollection(toType);
+ if (Collection.class.isAssignableFrom(useType)) {
+ Collection collection = allocateCollection(useType);
for (int i = 0; i < length; i++) {
collection.add(Array.get(object, i));
}
@@ -206,14 +194,14 @@
}
if (length > 0) {
Object value = Array.get(object, 0);
- return convert(value, toType);
+ return convert(value, useType);
}
- return convert("", toType);
+ return convert("", useType);
}
if (object instanceof Collection) {
int length = ((Collection) object).size();
- if (toType.isArray()) {
- Class cType = toType.getComponentType();
+ if (useType.isArray()) {
+ Class cType = useType.getComponentType();
Object array = Array.newInstance(cType, length);
Iterator it = ((Collection) object).iterator();
for (int i = 0; i < length; i++) {
@@ -222,8 +210,8 @@
}
return array;
}
- if (Collection.class.isAssignableFrom(toType)) {
- Collection collection = allocateCollection(toType);
+ if (Collection.class.isAssignableFrom(useType)) {
+ Collection collection = allocateCollection(useType);
collection.addAll((Collection) object);
return unmodifiableCollection(collection);
}
@@ -236,56 +224,55 @@
Iterator it = ((Collection) object).iterator();
value = it.next();
}
- return convert(value, toType);
+ return convert(value, useType);
}
- return convert("", toType);
+ return convert("", useType);
}
if (object instanceof NodeSet) {
- return convert(((NodeSet) object).getValues(), toType);
+ return convert(((NodeSet) object).getValues(), useType);
}
if (object instanceof Pointer) {
- return convert(((Pointer) object).getValue(), toType);
+ return convert(((Pointer) object).getValue(), useType);
}
- if (toType == String.class) {
+ if (useType == String.class) {
return object.toString();
}
if (object instanceof Boolean) {
- if (toType == boolean.class) {
- return object;
+ if (Number.class.isAssignableFrom(useType)) {
+ return allocateNumber(useType, ((Boolean)
object).booleanValue() ? 1 : 0);
}
- if (toType.isPrimitive() || Number.class.isAssignableFrom(toType))
{
- boolean value = ((Boolean) object).booleanValue();
- return allocateNumber(toType, value ? 1 : 0);
+ if
("java.util.concurrent.atomic.AtomicBoolean".equals(useType.getName())) {
+ try {
+ return useType.getConstructor(new Class[] { boolean.class
})
+ .newInstance(new Object[] { object });
+ } catch (Exception e) {
+ throw new JXPathTypeConversionException(useType.getName(),
e);
+ }
}
}
if (object instanceof Number) {
double value = ((Number) object).doubleValue();
- if (toType == boolean.class || toType == Boolean.class) {
+ if (useType == Boolean.class) {
return value == 0.0 ? Boolean.FALSE : Boolean.TRUE;
}
- if (toType.isPrimitive() || Number.class.isAssignableFrom(toType))
{
- return allocateNumber(toType, value);
- }
- }
- if (object instanceof Character) {
- if (toType == char.class) {
- return object;
+ if (Number.class.isAssignableFrom(useType)) {
+ return allocateNumber(useType, value);
}
}
if (object instanceof String) {
- Object value = convertStringToPrimitive(object, toType);
+ Object value = convertStringToPrimitive(object, useType);
if (value != null) {
return value;
}
}
- Converter converter = ConvertUtils.lookup(toType);
+ Converter converter = ConvertUtils.lookup(useType);
if (converter != null) {
- return converter.convert(toType, object);
+ return converter.convert(useType, object);
}
throw new JXPathTypeConversionException("Cannot convert "
- + object.getClass() + " to " + toType);
+ + object.getClass() + " to " + useType);
}
protected Object convertNullToPrimitive(Class toType) {
@@ -317,69 +304,93 @@
}
protected Object convertStringToPrimitive(Object object, Class toType) {
- if (toType == boolean.class || toType == Boolean.class) {
+ toType = TypeUtils.wrapPrimitive(toType);
+ if (toType == Boolean.class) {
return Boolean.valueOf((String) object);
}
- if (toType == char.class || toType == Character.class) {
+ if (toType == Character.class) {
return new Character(((String) object).charAt(0));
}
- if (toType == byte.class || toType == Byte.class) {
+ if (toType == Byte.class) {
return new Byte((String) object);
}
- if (toType == short.class || toType == Short.class) {
+ if (toType == Short.class) {
return new Short((String) object);
}
- if (toType == int.class || toType == Integer.class) {
+ if (toType == Integer.class) {
return new Integer((String) object);
}
- if (toType == long.class || toType == Long.class) {
+ if (toType == Long.class) {
return new Long((String) object);
}
- if (toType == float.class || toType == Float.class) {
+ if (toType == Float.class) {
return new Float((String) object);
}
- if (toType == double.class || toType == Double.class) {
+ if (toType == Double.class) {
return new Double((String) object);
}
return null;
}
protected Number allocateNumber(Class type, double value) {
- if (type == Byte.class || type == byte.class) {
+ type = TypeUtils.wrapPrimitive(type);
+ if (type == Byte.class) {
return new Byte((byte) value);
}
- if (type == Short.class || type == short.class) {
+ if (type == Short.class) {
return new Short((short) value);
}
- if (type == Integer.class || type == int.class) {
+ if (type == Integer.class) {
return new Integer((int) value);
}
- if (type == Long.class || type == long.class) {
+ if (type == Long.class) {
return new Long((long) value);
}
- if (type == Float.class || type == float.class) {
+ if (type == Float.class) {
return new Float((float) value);
}
- if (type == Double.class || type == double.class) {
+ if (type == Double.class) {
return new Double(value);
}
+ if (type == BigInteger.class) {
+ return BigInteger.valueOf((long) value);
+ }
+ if (type == BigDecimal.class) {
+ return new BigDecimal(value);
+ }
+ String classname = type.getName();
+ Class initialValueType = null;
+ if ("java.util.concurrent.atomic.AtomicInteger".equals(classname)) {
+ initialValueType = int.class;
+ }
+ if ("java.util.concurrent.atomic.AtomicLong".equals(classname)) {
+ initialValueType = long.class;
+ }
+ if (initialValueType != null) {
+ try {
+ return (Number) type.getConstructor(
+ new Class[] { initialValueType })
+ .newInstance(
+ new Object[] { allocateNumber(initialValueType,
+ value) });
+ } catch (Exception e) {
+ throw new JXPathTypeConversionException(classname, e);
+ }
+ }
return null;
}
protected boolean canCreateCollection(Class type) {
if (!type.isInterface()
- && ((type.getModifiers() & Modifier.ABSTRACT) == 0)) {
- return true;
- }
-
- if (type == List.class) {
- return true;
- }
-
- if (type == Set.class) {
- return true;
+ && ((type.getModifiers() & Modifier.ABSTRACT) == 0)) {
+ try {
+ type.getConstructor(new Class[0]);
+ return true;
+ } catch (Exception e) {
+ return false;
+ }
}
- return false;
+ return type == List.class || type == Collection.class || type ==
Set.class;
}
protected Collection allocateCollection(Class type) {
Modified:
jakarta/commons/proper/jxpath/trunk/src/java/org/apache/commons/jxpath/util/TypeUtils.java
URL:
http://svn.apache.org/viewvc/jakarta/commons/proper/jxpath/trunk/src/java/org/apache/commons/jxpath/util/TypeUtils.java?view=diff&rev=552965&r1=552964&r2=552965
==============================================================================
---
jakarta/commons/proper/jxpath/trunk/src/java/org/apache/commons/jxpath/util/TypeUtils.java
(original)
+++
jakarta/commons/proper/jxpath/trunk/src/java/org/apache/commons/jxpath/util/TypeUtils.java
Tue Jul 3 13:07:11 2007
@@ -16,6 +16,8 @@
*/
package org.apache.commons.jxpath.util;
+import java.util.HashMap;
+
/**
* Global type conversion utilities.
*
@@ -24,6 +26,18 @@
*/
public class TypeUtils {
private static TypeConverter typeConverter = new BasicTypeConverter();
+ private static final HashMap PRIMITIVE_TYPE_MAP = new HashMap() {
+ {
+ put(int.class, Integer.class);
+ put(byte.class, Byte.class);
+ put(short.class, Short.class);
+ put(char.class, Character.class);
+ put(long.class, Long.class);
+ put(float.class, Float.class);
+ put(double.class, Double.class);
+ put(boolean.class, Boolean.class);
+ }
+ };
/**
* Install an alternative type converter.
@@ -53,5 +67,15 @@
*/
public static Object convert(Object object, Class toType) {
return typeConverter.convert(object, toType);
+ }
+
+ /**
+ * Return the appropriate wrapper type for the specified class.
+ * @param p Class for which to retrieve a wrapper class.
+ * @return the wrapper if <code>p</code> is primitive, else <code>p</code>.
+ * @since JXPath 1.3
+ */
+ public static Class wrapPrimitive(Class p) {
+ return p.isPrimitive() ? (Class) PRIMITIVE_TYPE_MAP.get(p) : p;
}
}
---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]