/*************************************** * * * JBoss: The OpenSource J2EE WebOS * * * * Distributable under LGPL license. * * See terms of license at gnu.org. * * * ***************************************/ package org.jboss.util; import java.lang.reflect.Constructor; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Array; import java.lang.ref.Reference; import java.io.IOException; import java.io.ObjectOutputStream; import java.io.ObjectInputStream; import java.io.ByteArrayOutputStream; import java.io.ByteArrayInputStream; import java.io.Serializable; import org.jboss.util.coerce.CoercionHandler; import org.jboss.util.stream.Streams; /** * A collection of Object utilities. * * @version $Revision: 1.1 $ * @author Jason Dillon */ public final class Objects { ///////////////////////////////////////////////////////////////////////// // Coercion Methods // ///////////////////////////////////////////////////////////////////////// /** * Get a compatible constructor for the given value type * * @param type Class to look for constructor in * @param valueType Argument type for constructor * @return Constructor or null */ public static Constructor getCompatibleConstructor(final Class type, final Class valueType) { // first try and find a constructor with the exact argument type try { return type.getConstructor(new Class[] { valueType }); } catch (Exception ignore) { // if the above failed, then try and find a constructor with // an compatible argument type // get an array of compatible types Class[] types = type.getClasses(); for (int i=0; iPrimative classes will be translated into their respective * wrapper class as needed. * * @exception NotCoercibleException Value is not corecible. * @exception CoercionException Failed to coerce. */ public static Object coerce(final Object value, final Class type) throws CoercionException { // get the class for the given value Class valueType = value.getClass(); // if value typeis assignable (aka castable) from type then return value if (type.isAssignableFrom(valueType)) { return value; } // if the object is Coercible, then let it do the work if (value instanceof Coercible) { return ((Coercible)value).coerce(type); } // find a handler that can take a type object, let it decide if it // can actually coerce the correct object from value if (CoercionHandler.isInstalled(type)) { CoercionHandler handler = CoercionHandler.create(type); return handler.coerce(value, type); } // see if type has a construct that takes a value object // // NOTE: Just because the target type has a compatible constructor // does not nessicarily mean that by creating that object // with the source value will be the proper coercion. // Constructor c = getCompatibleConstructor(type, valueType); if (c != null) { try { return c.newInstance(new Object[] { value }); } catch (InvocationTargetException e) { // include the target exception as detail Throwable t = e.getTargetException(); if (t instanceof CoercionException) throw (CoercionException)t; throw new CoercionException(t); } catch (Exception e) { if (e instanceof CoercionException) throw (CoercionException)e; throw new CoercionException(e); } } // if type is a primitive, then get its wrapper, and recurse if (type.isPrimitive()) { return coerce(value, Classes.getPrimitiveWrapper(type)); } // if the object was not coerced by now, throw an exception throw new NotCoercibleException(value); } /** * Coerce the given values into the specified type. * *

If type is an array, then an array of that type is returned * else the first element from values is used. * *

Coerce will handle primative array types correctly by using * the reflection mechanism to unwrap primative values from their * wrapper classes. * * @param values Values to coerce. * @param type Class type to coerce object to. * @return Coerced object. * * @exception NotCoercibleException Value is not corecible. * @exception CoercionException Failed to coerce. * @exception IllegalArgumentException Indexed value is null * (values contains a null element). */ public static Object coerce(Object values[], Class type) throws CoercionException { // if the desired type is not an array, the use the first element // from the values list if (! type.isArray()) return coerce(values[0], type); // create a new array that can hold objects of the desired type type = type.getComponentType(); Object array = Array.newInstance(type, values.length); // coerce each element in the values array into the new array for (int i=0; inon-null and is an * instance of Reference. If the object is null * then null is returned. If the object is not an instance of * Reference, then the object is returned. * * @param obj Object to dereference. * @return Dereferenced object. */ public static Object deref(final Object obj) { if (obj != null && obj instanceof Reference) { Reference ref = (Reference)obj; return ref.get(); } return obj; } /** * Check if the given object is an array (primitve or native). * * @param obj Object to test. * @return True of the object is an array. */ public static boolean isArray(final Object obj) { if (obj != null) return obj.getClass().isArray(); return false; } /** * Return an Object array for the given object. * * @param obj Object to convert to an array. Converts primitive * arrays to Object arrays consisting of their wrapper * classes. If the object is not an array (object or primitve) * then a new array of the given type is created and the * object is set as the sole element. */ public static Object[] toArray(final Object obj) { // if the object is an array, the cast and return it. if (obj instanceof Object[]) { return (Object[])obj; } // if the object is an array of primitives then wrap the array Class type = obj.getClass(); Object array; if (type.isArray()) { int length = Array.getLength(obj); Class componentType = type.getComponentType(); array = Array.newInstance(componentType, length); for (int i=0; i