You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@commons.apache.org by sc...@apache.org on 2002/09/20 01:02:51 UTC
cvs commit: jakarta-commons-sandbox/lang ConstructorUtils.java ArrayUtils.java ReflectionException.java ReflectionUtils.java
scolebourne 2002/09/19 16:02:51
Added: lang ConstructorUtils.java ArrayUtils.java
ReflectionException.java ReflectionUtils.java
Log:
Initial versions of reflection code
Revision Changes Path
1.1 jakarta-commons-sandbox/lang/ConstructorUtils.java
Index: ConstructorUtils.java
===================================================================
/* ====================================================================
* The Apache Software License, Version 1.1
*
* Copyright (c) 2002 The Apache Software Foundation. All rights
* reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. The end-user documentation included with the redistribution, if
* any, must include the following acknowlegement:
* "This product includes software developed by the
* Apache Software Foundation (http://www.apache.org/)."
* Alternately, this acknowlegement may appear in the software itself,
* if and wherever such third-party acknowlegements normally appear.
*
* 4. The names "The Jakarta Project", "Commons", and "Apache Software
* Foundation" must not be used to endorse or promote products derived
* from this software without prior written permission. For written
* permission, please contact apache@apache.org.
*
* 5. Products derived from this software may not be called "Apache"
* nor may "Apache" appear in their names without prior written
* permission of the Apache Software Foundation.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation. For more
* information on the Apache Software Foundation, please see
* <http://www.apache.org/>.
*/
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import org.apache.commons.lang.StringUtils;
/**
* <code>ConstructorUtils</code> contains utility methods for working for
* constructors by reflection.
*
* @author <a href="mailto:scolebourne@apache.org">Stephen Colebourne</a>
* @version $Id: ConstructorUtils.java,v 1.1 2002/09/19 23:02:51 scolebourne Exp $
*/
public class ConstructorUtils {
/** An empty class array */
public static final Constructor[] EMPTY_CONSTRUCTOR_ARRAY = new Constructor[0];
/**
* ConstructorUtils instances should NOT be constructed in standard programming.
* Instead, the class should be used as <code>ConstructorUtils.newInstance(...)</code>.
* This constructor is public to permit tools that require a JavaBean instance
* to operate.
*/
public ConstructorUtils() {
}
// -------------------------------------------------------------------------
/**
* Gets a public <code>Constructor</code> object by exactly matching the
* parameter types.
*
* @param cls Class object to find constructor for, must not be null
* @param types array of Class objects representing parameter types, may be null
* @return Constructor object
* @throws ReflectionException if an error occurs during reflection
* @throws IllegalArgumentException if the class is null
*/
public static Constructor getConstructorExact(Class cls, Class[] types) {
return getConstructorExact(cls, types, true);
}
/**
* Gets a <code>Constructor</code> object by exactly matching the
* parameter types.
*
* @param cls Class object to find constructor for, must not be null
* @param types array of Class objects representing parameter types, may be null
* @param publicOnly whether to only consider public constructors. If false the
* <code>setAccessible</code> method will be used
* @return Constructor object
* @throws ReflectionException if an error occurs during reflection
* @throws IllegalArgumentException if the class is null
*/
public static Constructor getConstructorExact(Class cls, Class[] types, boolean publicOnly) {
if (cls == null) {
throw new IllegalArgumentException("The class must not be null");
}
try {
if (publicOnly) {
return cls.getConstructor(types);
} else {
Constructor con = cls.getDeclaredConstructor(types);
if (Modifier.isPublic(con.getModifiers()) == false) {
con.setAccessible(true);
}
return con;
}
} catch (Throwable th) {
throw new ReflectionException(ReflectionUtils.getThrowableText(
th, "invoking constructor", cls.getName(), types, null), th);
}
}
// -------------------------------------------------------------------------
/**
* Creates a new instance using a <code>Constructor</code> and parameters.
*
* @param con Class object to find constructor for, must not be null
* @param param the single parameter to pass to the constructor, may be null
* @return the newly created object
* @throws ReflectionException if an error occurs during reflection
* @throws IllegalArgumentException if the constructor is null
*/
public static Object newInstance(Constructor con, Object param) {
return newInstance(con, new Object[] {param}, true);
}
/**
* Creates a new instance using a <code>Constructor</code> and parameters.
*
* @param con Class object to find constructor for, must not be null
* @param params array of objects to pass as parameters, may be null
* @return the newly created object
* @throws ReflectionException if an error occurs during reflection
* @throws IllegalArgumentException if the constructor is null
*/
public static Object newInstance(Constructor con, Object[] params) {
return newInstance(con, params, true);
}
/**
* Creates a new instance using a <code>Constructor</code> and parameters.
*
* @param con Class object to find constructor for, must not be null
* @param params array of objects to pass as parameters, may be null
* @param publicOnly whether to only consider public constructors. If false the
* <code>setAccessible</code> method will be used
* @return the newly created object
* @throws ReflectionException if an error occurs during reflection
* @throws IllegalArgumentException if the constructor is null
*/
public static Object newInstance(Constructor con, Object[] params, boolean publicOnly) {
if (con == null) {
throw new IllegalArgumentException("The constructor must not be null");
}
try {
if (publicOnly == false && Modifier.isPublic(con.getModifiers()) == false) {
con.setAccessible(true);
}
return con.newInstance(params);
} catch (Throwable th) {
throw new ReflectionException(ReflectionUtils.getThrowableText(
th, "invoking constructor", con.getDeclaringClass().getName(), con.getParameterTypes(), null), th);
}
}
// -------------------------------------------------------------------------
/**
* Creates a new instance of the specified <code>Class</code> by name.
*
* @param className String class name to instantiate, must not be empty
* @return the newly created object
* @throws ReflectionException if an error occurs during reflection
* @throws IllegalArgumentException if the class name is empty
*/
public static Object newInstance(String className) {
return newInstance(className, true);
}
/**
* Creates a new instance of the specified <code>Class</code> by name.
* If the constructor is not public, <code>setAccessible(true)</code>
* is used to make it accessible.
*
* @param className String class name to instantiate, must not be empty
* @param publicOnly whether to only consider public constructors. If false the
* <code>setAccessible</code> method will be used
* @return the newly created object
* @throws ReflectionException if an error occurs during reflection
* @throws IllegalArgumentException if the class name is empty
*/
public static Object newInstance(String className, boolean publicOnly) {
Class cls = ReflectionUtils.getClass(className);
return ConstructorUtils.newInstance(cls, publicOnly);
}
// -------------------------------------------------------------------------
/**
* Creates a new instance of the specified <code>Class</code>.
*
* @param cls Class object to instantiate, must not be null
* @return the newly created object
* @throws ReflectionException if an error occurs during reflection
* @throws IllegalArgumentException if the class is null
*/
public static Object newInstance(Class cls) {
return newInstance(cls, true);
}
/**
* Creates a new instance of the specified <code>Class</code>.
* If the constructor is not public, <code>setAccessible(true)</code>
* is used to make it accessible.
*
* @param cls Class object to instantiate, must not be null
* @param publicOnly whether to only consider public constructors. If false the
* <code>setAccessible</code> method will be used
* @return the newly created object
* @throws ReflectionException if an error occurs during reflection
* @throws IllegalArgumentException if the class is null
*/
public static Object newInstance(Class cls, boolean publicOnly) {
if (publicOnly) {
if (cls == null) {
throw new IllegalArgumentException("The constructor must not be null");
}
try {
return cls.newInstance();
} catch (Throwable th) {
throw new ReflectionException(ReflectionUtils.getThrowableText(
th, "instantiating class", cls.getName(), null, null), th);
}
} else {
Constructor con = ConstructorUtils.getConstructorExact(cls, null, publicOnly);
return ConstructorUtils.newInstance(con, null, publicOnly);
}
}
// -------------------------------------------------------------------------
/**
* Creates a new instance of the specified <code>Class</code>.
*
* @param cls Class object to instantiate, must not be null
* @param types array of Class objects representing parameter types, may be null
* @param params array of objects to pass as parameters, may be null
* @return the newly created object
* @throws ReflectionException if an error occurs during reflection
* @throws IllegalArgumentException if the class is null
*/
public static Object newInstanceExact(Class cls, Class[] types, Object[] params) {
return newInstanceExact(cls, types, params, true);
}
/**
* Creates a new instance of the specified <code>Class</code>.
* If the constructor is not public, <code>setAccessible(true)</code>
* is used to make it accessible.
*
* @param cls Class object to instantiate, must not be null
* @param types array of Class objects representing parameter types, may be null
* @param params array of objects to pass as parameters, may be null
* @param publicOnly whether to only consider public constructors. If false the
* <code>setAccessible</code> method will be used
* @return the newly created object
* @throws ReflectionException if an error occurs during reflection
* @throws IllegalArgumentException if the class is null
*/
public static Object newInstanceExact(Class cls, Class[] types, Object[] params, boolean publicOnly) {
Constructor con = ConstructorUtils.getConstructorExact(cls, types, publicOnly);
return ConstructorUtils.newInstance(con, params, publicOnly);
}
// -------------------------------------------------------------------------
}
1.1 jakarta-commons-sandbox/lang/ArrayUtils.java
Index: ArrayUtils.java
===================================================================
/* ====================================================================
* The Apache Software License, Version 1.1
*
* Copyright (c) 2002 The Apache Software Foundation. All rights
* reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. The end-user documentation included with the redistribution, if
* any, must include the following acknowlegement:
* "This product includes software developed by the
* Apache Software Foundation (http://www.apache.org/)."
* Alternately, this acknowlegement may appear in the software itself,
* if and wherever such third-party acknowlegements normally appear.
*
* 4. The names "The Jakarta Project", "Commons", and "Apache Software
* Foundation" must not be used to endorse or promote products derived
* from this software without prior written permission. For written
* permission, please contact apache@apache.org.
*
* 5. Products derived from this software may not be called "Apache"
* nor may "Apache" appear in their names without prior written
* permission of the Apache Software Foundation.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation. For more
* information on the Apache Software Foundation, please see
* <http://www.apache.org/>.
*/
import org.apache.commons.lang.builder.ToStringBuilder;
import org.apache.commons.lang.builder.ToStringStyle;
/**
* <code>ArrayUtils</code> contains utility methods for working for
* arrays.
*
* @author <a href="mailto:scolebourne@apache.org">Stephen Colebourne</a>
* @version $Id: ArrayUtils.java,v 1.1 2002/09/19 23:02:51 scolebourne Exp $
*/
public class ArrayUtils {
/** An empty immutable object array */
public static final Object[] EMPTY_OBJECT_ARRAY = new Object[0];
/** An empty immutable class array */
public static final Class[] EMPTY_CLASS_ARRAY = new Class[0];
/** An empty immutable string array */
public static final String[] EMPTY_STRING_ARRAY = new String[0];
/** An empty immutable long array */
public static final long[] EMPTY_LONG_ARRAY = new long[0];
/** An empty immutable int array */
public static final int[] EMPTY_INT_ARRAY = new int[0];
/** An empty immutable short array */
public static final short[] EMPTY_SHORT_ARRAY = new short[0];
/** An empty immutable byte array */
public static final byte[] EMPTY_BYTE_ARRAY = new byte[0];
/** An empty immutable double array */
public static final double[] EMPTY_DOUBLE_ARRAY = new double[0];
/** An empty immutable float array */
public static final float[] EMPTY_FLOAT_ARRAY = new float[0];
/** An empty immutable boolean array */
public static final boolean[] EMPTY_BOOLEAN_ARRAY = new boolean[0];
/**
* ArrayUtils instances should NOT be constructed in standard programming.
* Instead, the class should be used as <code>ArrayUtils.clone(new int[] {2})</code>.
* This constructor is public to permit tools that require a JavaBean instance
* to operate.
*/
public ArrayUtils() {
}
//--------------------------------------------------------------------------
/**
* Output the array as a String.
* <p>
* Multi-dimensional arrays are handled correctly, including
* multi-dimensional primitive arrays.
* The format is that of Java source code, for example {a,b}.
*
* @param array the array to get a toString for
* @return a String representation of the array
* @throws IllegalArgumentException if the array is null
*/
public static String toString(Object[] array) {
return new ToStringBuilder(array, ToStringStyle.SIMPLE_STYLE).append(array).toString();
}
/**
* Output the array as a String.
* <p>
* Multi-dimensional arrays are handled by the Object[] method.
* The format is that of Java source code, for example {1,2}.
*
* @param array the array to get a toString for
* @return a String representation of the array
* @throws IllegalArgumentException if the array is null
*/
public static String toString(long[] array) {
return new ToStringBuilder(array, ToStringStyle.SIMPLE_STYLE).append(array).toString();
}
/**
* Output the array as a String.
* <p>
* Multi-dimensional arrays are handled by the Object[] method.
* The format is that of Java source code, for example {1,2}.
*
* @param array the array to get a toString for
* @return a String representation of the array
* @throws IllegalArgumentException if the array is null
*/
public static String toString(int[] array) {
return new ToStringBuilder(array, ToStringStyle.SIMPLE_STYLE).append(array).toString();
}
/**
* Output the array as a String.
* <p>
* Multi-dimensional arrays are handled by the Object[] method.
* The format is that of Java source code, for example {1,2}.
*
* @param array the array to get a toString for
* @return a String representation of the array
* @throws IllegalArgumentException if the array is null
*/
public static String toString(short[] array) {
return new ToStringBuilder(array, ToStringStyle.SIMPLE_STYLE).append(array).toString();
}
/**
* Output the array as a String.
* <p>
* Multi-dimensional arrays are handled by the Object[] method.
* The format is that of Java source code, for example {1,2}.
*
* @param array the array to get a toString for
* @return a String representation of the array
* @throws IllegalArgumentException if the array is null
*/
public static String toString(byte[] array) {
return new ToStringBuilder(array, ToStringStyle.SIMPLE_STYLE).append(array).toString();
}
/**
* Output the array as a String.
* <p>
* Multi-dimensional arrays are handled by the Object[] method.
* The format is that of Java source code, for example {1.0,2.0}.
*
* @param array the array to get a toString for
* @return a String representation of the array
* @throws IllegalArgumentException if the array is null
*/
public static String toString(double[] array) {
return new ToStringBuilder(array, ToStringStyle.SIMPLE_STYLE).append(array).toString();
}
/**
* Output the array as a String.
* <p>
* Multi-dimensional arrays are handled by the Object[] method.
* The format is that of Java source code, for example {1.0,2.0}.
*
* @param array the array to get a toString for
* @return a String representation of the array
* @throws IllegalArgumentException if the array is null
*/
public static String toString(float[] array) {
return new ToStringBuilder(array, ToStringStyle.SIMPLE_STYLE).append(array).toString();
}
/**
* Output the array as a String.
* <p>
* Multi-dimensional arrays are handled by the Object[] method.
* The format is that of Java source code, for example {true,false}.
*
* @param array the array to get a toString for
* @return a String representation of the array
* @throws IllegalArgumentException if the array is null
*/
public static String toString(boolean[] array) {
return new ToStringBuilder(array, ToStringStyle.SIMPLE_STYLE).append(array).toString();
}
//--------------------------------------------------------------------------
/**
* Shallow clone an array.
* <p>
* The objecs in the array are not cloned.
*
* @param array the array to shallow clone
* @return the cloned array
* @throws IllegalArgumentException if the array is null
*/
public static Object[] clone(Object[] array) {
if (array == null) {
throw new IllegalArgumentException("The array must not be null");
}
return (Object[]) array.clone();
}
/**
* Clone an array.
*
* @param array the array to clone
* @return the cloned array
* @throws IllegalArgumentException if the array is null
*/
public static long[] clone(long[] array) {
if (array == null) {
throw new IllegalArgumentException("The array must not be null");
}
return (long[]) array.clone();
}
/**
* Clone an array.
*
* @param array the array to clone
* @return the cloned array
* @throws IllegalArgumentException if the array is null
*/
public static int[] clone(int[] array) {
if (array == null) {
throw new IllegalArgumentException("The array must not be null");
}
return (int[]) array.clone();
}
/**
* Clone an array.
*
* @param array the array to clone
* @return the cloned array
* @throws IllegalArgumentException if the array is null
*/
public static short[] clone(short[] array) {
if (array == null) {
throw new IllegalArgumentException("The array must not be null");
}
return (short[]) array.clone();
}
/**
* Clone an array.
*
* @param array the array to clone
* @return the cloned array
* @throws IllegalArgumentException if the array is null
*/
public static byte[] clone(byte[] array) {
if (array == null) {
throw new IllegalArgumentException("The array must not be null");
}
return (byte[]) array.clone();
}
/**
* Clone an array.
*
* @param array the array to clone
* @return the cloned array
* @throws IllegalArgumentException if the array is null
*/
public static double[] clone(double[] array) {
if (array == null) {
throw new IllegalArgumentException("The array must not be null");
}
return (double[]) array.clone();
}
/**
* Clone an array.
*
* @param array the array to clone
* @return the cloned array
* @throws IllegalArgumentException if the array is null
*/
public static float[] clone(float[] array) {
if (array == null) {
throw new IllegalArgumentException("The array must not be null");
}
return (float[]) array.clone();
}
/**
* Clone an array.
*
* @param array the array to clone
* @return the cloned array
* @throws IllegalArgumentException if the array is null
*/
public static boolean[] clone(boolean[] array) {
if (array == null) {
throw new IllegalArgumentException("The array must not be null");
}
return (boolean[]) array.clone();
}
}
1.1 jakarta-commons-sandbox/lang/ReflectionException.java
Index: ReflectionException.java
===================================================================
/* ====================================================================
* The Apache Software License, Version 1.1
*
* Copyright (c) 2002 The Apache Software Foundation. All rights
* reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. The end-user documentation included with the redistribution, if
* any, must include the following acknowlegement:
* "This product includes software developed by the
* Apache Software Foundation (http://www.apache.org/)."
* Alternately, this acknowlegement may appear in the software itself,
* if and wherever such third-party acknowlegements normally appear.
*
* 4. The names "The Jakarta Project", "Commons", and "Apache Software
* Foundation" must not be used to endorse or promote products derived
* from this software without prior written permission. For written
* permission, please contact apache@apache.org.
*
* 5. Products derived from this software may not be called "Apache"
* nor may "Apache" appear in their names without prior written
* permission of the Apache Software Foundation.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation. For more
* information on the Apache Software Foundation, please see
* <http://www.apache.org/>.
*/
import org.apache.commons.lang.exception.NestableRuntimeException;
/**
* Exception thrown when the Reflection process fails. The original
* error is wrapped within this one.
*
* @author <a href="mailto:scolebourne@joda.org">Stephen Colebourne</a>
* @version $Id: ReflectionException.java,v 1.1 2002/09/19 23:02:51 scolebourne Exp $
*/
public class ReflectionException extends NestableRuntimeException {
/**
* Constructs a new <code>ReflectionException</code> without specified
* detail message.
*/
public ReflectionException() {
super();
}
/**
* Constructs a new <code>ReflectionException</code> with specified
* detail message.
*
* @param msg The error message.
*/
public ReflectionException(String msg) {
super(msg);
}
/**
* Constructs a new <code>ReflectionException</code> with specified
* nested <code>Throwable</code>.
*
* @param cause The exception or error that caused this exception
* to be thrown.
*/
public ReflectionException(Throwable cause) {
super(cause);
}
/**
* Constructs a new <code>ReflectionException</code> with specified
* detail message and nested <code>Throwable</code>.
*
* @param msg The error message.
* @param cause The exception or error that caused this exception
* to be thrown.
*/
public ReflectionException(String msg, Throwable cause) {
super(msg, cause);
}
}
1.1 jakarta-commons-sandbox/lang/ReflectionUtils.java
Index: ReflectionUtils.java
===================================================================
/* ====================================================================
* The Apache Software License, Version 1.1
*
* Copyright (c) 2002 The Apache Software Foundation. All rights
* reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. The end-user documentation included with the redistribution, if
* any, must include the following acknowlegement:
* "This product includes software developed by the
* Apache Software Foundation (http://www.apache.org/)."
* Alternately, this acknowlegement may appear in the software itself,
* if and wherever such third-party acknowlegements normally appear.
*
* 4. The names "The Jakarta Project", "Commons", and "Apache Software
* Foundation" must not be used to endorse or promote products derived
* from this software without prior written permission. For written
* permission, please contact apache@apache.org.
*
* 5. Products derived from this software may not be called "Apache"
* nor may "Apache" appear in their names without prior written
* permission of the Apache Software Foundation.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation. For more
* information on the Apache Software Foundation, please see
* <http://www.apache.org/>.
*/
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import org.apache.commons.lang.StringUtils;
/**
* <code>MethodUtils</code> contains utility methods for working for
* methods by reflection.
*
* @author Based on code from BeanUtils
* @author <a href="mailto:scolebourne@apache.org">Stephen Colebourne</a>
* @version $Id: ReflectionUtils.java,v 1.1 2002/09/19 23:02:51 scolebourne Exp $
*/
public class ReflectionUtils {
//
// WORK IN PROGRESS - DOESN't COMPILE
//
/** An empty class array */
public static final Method[] EMPTY_METHOD_ARRAY = new Method[0];
/** An empty class array */
public static final Field[] EMPTY_FIELD_ARRAY = new Field[0];
/** An empty class array */
public static final Constructor[] EMPTY_CONSTRUCTOR_ARRAY = new Constructor[0];
// -------------------------------------------------------------------------
/**
* Gets the class name minus the package name from a Class.
*
* @param cls the class to get the short name for, must not be null
* @return the class name without the package name
* @throws IllegalArgumentException if the class is null
*/
public static String getShortClassName(Class cls) {
if (cls == null) {
throw new IllegalArgumentException("The class must not be null");
}
return getShortClassName(cls.getName());
}
/**
* Gets the class name minus the package name for an Object.
*
* @param object the class to get the short name for, must not be null
* @return the class name of the object without the package name
* @throws IllegalArgumentException if the object is null
*/
public static String getShortClassName(Object object) {
if (object == null) {
throw new IllegalArgumentException("The object must not be null");
}
return getShortClassName(object.getClass().getName());
}
/**
* Gets the class name minus the package name from a String.
* <p>
* The string passed in is assumed to be a class name - it is not
* checked.
*
* @param className the className to get the short name for, must not be empty
* @return the class name of the class without the package name
* @throws IllegalArgumentException if the className is empty
*/
public static String getShortClassName(String className) {
if (StringUtils.isEmpty(className)) {
throw new IllegalArgumentException("The className must not be empty");
}
int i = className.lastIndexOf('.');
if (i == -1) {
return className;
}
return className.substring(i + 1);
}
// -------------------------------------------------------------------------
/**
* Gets the package name of a Class.
*
* @param cls the class to get the package name for, must not be null
* @return the package name
* @throws IllegalArgumentException if the class is null
*/
public static String getPackageName(Class cls) {
if (cls == null) {
throw new IllegalArgumentException("The class must not be null");
}
return getPackageName(cls.getName());
}
/**
* Gets the package name of an Object.
*
* @param object the class to get the package name for, must not be null
* @return the package name
* @throws IllegalArgumentException if the object is null
*/
public static String getPackageName(Object object) {
if (object == null) {
throw new IllegalArgumentException("The object must not be null");
}
return getPackageName(object.getClass().getName());
}
/**
* Gets the package name from a String.
* <p>
* The string passed in is assumed to be a class name - it is not
* checked.
*
* @param className the className to get the package name for, must not be empty
* @return the package name
* @throws IllegalArgumentException if the className is empty
*/
public static String getPackageName(String className) {
if (StringUtils.isEmpty(className)) {
throw new IllegalArgumentException("The className must not be empty");
}
int i = className.lastIndexOf('.');
if (i == -1) {
return "";
}
return className.substring(0, i);
}
// -------------------------------------------------------------------------
/**
* Gets a class object for the specified string.
*
* @param className fully qualified class name to find, must not be empty
* @return Class object for class
* @throws ReflectionException if an error occurs during reflection
* @throws IllegalArgumentException if the class name is empty
*/
public static Class getClass(String className) throws ReflectionException {
if (StringUtils.isEmpty(className)) {
throw new IllegalArgumentException("The class name must not be null");
}
try {
return Class.forName(className);
} catch (ExceptionInInitializerError ex) {
throw new ReflectionException("ExceptionInInitializerError while creating Class '" + className + "'", ex);
} catch (NoClassDefFoundError ex) {
throw new ReflectionException("NoClassDefFoundError while creating Class '" + className + "'", ex);
} catch (LinkageError ex) {
throw new ReflectionException("LinkageError while creating Class '" + className + "'", ex);
} catch (ClassNotFoundException ex) {
throw new ReflectionException("ClassNotFoundException while creating Class '" + className + "'", ex);
}
}
// -------------------------------------------------------------------------
/**
* <p>Invoke a named method whose parameter type matches the object type.</p>
*
* <p>The behaviour of this method is less deterministic
* than {@link #invokeExactMethod}.
* It loops through all methods with names that match
* and then executes the first it finds with compatable parameters.</p>
*
* <p>This method supports calls to methods taking primitive parameters
* via passing in wrapping classes. So, for example, a <code>Boolean</code> class
* would match a <code>boolean</code> primitive.</p>
*
* <p> This is a convenient wrapper for
* {@link #invokeMethod(Object object,String methodName,Object [] args)}.
* </p>
*
* @param objectToInvoke invoke method on this object, must not be null
* @param methodName get method with this name, must not be null
* @param arg use this argument, must not be null
*
* @throws NoSuchMethodException if there is no such accessible method
* @throws InvocationTargetException wraps an exception thrown by the
* method invoked
* @throws IllegalAccessException if the requested method is not accessible
* via reflection
* @throws IllegalArgumentException if any parameter is null
*/
public static Object invokeMethod(
Object objectToInvoke,
String methodName,
Object arg)
throws
NoSuchMethodException,
IllegalAccessException,
InvocationTargetException {
if (objectToInvoke == null) {
throw new IllegalArgumentException("The object to invoke must not be null");
}
if (methodName == null) {
throw new IllegalArgumentException("The method name must not be null");
}
if (arg == null) {
throw new IllegalArgumentException("The argument must not be null");
}
Object[] args = {arg};
return invokeMethod(objectToInvoke, methodName, args);
}
/**
* <p>Invoke a named method whose parameter type matches the object type.</p>
*
* <p>The behaviour of this method is less deterministic
* than {@link #invokeExactMethod(Object object,String methodName,Object [] args)}.
* It loops through all methods with names that match
* and then executes the first it finds with compatable parameters.</p>
*
* <p>This method supports calls to methods taking primitive parameters
* via passing in wrapping classes. So, for example, a <code>Boolean</code> class
* would match a <code>boolean</code> primitive.</p>
*
* <p> This is a convenient wrapper for
* {@link #invokeMethod(Object object,String methodName,Object [] args,Class[] parameterTypes)}.
* </p>
*
* @param objectToInvoke invoke method on this object, must not be null
* @param methodName get method with this name, must not be null
* @param args use these arguments - treat null as empty array
*
* @throws NoSuchMethodException if there is no such accessible method
* @throws InvocationTargetException wraps an exception thrown by the
* method invoked
* @throws IllegalAccessException if the requested method is not accessible
* via reflection
* @throws IllegalArgumentException if the objectToInvoke, methodName or any argument is null
*/
public static Object invokeMethod(
Object objectToInvoke,
String methodName,
Object[] args)
throws
NoSuchMethodException,
IllegalAccessException,
InvocationTargetException {
if (objectToInvoke == null) {
throw new IllegalArgumentException("The object to invoke must not be null");
}
if (methodName == null) {
throw new IllegalArgumentException("The method name must not be null");
}
if (args == null) {
return invokeMethod(objectToInvoke, methodName, null, null);
} else {
int arguments = args.length;
Class parameterTypes [] = new Class[arguments];
for (int i = 0; i < arguments; i++) {
if (args[i] == null) {
throw new IllegalArgumentException("The arguments must not be null. Index " + i + " was null.");
}
parameterTypes[i] = args[i].getClass();
}
return invokeMethod(objectToInvoke, methodName, args, parameterTypes);
}
}
/**
* <p>Invoke a named method whose parameter type matches the object type.</p>
*
* <p>The behaviour of this method is less deterministic
* than {@link
* #invokeExactMethod(Object object,String methodName,Object [] args,Class[] parameterTypes)}.
* It loops through all methods with names that match
* and then executes the first it finds with compatable parameters.</p>
*
* <p>This method supports calls to methods taking primitive parameters
* via passing in wrapping classes. So, for example, a <code>Boolean</code> class
* would match a <code>boolean</code> primitive.</p>
*
*
* @param object invoke method on this object
* @param methodName get method with this name
* @param args use these arguments - treat null as empty array
* @param parameterTypes match these parameters - treat null as empty array
*
* @throws NoSuchMethodException if there is no such accessible method
* @throws InvocationTargetException wraps an exception thrown by the
* method invoked
* @throws IllegalAccessException if the requested method is not accessible
* via reflection
*/
public static Object invokeMethod(
Object object,
String methodName,
Object[] args,
Class[] parameterTypes)
throws
NoSuchMethodException,
IllegalAccessException,
InvocationTargetException {
if (parameterTypes == null) {
parameterTypes = emptyClassArray;
}
if (args == null) {
args = emptyObjectArray;
}
Method method = getMatchingAccessibleMethod(
object.getClass(),
methodName,
parameterTypes);
if (method == null)
throw new NoSuchMethodException("No such accessible method: " +
methodName + "() on object: " + object.getClass().getName());
return method.invoke(object, args);
}
/**
* <p>Invoke a method whose parameter type matches exactly the object
* type.</p>
*
* <p> This is a convenient wrapper for
* {@link #invokeExactMethod(Object object,String methodName,Object [] args)}.
* </p>
*
* @param object invoke method on this object
* @param methodName get method with this name
* @param arg use this argument
*
* @throws NoSuchMethodException if there is no such accessible method
* @throws InvocationTargetException wraps an exception thrown by the
* method invoked
* @throws IllegalAccessException if the requested method is not accessible
* via reflection
*/
public static Object invokeExactMethod(
Object object,
String methodName,
Object arg)
throws
NoSuchMethodException,
IllegalAccessException,
InvocationTargetException {
Object[] args = {arg};
return invokeExactMethod(object, methodName, args);
}
/**
* <p>Invoke a method whose parameter types match exactly the object
* types.</p>
*
* <p> This uses reflection to invoke the method obtained from a call to
* {@link #getAccessibleMethod}.</p>
*
* @param object invoke method on this object
* @param methodName get method with this name
* @param args use these arguments - treat null as empty array
*
* @throws NoSuchMethodException if there is no such accessible method
* @throws InvocationTargetException wraps an exception thrown by the
* method invoked
* @throws IllegalAccessException if the requested method is not accessible
* via reflection
*/
public static Object invokeExactMethod(
Object object,
String methodName,
Object[] args)
throws
NoSuchMethodException,
IllegalAccessException,
InvocationTargetException {
if (args == null) {
args = emptyObjectArray;
}
int arguments = args.length;
Class parameterTypes [] = new Class[arguments];
for (int i = 0; i < arguments; i++) {
parameterTypes[i] = args[i].getClass();
}
return invokeExactMethod(object, methodName, args, parameterTypes);
}
/**
* <p>Invoke a method whose parameter types match exactly the parameter
* types given.</p>
*
* <p>This uses reflection to invoke the method obtained from a call to
* {@link #getAccessibleMethod}.</p>
*
* @param object invoke method on this object
* @param methodName get method with this name
* @param args use these arguments - treat null as empty array
* @param parameterTypes match these parameters - treat null as empty array
*
* @throws NoSuchMethodException if there is no such accessible method
* @throws InvocationTargetException wraps an exception thrown by the
* method invoked
* @throws IllegalAccessException if the requested method is not accessible
* via reflection
*/
public static Object invokeExactMethod(
Object object,
String methodName,
Object[] args,
Class[] parameterTypes)
throws
NoSuchMethodException,
IllegalAccessException,
InvocationTargetException {
if (args == null) {
args = emptyObjectArray;
}
if (parameterTypes == null) {
parameterTypes = emptyClassArray;
}
Method method = getAccessibleMethod(
object.getClass(),
methodName,
parameterTypes);
if (method == null)
throw new NoSuchMethodException("No such accessible method: " +
methodName + "() on object: " + object.getClass().getName());
return method.invoke(object, args);
}
/**
* <p>Return an accessible method (that is, one that can be invoked via
* reflection) with given name and a single parameter. If no such method
* can be found, return <code>null</code>.
* Basically, a convenience wrapper that constructs a <code>Class</code>
* array for you.</p>
*
* @param clazz get method from this class
* @param methodName get method with this name
* @param parameterType taking this type of parameter
*/
public static Method getAccessibleMethod(
Class clazz,
String methodName,
Class parameterType) {
Class[] parameterTypes = {parameterType};
return getAccessibleMethod(clazz, methodName, parameterTypes);
}
/**
* <p>Return an accessible method (that is, one that can be invoked via
* reflection) with given name and parameters. If no such method
* can be found, return <code>null</code>.
* This is just a convenient wrapper for
* {@link #getAccessibleMethod(Method method)}.</p>
*
* @param clazz get method from this class
* @param methodName get method with this name
* @param parameterTypes with these parameters types
*/
public static Method getAccessibleMethod(
Class clazz,
String methodName,
Class[] parameterTypes) {
try {
return getAccessibleMethod
(clazz.getMethod(methodName, parameterTypes));
} catch (NoSuchMethodException e) {
return (null);
}
}
/**
* <p>Return an accessible method (that is, one that can be invoked via
* reflection) that implements the specified Method. If no such method
* can be found, return <code>null</code>.</p>
*
* @param method The method that we wish to call
*/
public static Method getAccessibleMethod(Method method) {
// Make sure we have a method to check
if (method == null) {
return (null);
}
// If the requested method is not public we cannot call it
if (!Modifier.isPublic(method.getModifiers())) {
return (null);
}
// If the declaring class is public, we are done
Class clazz = method.getDeclaringClass();
if (Modifier.isPublic(clazz.getModifiers())) {
return (method);
}
// Check the implemented interfaces and subinterfaces
String methodName = method.getName();
Class[] parameterTypes = method.getParameterTypes();
method =
getAccessibleMethodFromInterfaceNest(clazz,
method.getName(),
method.getParameterTypes());
return (method);
}
// -------------------------------------------------------- Private Methods
/**
* <p>Return an accessible method (that is, one that can be invoked via
* reflection) that implements the specified method, by scanning through
* all implemented interfaces and subinterfaces. If no such method
* can be found, return <code>null</code>.</p>
*
* <p> There isn't any good reason why this method must be private.
* It is because there doesn't seem any reason why other classes should
* call this rather than the higher level methods.</p>
*
* @param clazz Parent class for the interfaces to be checked
* @param methodName Method name of the method we wish to call
* @param parameterTypes The parameter type signatures
*/
private static Method getAccessibleMethodFromInterfaceNest
(Class clazz, String methodName, Class parameterTypes[]) {
Method method = null;
// Search up the superclass chain
for (; clazz != null; clazz = clazz.getSuperclass()) {
// Check the implemented interfaces of the parent class
Class interfaces[] = clazz.getInterfaces();
for (int i = 0; i < interfaces.length; i++) {
// Is this interface public?
if (!Modifier.isPublic(interfaces[i].getModifiers()))
continue;
// Does the method exist on this interface?
try {
method = interfaces[i].getDeclaredMethod(methodName,
parameterTypes);
} catch (NoSuchMethodException e) {
;
}
if (method != null)
break;
// Recursively check our parent interfaces
method =
getAccessibleMethodFromInterfaceNest(interfaces[i],
methodName,
parameterTypes);
if (method != null)
break;
}
}
// If we found a method return it
if (method != null)
return (method);
// We did not find anything
return (null);
}
/**
* <p>Find an accessible method that matches the given name and has compatible parameters.
* Compatible parameters mean that every method parameter is assignable from
* the given parameters.
* In other words, it finds a method with the given name
* that will take the parameters given.<p>
*
* <p>This method is slightly undeterminstic since it loops
* through methods names and return the first matching method.</p>
*
* <p>This method is used by
* {@link
* #invokeMethod(Object object,String methodName,Object [] args,Class[] parameterTypes)}.
*
* <p>This method can match primitive parameter by passing in wrapper classes.
* For example, a <code>Boolean</code> will match a primitive <code>boolean</code>
* parameter.
*
* @param clazz find method in this class
* @param methodName find method with this name
* @param parameterTypes find method with compatible parameters
*/
private static Method getMatchingAccessibleMethod(
Class clazz,
String methodName,
Class[] parameterTypes) {
// trace logging
if (log.isTraceEnabled()) {
log.trace("Matching name=" + methodName + " on " + clazz);
}
// see if we can find the method directly
// most of the time this works and it's much faster
try {
Method method = clazz.getMethod(methodName, parameterTypes);
return method;
} catch (NoSuchMethodException e) { /* SWALLOW */ }
// search through all methods
int paramSize = parameterTypes.length;
Method[] methods = clazz.getMethods();
for (int i = 0, size = methods.length; i < size ; i++) {
if (methods[i].getName().equals(methodName)) {
// log some trace information
if (log.isTraceEnabled()) {
log.trace("Found matching name:");
log.trace(methods[i]);
}
// compare parameters
Class[] methodsParams = methods[i].getParameterTypes();
int methodParamSize = methodsParams.length;
if (methodParamSize == paramSize) {
boolean match = true;
for (int n = 0 ; n < methodParamSize; n++) {
if (log.isTraceEnabled()) {
log.trace("Param=" + parameterTypes[n].getName());
log.trace("Method=" + methodsParams[n].getName());
}
if (!isAssignmentCompatible(methodsParams[n], parameterTypes[n])) {
if (log.isTraceEnabled()) {
log.trace(methodsParams[n] + " is not assignable from "
+ parameterTypes[n]);
}
match = false;
break;
}
}
if (match) {
// get accessible version of method
Method method = getAccessibleMethod(methods[i]);
if (method != null) {
if (log.isTraceEnabled()) {
log.trace(method + " accessible version of "
+ methods[i]);
}
return method;
}
log.trace("Couldn't find accessible method.");
}
}
}
}
// didn't find a match
log.trace("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;
}
/**
* Gets the Field for the specified parameters.
*
* @return java.lang.reflect.Field
* @param cls java.lang.Class
* @param fieldName java.lang.String
*/
public static Field getField(Class cls, String fieldName) throws ReflectionException {
try {
return cls.getDeclaredField(fieldName);
} catch (NullPointerException ex) {
throw new ReflectionException(ex, "The class cannot be null");
} catch (NoSuchFieldException ex) {
throw new ReflectionException(ex, "The field '" + fieldName + "' does not exist on " + cls.getName());
}
}
/**
* Gets the value of the field on the object
* @return java.lang.Object
* @param cls java.lang.Class
* @param fieldName java.lang.String
* @param calledObj java.lang.Object
*/
public static Object getFieldValue(Class cls, String fieldName, Object calledObject) throws ReflectionException {
try {
return cls.getDeclaredField(fieldName).get(calledObject);
} catch (IllegalAccessException ex) {
throw new ReflectionException(ex, "The field cannot be accessed");
} catch (NullPointerException ex) {
throw new ReflectionException(ex, "The class cannot be null");
} catch (NoSuchFieldException ex) {
throw new ReflectionException(ex, "The field '" + fieldName + "' does not exist on " + cls.getName());
}
}
/**
* Gets the Method for the specified parameters. The method to be searched
* for has no parameters.
* @return java.lang.reflect.Method
* @param cls java.lang.Class
* @param methodName java.lang.String
*/
public static Method getMethod(Class cls, String methodName) throws ReflectionException {
return Reflection.getMethod(cls, methodName, (Class[]) null);
}
/**
* Gets the Method for the specified parameters.
* @return java.lang.reflect.Method
* @param cls java.lang.Class
* @param methodName java.lang.String
* @param types java.lang.Class[]
*/
public static Method getMethod(Class cls, String methodName, Class[] types) throws ReflectionException {
if ((methodName == null) || (methodName.length() == 0)) {
throw new ReflectionException(new IllegalArgumentException(), "Method name cannot be null");
}
try {
return cls.getMethod(methodName, types);
} catch (NullPointerException ex) {
throw new ReflectionException(ex, "The Class cannot be null");
} catch (NoSuchMethodException ex) {
throw new ReflectionException(ex, "The Method '" + methodName + "' does not exist");
} catch (SecurityException ex) {
throw new ReflectionException(ex);
}
}
/**
* Gets the Method for the specified parameters. The method to be searched
* for has no parameters.
* @return java.lang.reflect.Method
* @param className java.lang.String
* @param methodName java.lang.String
*/
public static Method getMethod(String className, String methodName) throws ReflectionException {
return Reflection.getMethod(getClass(className), methodName);
}
/**
* Gets the Method for the specified parameters.
* @return java.lang.reflect.Method
* @param className java.lang.String
* @param methodName java.lang.String
* @param types java.lang.Class[]
*/
public static Method getMethod(String className, String methodName, Class[] types) throws ReflectionException {
return Reflection.getMethod(getClass(className), methodName, types);
}
/**
* Invoke a method with no parameters.
*/
public static Object invokeMethod(Method mth, Object obj) throws IllegalArgumentException, ReflectionException {
return Reflection.invokeMethod(mth, obj, (Object[]) null);
}
/**
* Invoke a method.
*/
public static Object invokeMethod(Method mth, Object obj, Object[] args)
throws IllegalArgumentException, ReflectionException {
try {
return mth.invoke(obj, args); // Handles statics OK as well.
} catch (NullPointerException ex) {
throw new ReflectionException(ex, "The Method cannot be null");
} catch (InvocationTargetException ex) {
throw new ReflectionException(ex, "The Method '" + mth + "' threw an exception");
} catch (IllegalAccessException ex) {
throw new ReflectionException(ex, "The Method '" + mth + "' is not public");
}
}
/**
* Invoke a method with no parameters.
*/
public static Object invokeMethod(String methodName, Object obj)
throws IllegalArgumentException, ReflectionException {
Method mth = Reflection.getMethod(obj.getClass(), methodName);
return Reflection.invokeMethod(mth, obj);
}
/**
* Invoke a method.
*/
public static Object invokeMethod(String methodName, Object obj, Class[] types, Object[] args)
throws IllegalArgumentException, ReflectionException {
Method mth = Reflection.getMethod(obj.getClass(), methodName, types);
return Reflection.invokeMethod(mth, obj, args);
}
/**
* Tests whether the specified field is a static or not
* @return boolean
* @param mth java.lang.reflect.Field
*/
public static boolean isStatic(Field fld) {
return Modifier.isStatic(fld.getModifiers());
}
/**
* Tests whether the specified method is a static or not
* @return boolean
* @param mth java.lang.reflect.Method
*/
public static boolean isStatic(Method mth) {
return Modifier.isStatic(mth.getModifiers());
}
/**
* Gets a list of all interfaces implemented by the given class.
* @return the list of interfaces
* @param cls the class to look up
*/
public static List getAllInterfaces(Class cls) {
if (cls == null) {
return new ArrayList();
}
Set classes = new HashSet();
Class[] interfaces = cls.getInterfaces();
for (int i = 0; i < interfaces.length; i++) {
classes.add(interfaces[i]);
classes.addAll(getAllInterfaces(interfaces[i]));
}
classes.addAll(getAllInterfaces(cls.getSuperclass()));
return new ArrayList(classes);
}
/**
* Gets a list of super classes for the given class.
* @return the list of classes
* @param cls the class to look up
*/
public static List getAllSuperClasses(Class cls) {
List classes = new ArrayList();
if (cls != null) {
Class superClass = cls.getSuperclass();
if (superClass != null) {
classes.add(superClass);
classes.addAll(getAllSuperClasses(superClass));
}
}
return classes;
}
/**
* Given a list of classes, this method finds all those which are
* subclasses or implementations of a specified super class
* @return the list of subclasses or implementors
* @param classes the classes to check
* @param superClass the super class to check for
*/
public static List getAllSubclasses(List classes, Class superClass) {
List clsss = new ArrayList();
Iterator it = classes.iterator();
while (it.hasNext()) {
Class cls = (Class) it.next();
if (superClass.isAssignableFrom(cls)) {
clsss.add(cls);
}
}
return clsss;
}
/**
* Get the array of types for error messages
*/
static String getClassArrayString(Class[] array) {
return array == null ? "{}" : ArrayUtils.toString(array);
}
/**
* Produce nice error messages
*/
static String getThrowableText(Throwable th, String desc, String className, Class[] types, String methodName) {
String message = null;
try {
throw th;
} catch (ExceptionInInitializerError ex) {
message = "the class initialization threw an exception";
} catch (InvocationTargetException ex) {
message = "the method threw an exception";
} catch (NoSuchMethodException ex) {
message = "the method does not exist";
} catch (InstantiationException ex) {
message = "the class is abstract/interface/array/primitive";
} catch (IllegalAccessException ex) {
message = "the method was not public/accessible";
} catch (IllegalArgumentException ex) {
message = "the parameters did not match those expected";
} catch (SecurityException ex) {
message = "the security manager is blocking reflection";
} catch (Throwable ex) {
message = null;
}
StringBuffer buf = new StringBuffer();
buf.append(ReflectionUtils.getShortClassName(th));
buf.append(" while ");
buf.append(desc);
buf.append(" on Class '");
buf.append(className);
buf.append("'");
if (types != null) {
buf.append(" for types ");
buf.append(ReflectionUtils.getClassArrayString(types));
}
if (methodName != null) {
buf.append(" for method '");
buf.append(methodName);
buf.append("'");
}
if (message != null) {
buf.append(" - ");
buf.append(message);
}
return buf.toString();
}
}
--
To unsubscribe, e-mail: <ma...@jakarta.apache.org>
For additional commands, e-mail: <ma...@jakarta.apache.org>