craigmcc 01/04/14 11:29:57
Added: beanutils/src/java/org/apache/commons/beanutils
BeanUtils.java ConvertUtils.java PropertyUtils.java
package.html
Removed: beanutils/src/share/org/apache/commons/beanutils
BeanUtils.java ConvertUtils.java PropertyUtils.java
package.html
Log:
Migrate "src/share" to "src/java" for consistency.
Revision Changes Path
1.1
jakarta-commons/beanutils/src/java/org/apache/commons/beanutils/BeanUtils.java
Index: BeanUtils.java
===================================================================
/*
* $Header:
/home/cvs/jakarta-commons/beanutils/src/java/org/apache/commons/beanutils/BeanUtils.java,v
1.1 2001/04/14 18:29:56 craigmcc Exp $
* $Revision: 1.1 $
* $Date: 2001/04/14 18:29:56 $
*
* ====================================================================
*
* The Apache Software License, Version 1.1
*
* Copyright (c) 1999-2001 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 [EMAIL PROTECTED]
*
* 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 Group.
*
* 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/>.
*
*/
package org.apache.commons.beanutils;
import java.beans.BeanInfo;
import java.beans.IndexedPropertyDescriptor;
import java.beans.IntrospectionException;
import java.beans.Introspector;
import java.beans.PropertyDescriptor;
import java.lang.reflect.Array;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import java.util.Map;
/**
* Utility methods for populating JavaBeans properties via reflection.
*
* @author Craig R. McClanahan
* @author Ralph Schaer
* @author Chris Audley
* @version $Revision: 1.1 $ $Date: 2001/04/14 18:29:56 $
*/
public class BeanUtils {
// ------------------------------------------------------ Private Variables
/**
* The debugging detail level for this component.
*/
private static int debug = 0;
public static int getDebug() {
return (debug);
}
public static void setDebug(int newDebug) {
debug = newDebug;
}
// --------------------------------------------------------- Public Classes
/**
* Clone a bean based on the available property getters and setters,
* even if the bean class itself does not implement Cloneable.
*
* @param bean Bean to be cloned
*
* @exception IllegalAccessException if the caller does not have
* access to the property accessor method
* @exception InstantiationException if a new instance of the bean's
* class cannot be instantiated
* @exception InvocationTargetException if the property accessor method
* throws an exception
* @exception NoSuchMethodException if an accessor method for this
* propety cannot be found
*/
public static Object cloneBean(Object bean)
throws IllegalAccessException, InstantiationException,
InvocationTargetException, NoSuchMethodException {
Class clazz = bean.getClass();
Object newBean = clazz.newInstance();
PropertyUtils.copyProperties(newBean, bean);
return (newBean);
}
/**
* Return the value of the specified array property of the specified
* bean, as a String array.
*
* @param bean Bean whose property is to be extracted
* @param name Name of the property to be extracted
*
* @exception IllegalAccessException if the caller does not have
* access to the property accessor method
* @exception InvocationTargetException if the property accessor method
* throws an exception
* @exception NoSuchMethodException if an accessor method for this
* propety cannot be found
*/
public static String[] getArrayProperty(Object bean, String name)
throws IllegalAccessException, InvocationTargetException,
NoSuchMethodException {
Object value = PropertyUtils.getProperty(bean, name);
if (value == null) {
return (null);
} else if (value instanceof Collection) {
ArrayList values = new ArrayList();
Iterator items = ((Collection) value).iterator();
while (items.hasNext()) {
Object item = items.next();
if (item == null)
values.add((String) null);
else
values.add(item.toString());
}
return ((String[]) values.toArray(new String[values.size()]));
} else if (value.getClass().isArray()) {
ArrayList values = new ArrayList();
try {
int n = Array.getLength(value);
for (int i = 0; i < n; i++) {
values.add(Array.get(value, i).toString());
}
} catch (ArrayIndexOutOfBoundsException e) {
;
}
return ((String[]) values.toArray(new String[values.size()]));
} else {
String results[] = new String[1];
results[0] = value.toString();
return (results);
}
}
/**
* Return the value of the specified indexed property of the specified
* bean, as a String. The zero-relative index of the
* required value must be included (in square brackets) as a suffix to
* the property name, or <code>IllegalArgumentException</code> will be
* thrown.
*
* @param bean Bean whose property is to be extracted
* @param name <code>propertyname[index]</code> of the property value
* to be extracted
*
* @exception IllegalAccessException if the caller does not have
* access to the property accessor method
* @exception InvocationTargetException if the property accessor method
* throws an exception
* @exception NoSuchMethodException if an accessor method for this
* propety cannot be found
*/
public static String getIndexedProperty(Object bean, String name)
throws IllegalAccessException, InvocationTargetException,
NoSuchMethodException {
Object value = PropertyUtils.getIndexedProperty(bean, name);
return (ConvertUtils.convert(value));
}
/**
* Return the value of the specified indexed property of the specified
* bean, as a String. The index is specified as a method parameter and
* must *not* be included in the property name expression
*
* @param bean Bean whose property is to be extracted
* @param name Simple property name of the property value to be extracted
* @param index Index of the property value to be extracted
*
* @exception IllegalAccessException if the caller does not have
* access to the property accessor method
* @exception InvocationTargetException if the property accessor method
* throws an exception
* @exception NoSuchMethodException if an accessor method for this
* propety cannot be found
*/
public static String getIndexedProperty(Object bean,
String name, int index)
throws IllegalAccessException, InvocationTargetException,
NoSuchMethodException {
StringBuffer sb = new StringBuffer(name);
sb.append(PropertyUtils.INDEXED_DELIM);
sb.append(index);
sb.append(PropertyUtils.INDEXED_DELIM2);
Object value = PropertyUtils.getIndexedProperty(bean, name);
return (ConvertUtils.convert(value));
}
/**
* Return the value of the (possibly nested) property of the specified
* name, for the specified bean, as a String.
*
* @param bean Bean whose property is to be extracted
* @param name Possibly nested name of the property to be extracted
*
* @exception IllegalAccessException if the caller does not have
* access to the property accessor method
* @exception IllegalArgumentException if a nested reference to a
* property returns null
* @exception InvocationTargetException if the property accessor method
* throws an exception
* @exception NoSuchMethodException if an accessor method for this
* propety cannot be found
*/
public static String getNestedProperty(Object bean, String name)
throws IllegalAccessException, InvocationTargetException,
NoSuchMethodException {
Object value = PropertyUtils.getNestedProperty(bean, name);
return (ConvertUtils.convert(value));
}
/**
* Return the value of the specified property of the specified bean,
* no matter which property reference format is used, as a String.
*
* @param bean Bean whose property is to be extracted
* @param name Possibly indexed and/or nested name of the property
* to be extracted
*
* @exception IllegalAccessException if the caller does not have
* access to the property accessor method
* @exception InvocationTargetException if the property accessor method
* throws an exception
* @exception NoSuchMethodException if an accessor method for this
* propety cannot be found
*/
public static String getProperty(Object bean, String name)
throws IllegalAccessException, InvocationTargetException,
NoSuchMethodException {
return (getNestedProperty(bean, name));
}
/**
* Return the value of the specified simple property of the specified
* bean, converted to a String.
*
* @param bean Bean whose property is to be extracted
* @param name Name of the property to be extracted
*
* @exception IllegalAccessException if the caller does not have
* access to the property accessor method
* @exception InvocationTargetException if the property accessor method
* throws an exception
* @exception NoSuchMethodException if an accessor method for this
* propety cannot be found
*/
public static String getSimpleProperty(Object bean, String name)
throws IllegalAccessException, InvocationTargetException,
NoSuchMethodException {
Object value = PropertyUtils.getSimpleProperty(bean, name);
return (ConvertUtils.convert(value));
}
/**
* Populate the JavaBeans properties of the specified bean, based on
* the specified name/value pairs. This method uses Java reflection APIs
* to identify corresponding "property setter" method names, and deals
* with setter arguments of type <code>String</code>, <code>boolean</code>,
* <code>int</code>, <code>long</code>, <code>float</code>, and
* <code>double</code>. In addition, array setters for these types (or the
* corresponding primitive types) can also be identified.
* <p>
* The particular setter method to be called for each property is
* determined using the usual JavaBeans introspection mechanisms. Thus,
* you may identify custom setter methods using a BeanInfo class that is
* associated with the class of the bean itself. If no such BeanInfo
* class is available, the standard method name conversion ("set" plus
* the capitalized name of the property in question) is used.
* <p>
* <strong>NOTE</strong>: It is contrary to the JavaBeans Specification
* to have more than one setter method (with different argument
* signatures) for the same property.
*
* @param bean JavaBean whose properties are being populated
* @param properties Map keyed by property name, with the
* corresponding (String or String[]) value(s) to be set
*
* @exception IllegalAccessException if the caller does not have
* access to the property accessor method
* @exception InvocationTargetException if the property accessor method
* throws an exception
*/
public static void populate(Object bean, Map properties)
throws IllegalAccessException, InvocationTargetException {
if ((bean == null) || (properties == null))
return;
/*
if (debug >= 1)
System.out.println("BeanUtils.populate(" + bean + ", " +
properties + ")");
*/
// Loop through the property name/value pairs to be set
Iterator names = properties.keySet().iterator();
while (names.hasNext()) {
// Identify the property name and value(s) to be assigned
String name = (String) names.next();
if (name == null)
continue;
Object value = properties.get(name); // String or String[]
/*
if (debug >= 1)
System.out.println(" name='" + name + "', value.class='" +
(value == null ? "NONE" :
value.getClass().getName()) + "'");
*/
// Get the property descriptor of the requested property (if any)
PropertyDescriptor descriptor = null;
try {
descriptor = PropertyUtils.getPropertyDescriptor(bean, name);
} catch (Throwable t) {
/*
if (debug >= 1)
System.out.println(" getPropertyDescriptor: " + t);
*/
descriptor = null;
}
if (descriptor == null) {
/*
if (debug >= 1)
System.out.println(" No such property, skipping");
*/
continue;
}
/*
if (debug >= 1)
System.out.println(" Property descriptor is '" +
descriptor + "'");
*/
// Identify the relevant setter method (if there is one)
Method setter = null;
if (descriptor instanceof IndexedPropertyDescriptor)
setter = ((IndexedPropertyDescriptor) descriptor).
getIndexedWriteMethod();
if (setter == null)
setter = descriptor.getWriteMethod();
if (setter == null) {
/*
if (debug >= 1)
System.out.println(" No setter method, skipping");
*/
continue;
}
Class parameterTypes[] = setter.getParameterTypes();
/*
if (debug >= 1)
System.out.println(" Setter method is '" +
setter.getName() + "(" +
parameterTypes[0].getName() +
(parameterTypes.length > 1 ?
", " + parameterTypes[1].getName() : "" )
+ ")'");
*/
Class parameterType = parameterTypes[0];
if (parameterTypes.length > 1)
parameterType = parameterTypes[1]; // Indexed setter
// Convert the parameter value as required for this setter method
Object parameters[] = new Object[1];
if (parameterTypes[0].isArray()) {
if (value instanceof String) {
String values[] = new String[1];
values[0] = (String) value;
parameters[0] = ConvertUtils.convert((String[]) values,
parameterType);
} else if (value instanceof String[]) {
parameters[0] = ConvertUtils.convert((String[]) value,
parameterType);
} else {
parameters[0] = value;
}
} else {
if (value instanceof String) {
parameters[0] = ConvertUtils.convert((String) value,
parameterType);
} else if (value instanceof String[]) {
parameters[0] = ConvertUtils.convert(((String[]) value)[0],
parameterType);
} else {
parameters[0] = value;
}
}
// Invoke the setter method
/*
if (debug >= 1)
System.out.println(" Setting to " +
(parameters[0] == null ? "NULL" :
"'" + parameters[0] + "'"));
*/
try {
PropertyUtils.setProperty(bean, name, parameters[0]);
} catch (NoSuchMethodException e) {
/*
if (debug >= 1) {
System.out.println(" CANNOT HAPPEN: " + e);
e.printStackTrace(System.out);
}
*/
}
}
/*
if (debug >= 1)
System.out.println("============================================");
*/
}
}
1.1
jakarta-commons/beanutils/src/java/org/apache/commons/beanutils/ConvertUtils.java
Index: ConvertUtils.java
===================================================================
/*
* $Header:
/home/cvs/jakarta-commons/beanutils/src/java/org/apache/commons/beanutils/ConvertUtils.java,v
1.1 2001/04/14 18:29:56 craigmcc Exp $
* $Revision: 1.1 $
* $Date: 2001/04/14 18:29:56 $
*
* ====================================================================
*
* The Apache Software License, Version 1.1
*
* Copyright (c) 1999-2001 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 [EMAIL PROTECTED]
*
* 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 Group.
*
* 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/>.
*
*/
package org.apache.commons.beanutils;
import java.lang.reflect.Array;
/**
* Utility methods for converting String values to objects of the specified
* class. If you specify a Java primitive type, or an array of a Java
* primitive type, as a destination type, a scalar or array of the coresponding
* Java wrapper class will be created instead. If you attempt to convert an
* Object or Object array of a non-String and non-primitive type, it will be
* converted to a scalar String or array of Strings, as appropriate.
*
* @author Craig R. McClanahan
* @author Ralph Schaer
* @author Chris Audley
* @version $Revision: 1.1 $ $Date: 2001/04/14 18:29:56 $
*/
public class ConvertUtils {
// ------------------------------------------------------ Static Properties
/**
* The default value for Boolean conversions.
*/
private static Boolean defaultBoolean = Boolean.FALSE;
public boolean getDefaultBoolean() {
return (defaultBoolean.booleanValue());
}
public void setDefaultBoolean(boolean defaultBoolean) {
this.defaultBoolean = new Boolean(defaultBoolean);
}
/**
* The default value for Byte conversions.
*/
private static Byte defaultByte = new Byte((byte) 0);
public byte getDefaultByte() {
return (defaultByte.byteValue());
}
public void setDefaultByte(byte defaultByte) {
this.defaultByte = new Byte(defaultByte);
}
/**
* The default value for Character conversions.
*/
private static Character defaultCharacter = new Character(' ');
public char getDefaultCharacter() {
return (defaultCharacter.charValue());
}
public void setDefaultCharacter(char defaultCharacter) {
this.defaultCharacter = new Character(defaultCharacter);
}
/**
* The default value for Double conversions.
*/
private static Double defaultDouble = new Double((double) 0.0);
public double getDefaultDouble() {
return (defaultDouble.doubleValue());
}
public void setDefaultDouble(double defaultDouble) {
this.defaultDouble = new Double(defaultDouble);
}
/**
* The default value for Float conversions.
*/
private static Float defaultFloat = new Float((float) 0.0);
public float getDefaultFloat() {
return (defaultFloat.floatValue());
}
public void setDefaultFloat(float defaultFloat) {
this.defaultFloat = new Float(defaultFloat);
}
/**
* The default value for Integer conversions.
*/
private static Integer defaultInteger = new Integer(0);
public int getDefaultInteger() {
return (defaultInteger.intValue());
}
public void setDefaultInteger(int defaultInteger) {
this.defaultInteger = new Integer(defaultInteger);
}
/**
* The default value for Long conversions.
*/
private static Long defaultLong = new Long((long) 0);
public long getDefaultLong() {
return (defaultLong.longValue());
}
public void setDefaultLong(long defaultLong) {
this.defaultLong = new Long(defaultLong);
}
/**
* The default value for Short conversions.
*/
private static Short defaultShort = new Short((short) 0);
public short getDefaultShort() {
return (defaultShort.shortValue());
}
public void setDefaultShort(short defaultShort) {
this.defaultShort = new Short(defaultShort);
}
// ------------------------------------------------------- Static Variables
/**
* The Class object for java.lang.String.
*/
private static Class stringClass = String.class;
// --------------------------------------------------------- Public Classes
/**
* Convert the specified value into a String. If the specified value
* is an array, the first element (converted to a String) will be
* returned.
*
* @param value Value to be converted (may be null)
*/
public static String convert(Object value) {
if (value == null) {
return ((String) null);
} else if (value.getClass().isArray()) {
value = Array.get(value, 0);
if (value == null)
return ((String) null);
else
return (value.toString());
} else {
return (value.toString());
}
}
/**
* Convert the specified value to an object of the specified class (if
* possible). Otherwise, return a String representation of the value.
* If you specify <code>type</code> as the name of a Java primitive
* type, an instance of the corresponding wrapper class (initialized
* to the correct value) is returned instead.
*
* @param value Value to be converted (may be null)
* @param clazz Java class to be converted to (must be java.lang.String
* or one of the primitive type wrappers)
*/
public static Object convert(String value, Class clazz) {
if (clazz == stringClass) {
if (value == null)
return ((String) null);
else
return (value);
} else if (clazz == Integer.TYPE) {
return (convertInteger(value, defaultInteger));
} else if (clazz == Boolean.TYPE) {
return (convertBoolean(value, defaultBoolean));
} else if (clazz == Long.TYPE) {
return (convertLong(value, defaultLong));
} else if (clazz == Double.TYPE) {
return (convertDouble(value, defaultDouble));
} else if (clazz == Character.TYPE) {
return (convertCharacter(value, defaultCharacter));
} else if (clazz == Byte.TYPE) {
return (convertByte(value, defaultByte));
} else if (clazz == Float.TYPE) {
return (convertFloat(value, defaultFloat));
} else if (clazz == Short.TYPE) {
return (convertShort(value, defaultShort));
} else if (clazz == Integer.class) {
return (convertInteger(value, null));
} else if (clazz == Boolean.class) {
return (convertBoolean(value, null));
} else if (clazz == Long.class) {
return (convertLong(value, null));
} else if (clazz == Double.class) {
return (convertDouble(value, null));
} else if (clazz == Character.class) {
return (convertCharacter(value, null));
} else if (clazz == Byte.class) {
return (convertByte(value, null));
} else if (clazz == Float.class) {
return (convertFloat(value, null));
} else if (clazz == Short.class) {
return (convertShort(value, null));
} else {
if (value == null)
return ((String) null);
else
return (value.toString());
}
}
/**
* Convert an array of specified values to an array of objects of the
* specified class (if possible). If you specify <code>type</code>
* as one of the Java primitive types, an array of that type will be
* returned; otherwise an array of the requested type (must be String
* or a Java wrapper class for the primitive types) will be returned.
*
* @param value Value to be converted (may be null)
* @param clazz Java array class to be converted to (must be String[],
* or an array of one of the Java primitive types)
*/
public static Object convert(String values[], Class clazz) {
Class type = clazz.getComponentType();
if (type == stringClass) {
if (values == null)
return ((String[]) null);
else
return (values);
}
int len = values.length;
if (type == Integer.TYPE) {
int array[] = new int[len];
for (int i = 0; i < len; i++)
array[i] = convertInteger(values[i], defaultInteger).intValue();
return (array);
} else if (type == Boolean.TYPE) {
boolean array[] = new boolean[len];
for (int i = 0; i < len; i++)
array[i] = convertBoolean(values[i], defaultBoolean).booleanValue();
return (array);
} else if (type == Long.TYPE) {
long array[] = new long[len];
for (int i = 0; i < len; i++)
array[i] = convertLong(values[i], defaultLong).longValue();
return (array);
} else if (type == Double.TYPE) {
double array[] = new double[len];
for (int i = 0; i < len; i++)
array[i] = convertDouble(values[i], defaultDouble).doubleValue();
return (array);
} else if (type == Character.TYPE) {
char array[] = new char[len];
for (int i = 0; i < len; i++)
array[i] = convertCharacter(values[i], defaultCharacter).charValue();
return (array);
} else if (type == Byte.TYPE) {
byte array[] = new byte[len];
for (int i = 0; i < len; i++)
array[i] = convertByte(values[i], defaultByte).byteValue();
return (array);
} else if (type == Float.TYPE) {
float array[] = new float[len];
for (int i = 0; i < len; i++)
array[i] = convertFloat(values[i], defaultFloat).floatValue();
return (array);
} else if (type == Short.TYPE) {
short array[] = new short[len];
for (int i = 0; i < len; i++)
array[i] = convertShort(values[i], defaultShort).shortValue();
return (array);
} else if (type == Integer.class) {
Integer array[] = new Integer[len];
for (int i = 0; i < len; i++)
array[i] = convertInteger(values[i], null);
return (array);
} else if (type == Boolean.class) {
Boolean array[] = new Boolean[len];
for (int i = 0; i < len; i++)
array[i] = convertBoolean(values[i], null);
return (array);
} else if (type == Long.class) {
Long array[] = new Long[len];
for (int i = 0; i < len; i++)
array[i] = convertLong(values[i], null);
return (array);
} else if (type == Double.class) {
Double array[] = new Double[len];
for (int i = 0; i < len; i++)
array[i] = convertDouble(values[i], null);
return (array);
} else if (type == Character.class) {
Character array[] = new Character[len];
for (int i = 0; i < len; i++)
array[i] = convertCharacter(values[i], null);
return (array);
} else if (type == Byte.class) {
Byte array[] = new Byte[len];
for (int i = 0; i < len; i++)
array[i] = convertByte(values[i], null);
return (array);
} else if (type == Float.class) {
Float array[] = new Float[len];
for (int i = 0; i < len; i++)
array[i] = convertFloat(values[i], null);
return (array);
} else if (type == Short.class) {
Short array[] = new Short[len];
for (int i = 0; i < len; i++)
array[i] = convertShort(values[i], null);
return (array);
} else {
if (values == null)
return ((String[]) null);
else {
String array[] = new String[len];
for (int i = 0; i < len; i++)
array[i] = values[i].toString();
return (array);
}
}
}
// -------------------------------------------------------- Private Methods
/**
* Convert a String value to a corresponding Boolean value.
*
* @param value The string value to convert
* @param defaultValue Default value to return on a conversion error
*/
private static Boolean convertBoolean(String value, Boolean defaultValue) {
if (value == null)
return (defaultValue);
else if (value.equalsIgnoreCase("yes") ||
value.equalsIgnoreCase("true") ||
value.equalsIgnoreCase("on"))
return (Boolean.TRUE);
else if (value.equalsIgnoreCase("no") ||
value.equalsIgnoreCase("false") ||
value.equalsIgnoreCase("off"))
return (Boolean.FALSE);
else
return (defaultValue);
}
/**
* Convert a String value to a corresponding Byte value.
*
* @param value The string value to convert
* @param defaultValue Default value to return on a conversion error
*/
private static Byte convertByte(String value, Byte defaultValue) {
try {
return (new Byte(value));
} catch (NumberFormatException e) {
return (defaultValue);
}
}
/**
* Convert a String value to a corresponding Character value.
*
* @param value The string value to convert
* @param defaultValue Default value to return on a conversion error
*/
private static Character convertCharacter(String value,
Character defaultValue) {
if (value == null)
return (defaultValue);
else if (value.length() == 0)
return (new Character(' '));
else
return (defaultValue);
}
/**
* Convert a String value to a corresponding Double value.
*
* @param value The string value to convert
* @param defaultValue Default value to return on a conversion error
*/
private static Double convertDouble(String value,
Double defaultValue) {
try {
return (new Double(value));
} catch (NumberFormatException e) {
return (defaultValue);
}
}
/**
* Convert a String value to a corresponding Float value.
*
* @param value The string value to convert
* @param defaultValue Default value to return on a conversion error
*/
private static Float convertFloat(String value,
Float defaultValue) {
try {
return (new Float(value));
} catch (NumberFormatException e) {
return (defaultValue);
}
}
/**
* Convert a String value to a corresponding Integer value.
*
* @param value The string value to convert
* @param defaultValue Default value to return on a conversion error
*/
private static Integer convertInteger(String value,
Integer defaultValue) {
try {
return (new Integer(value));
} catch (NumberFormatException e) {
return (defaultValue);
}
}
/**
* Convert a String value to a corresponding Long value.
*
* @param value The string value to convert
* @param defaultValue Default value to return on a conversion error
*/
private static Long convertLong(String value, Long defaultValue) {
try {
return (new Long(value));
} catch (NumberFormatException e) {
return (defaultValue);
}
}
/**
* Convert a String value to a corresponding Short value.
*
* @param value The string value to convert
* @param defaultValue Default value to return on a conversion error
*/
private static Short convertShort(String value, Short defaultValue) {
try {
return (new Short(value));
} catch (NumberFormatException e) {
return (defaultValue);
}
}
}
1.1
jakarta-commons/beanutils/src/java/org/apache/commons/beanutils/PropertyUtils.java
Index: PropertyUtils.java
===================================================================
/*
* $Header:
/home/cvs/jakarta-commons/beanutils/src/java/org/apache/commons/beanutils/PropertyUtils.java,v
1.1 2001/04/14 18:29:56 craigmcc Exp $
* $Revision: 1.1 $
* $Date: 2001/04/14 18:29:56 $
*
* ====================================================================
*
* The Apache Software License, Version 1.1
*
* Copyright (c) 1999-2001 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 [EMAIL PROTECTED]
*
* 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 Group.
*
* 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/>.
*
*/
package org.apache.commons.beanutils;
import java.beans.BeanInfo;
import java.beans.IndexedPropertyDescriptor;
import java.beans.IntrospectionException;
import java.beans.Introspector;
import java.beans.PropertyDescriptor;
import java.lang.reflect.Array;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.util.HashMap;
/**
* Utility methods for using Java Reflection APIs to facilitate generic
* property getter and setter operations on Java objects. Much of this
* code was originally included in <code>BeanUtils</code>, but has been
* separated because of the volume of code involved.
* <p>
* In general, the objects that are examined and modified using these
* methods are expected to conform to the property getter and setter method
* naming conventions described in the JavaBeans Specification (Version 1.0.1).
* No data type conversions are performed, and there are no usage of any
* <code>PropertyEditor</code> classes that have been registered, although
* a convenient way to access the registered classes themselves is included.
* <p>
* For the purposes of this class, three formats for referencing a particular
* property value of a bean are defined, with the layout of an identifying
* String in parentheses:
* <ul>
* <li><strong>Simple (<code>name</code>)</strong> - The specified
* <code>name</code> identifies an individual property of a particular
* JavaBean. The name of the actual getter or setter method to be used
* is determined using standard JavaBeans instrospection, so that (unless
* overridden by a <code>BeanInfo</code> class, a property named "xyz"
* will have a getter method named <code>getXyz()</code> or (for boolean
* properties only) <code>isXyz()</code>, and a setter method named
* <code>setXyz()</code>.</li>
* <li><strong>Nested (<code>name1.name2.name3</code>)</strong> The first
* name element is used to select a property getter, as for simple
* references above. The object returned for this property is then
* consulted, using the same approach, for a property getter for a
* property named <code>name2</code>, and so on. The property value that
* is ultimately retrieved or modified is the one identified by the
* last name element.</li>
* <li><strong>Indexed (<code>name[index]</code>)</strong> - The underlying
* property value is assumed to be an array, or this JavaBean is assumed
* to have indexed property getter and setter methods. The appropriate
* (zero-relative) entry in the array is selected.</li>
* <li><strong>Combined (<code>name1.name2[index].name3</strong> - Various
* forms combining nested and indexed references are also supported.</li>
* </ul>
*
* @author Craig R. McClanahan
* @author Ralph Schaer
* @author Chris Audley
* @version $Revision: 1.1 $ $Date: 2001/04/14 18:29:56 $
*/
public class PropertyUtils {
// ----------------------------------------------------- Manifest Constants
/**
* The delimiter that preceeds the zero-relative subscript for an
* indexed reference.
*/
public static final char INDEXED_DELIM = '[';
/**
* The delimiter that follows the zero-relative subscript for an
* indexed reference.
*/
public static final char INDEXED_DELIM2 = ']';
/**
* The delimiter that separates the components of a nested reference.
*/
public static final char NESTED_DELIM = '.';
// ------------------------------------------------------- Static Variables
/**
* The debugging detail level for this component.
*/
private static int debug = 0;
public static int getDebug() {
return (debug);
}
public static void setDebug(int newDebug) {
debug = newDebug;
}
/**
* The cache of PropertyDescriptor arrays for beans we have already
* introspected, keyed by the fully qualified class name of this object.
*/
private static HashMap descriptorsCache = new HashMap();
// --------------------------------------------------------- Public Methods
/**
* Copy property values from the "origin" bean to the "destination" bean
* for all cases where the property names are the same (even though the
* actual getter and setter methods might have been customized via
* <code>BeanInfo</code> classes). No conversions are performed on the
* actual property values -- it is assumed that the values retrieved from
* the origin bean are assignment-compatible with the types expected by
* the destination bean.
*
* @param dest Destination bean whose properties are modified
* @param orig Origin bean whose properties are retrieved
*
* @exception IllegalAccessException if the caller does not have
* access to the property accessor method
* @exception InvocationTargetException if the property accessor method
* throws an exception
* @exception NoSuchMethodException if an accessor method for this
* propety cannot be found
*/
public static void copyProperties(Object dest, Object orig)
throws IllegalAccessException, InvocationTargetException,
NoSuchMethodException {
PropertyDescriptor origDescriptors[] = getPropertyDescriptors(orig);
for (int i = 0; i < origDescriptors.length; i++) {
String name = origDescriptors[i].getName();
if (getPropertyDescriptor(dest, name) != null) {
Object value = getSimpleProperty(orig, name);
try {
setSimpleProperty(dest, name, value);
} catch (NoSuchMethodException e) {
; // Skip non-matching property
}
}
}
}
/**
* Return the value of the specified indexed property of the specified
* bean, with no type conversions. The zero-relative index of the
* required value must be included (in square brackets) as a suffix to
* the property name, or <code>IllegalArgumentException</code> will be
* thrown.
*
* @param bean Bean whose property is to be extracted
* @param name <code>propertyname[index]</code> of the property value
* to be extracted
*
* @exception IllegalAccessException if the caller does not have
* access to the property accessor method
* @exception InvocationTargetException if the property accessor method
* throws an exception
* @exception NoSuchMethodException if an accessor method for this
* propety cannot be found
*/
public static Object getIndexedProperty(Object bean, String name)
throws IllegalAccessException, InvocationTargetException,
NoSuchMethodException {
// Identify the index of the requested individual property
int delim = name.indexOf(INDEXED_DELIM);
int delim2 = name.indexOf(INDEXED_DELIM2);
if ((delim < 0) || (delim2 <= delim))
throw new IllegalArgumentException("Invalid indexed property '" +
name + "'");
int index = -1;
try {
String subscript = name.substring(delim + 1, delim2);
index = Integer.parseInt(subscript);
} catch (NumberFormatException e) {
throw new IllegalArgumentException("Invalid indexed property '" +
name + "'");
}
name = name.substring(0, delim);
// Request the specified indexed property value
return (getIndexedProperty(bean, name, index));
}
/**
* Return the value of the specified indexed property of the specified
* bean, with no type conversions.
*
* @param bean Bean whose property is to be extracted
* @param name Simple property name of the property value to be extracted
* @param index Index of the property value to be extracted
*
* @exception IllegalAccessException if the caller does not have
* access to the property accessor method
* @exception InvocationTargetException if the property accessor method
* throws an exception
* @exception NoSuchMethodException if an accessor method for this
* propety cannot be found
*/
public static Object getIndexedProperty(Object bean,
String name, int index)
throws IllegalAccessException, InvocationTargetException,
NoSuchMethodException {
// Retrieve the property descriptor for the specified property
PropertyDescriptor descriptor =
getPropertyDescriptor(bean, name);
if (descriptor == null)
throw new NoSuchMethodException("Unknown property '" +
name + "'");
// Call the indexed getter method if there is one
if (descriptor instanceof IndexedPropertyDescriptor) {
Method readMethod = ((IndexedPropertyDescriptor) descriptor).
getIndexedReadMethod();
if (readMethod != null) {
Object subscript[] = new Object[1];
subscript[0] = new Integer(index);
return (readMethod.invoke(bean, subscript));
}
}
// Otherwise, the underlying property must be an array
Method readMethod = getReadMethod(descriptor);
if (readMethod == null)
throw new NoSuchMethodException("Property '" + name +
"' has no getter method");
// Call the property getter and return the value
Object value = readMethod.invoke(bean, new Object[0]);
if (!value.getClass().isArray())
throw new IllegalArgumentException("Property '" + name +
"' is not indexed");
return (Array.get(value, index));
}
/**
* Return the value of the (possibly nested) property of the specified
* name, for the specified bean, with no type conversions.
*
* @param bean Bean whose property is to be extracted
* @param name Possibly nested name of the property to be extracted
*
* @exception IllegalAccessException if the caller does not have
* access to the property accessor method
* @exception IllegalArgumentException if a nested reference to a
* property returns null
* @exception InvocationTargetException if the property accessor method
* throws an exception
* @exception NoSuchMethodException if an accessor method for this
* propety cannot be found
*/
public static Object getNestedProperty(Object bean, String name)
throws IllegalAccessException, InvocationTargetException,
NoSuchMethodException {
while (true) {
int delim = name.indexOf(NESTED_DELIM);
if (delim < 0)
break;
String next = name.substring(0, delim);
if (next.indexOf(INDEXED_DELIM) >= 0)
bean = getIndexedProperty(bean, next);
else
bean = getSimpleProperty(bean, next);
if (bean == null)
throw new IllegalArgumentException
("Null property value for '" +
name.substring(0, delim) + "'");
name = name.substring(delim + 1);
}
if (name.indexOf(INDEXED_DELIM) >= 0)
return (getIndexedProperty(bean, name));
else
return (getSimpleProperty(bean, name));
}
/**
* Return the value of the specified property of the specified bean,
* no matter which property reference format is used, with no
* type conversions.
*
* @param bean Bean whose property is to be extracted
* @param name Possibly indexed and/or nested name of the property
* to be extracted
*
* @exception IllegalAccessException if the caller does not have
* access to the property accessor method
* @exception InvocationTargetException if the property accessor method
* throws an exception
* @exception NoSuchMethodException if an accessor method for this
* propety cannot be found
*/
public static Object getProperty(Object bean, String name)
throws IllegalAccessException, InvocationTargetException,
NoSuchMethodException {
return (getNestedProperty(bean, name));
}
/**
* Retrieve the property descriptor for the specified property of the
* specified bean, or return <code>null</code> if there is no such
* descriptor. This method resolves indexed and nested property
* references in the same manner as other methods in this class, except
* that if the last (or only) name element is indexed, the descriptor
* for the last resolved property itself is returned.
*
* @param bean Bean for which a property descriptor is requested
* @param name Possibly indexed and/or nested name of the property for
* which a property descriptor is requested
*
* @exception IllegalAccessException if the caller does not have
* access to the property accessor method
* @exception IllegalArgumentException if a nested reference to a
* property returns null
* @exception InvocationTargetException if the property accessor method
* throws an exception
* @exception NoSuchMethodException if an accessor method for this
* propety cannot be found
*/
public static PropertyDescriptor getPropertyDescriptor(Object bean,
String name)
throws IllegalAccessException, InvocationTargetException,
NoSuchMethodException {
// Resolve nested references
while (true) {
int period = name.indexOf(NESTED_DELIM);
if (period < 0)
break;
String next = name.substring(0, period);
if (next.indexOf(INDEXED_DELIM) >= 0)
bean = getIndexedProperty(bean, next);
else
bean = getSimpleProperty(bean, next);
if (bean == null)
throw new IllegalArgumentException
("Null property value for '" +
name.substring(0, period) + "'");
name = name.substring(period + 1);
}
// Remove any subscript from the final name value
int left = name.indexOf(INDEXED_DELIM);
if (left >= 0)
name = name.substring(0, left);
// Look up and return this property from our cache
if ((bean == null) || (name == null))
return (null);
PropertyDescriptor descriptors[] = getPropertyDescriptors(bean);
if (descriptors == null)
return (null);
for (int i = 0; i < descriptors.length; i++) {
if (name.equals(descriptors[i].getName()))
return (descriptors[i]);
}
return (null);
}
/**
* Retrieve the property descriptors for the specified bean, introspecting
* and caching them the first time a particular bean class is encountered.
*
* @param bean Bean for which property descriptors are requested
*/
public static PropertyDescriptor[] getPropertyDescriptors(Object bean) {
if (bean == null)
return (new PropertyDescriptor[0]);
// Look up any cached descriptors for this bean class
String beanClassName = bean.getClass().getName();
PropertyDescriptor descriptors[] = null;
synchronized (descriptorsCache) {
descriptors =
(PropertyDescriptor[]) descriptorsCache.get(beanClassName);
}
if (descriptors != null)
return (descriptors);
// Introspect the bean and cache the generated descriptors
BeanInfo beanInfo = null;
try {
beanInfo = Introspector.getBeanInfo(bean.getClass());
} catch (IntrospectionException e) {
return (new PropertyDescriptor[0]);
}
descriptors = beanInfo.getPropertyDescriptors();
if (descriptors == null)
descriptors = new PropertyDescriptor[0];
synchronized (descriptorsCache) {
descriptorsCache.put(beanClassName, descriptors);
}
return (descriptors);
}
/**
* Return the Java Class repesenting the property editor class that has
* been registered for this property (if any). This method follows the
* same name resolution rules used by <code>getPropertyDescriptor()</code>,
* so if the last element of a name reference is indexed, the property
* editor for the underlying property's class is returned.
* <p>
* Note that <code>null</code> will be returned if there is no property,
* or if there is no registered property editor class. Because this
* return value is ambiguous, you should determine the existence of the
* property itself by other means.
*
* @param bean Bean for which a property descriptor is requested
* @param name Possibly indexed and/or nested name of the property for
* which a property descriptor is requested
*
* @exception IllegalAccessException if the caller does not have
* access to the property accessor method
* @exception IllegalArgumentException if a nested reference to a
* property returns null
* @exception InvocationTargetException if the property accessor method
* throws an exception
* @exception NoSuchMethodException if an accessor method for this
* propety cannot be found
*/
public static Class getPropertyEditorClass(Object bean, String name)
throws IllegalAccessException, InvocationTargetException,
NoSuchMethodException {
PropertyDescriptor descriptor =
getPropertyDescriptor(bean, name);
if (descriptor != null)
return (descriptor.getPropertyEditorClass());
else
return (null);
}
/**
* Return the Java Class representing the property type of the specified
* property, or <code>null</code> if there is no such property for the
* specified bean. This method follows the same name resolution rules
* used by <code>getPropertyDescriptor()</code>, so if the last element
* of a name reference is indexed, the type of the property itself will
* be returned. If the last (or only) element has no property with the
* specified name, <code>null</code> is returned.
*
* @param bean Bean for which a property descriptor is requested
* @param name Possibly indexed and/or nested name of the property for
* which a property descriptor is requested
*
* @exception IllegalAccessException if the caller does not have
* access to the property accessor method
* @exception IllegalArgumentException if a nested reference to a
* property returns null
* @exception InvocationTargetException if the property accessor method
* throws an exception
* @exception NoSuchMethodException if an accessor method for this
* propety cannot be found
*/
public static Class getPropertyType(Object bean, String name)
throws IllegalAccessException, InvocationTargetException,
NoSuchMethodException {
PropertyDescriptor descriptor =
getPropertyDescriptor(bean, name);
if (descriptor == null)
return (null);
else if (descriptor instanceof IndexedPropertyDescriptor)
return (((IndexedPropertyDescriptor) descriptor).
getIndexedPropertyType());
else
return (descriptor.getPropertyType());
}
/**
* Return the value of the specified simple property of the specified
* bean, with no type conversions.
*
* @param bean Bean whose property is to be extracted
* @param name Name of the property to be extracted
*
* @exception IllegalAccessException if the caller does not have
* access to the property accessor method
* @exception IllegalArgumentException if the property name
* is nested or indexed
* @exception InvocationTargetException if the property accessor method
* throws an exception
* @exception NoSuchMethodException if an accessor method for this
* propety cannot be found
*/
public static Object getSimpleProperty(Object bean, String name)
throws IllegalAccessException, InvocationTargetException,
NoSuchMethodException {
// Validate the syntax of the property name
if (name.indexOf(NESTED_DELIM) >= 0)
throw new IllegalArgumentException
("Nested property names are not allowed");
else if (name.indexOf(INDEXED_DELIM) >= 0)
throw new IllegalArgumentException
("Indexed property names are not allowed");
// Retrieve the property getter method for the specified property
PropertyDescriptor descriptor =
getPropertyDescriptor(bean, name);
if (descriptor == null)
throw new NoSuchMethodException("Unknown property '" +
name + "'");
Method readMethod = getReadMethod(descriptor);
if (readMethod == null)
throw new NoSuchMethodException("Property '" + name +
"' has no getter method");
// Call the property getter and return the value
Object value = readMethod.invoke(bean, new Object[0]);
return (value);
}
/**
* Set the value of the specified indexed property of the specified
* bean, with no type conversions. The zero-relative index of the
* required value must be included (in square brackets) as a suffix to
* the property name, or <code>IllegalArgumentException</code> will be
* thrown.
*
* @param bean Bean whose property is to be modified
* @param name <code>propertyname[index]</code> of the property value
* to be modified
* @param value Value to which the specified property element
* should be set
*
* @exception IllegalAccessException if the caller does not have
* access to the property accessor method
* @exception InvocationTargetException if the property accessor method
* throws an exception
* @exception NoSuchMethodException if an accessor method for this
* propety cannot be found
*/
public static void setIndexedProperty(Object bean, String name,
Object value)
throws IllegalAccessException, InvocationTargetException,
NoSuchMethodException {
if (debug >= 1)
System.out.println("setIndexedProperty('" + bean + ", " +
name + ", " + value + ")");
// Identify the index of the requested individual property
int delim = name.indexOf(INDEXED_DELIM);
int delim2 = name.indexOf(INDEXED_DELIM2);
if ((delim < 0) || (delim2 <= delim))
throw new IllegalArgumentException("Invalid indexed property '" +
name + "'");
int index = -1;
try {
String subscript = name.substring(delim + 1, delim2);
index = Integer.parseInt(subscript);
} catch (NumberFormatException e) {
throw new IllegalArgumentException("Invalid indexed property '" +
name + "'");
}
name = name.substring(0, delim);
// Set the specified indexed property value
setIndexedProperty(bean, name, index, value);
}
/**
* Set the value of the specified indexed property of the specified
* bean, with no type conversions.
*
* @param bean Bean whose property is to be set
* @param name Simple property name of the property value to be set
* @param index Index of the property value to be set
* @param value Value to which the indexed property element is to be set
*
* @exception IllegalAccessException if the caller does not have
* access to the property accessor method
* @exception InvocationTargetException if the property accessor method
* throws an exception
* @exception NoSuchMethodException if an accessor method for this
* propety cannot be found
*/
public static void setIndexedProperty(Object bean, String name,
int index, Object value)
throws IllegalAccessException, InvocationTargetException,
NoSuchMethodException {
if (debug >= 1)
System.out.println("setIndexedProperty('" + bean + ", " +
name + ", " + index + ", " + value + ")");
// Retrieve the property descriptor for the specified property
PropertyDescriptor descriptor =
getPropertyDescriptor(bean, name);
if (descriptor == null)
throw new NoSuchMethodException("Unknown property '" +
name + "'");
// Call the indexed setter method if there is one
if (descriptor instanceof IndexedPropertyDescriptor) {
Method writeMethod = ((IndexedPropertyDescriptor) descriptor).
getIndexedWriteMethod();
if (writeMethod != null) {
Object subscript[] = new Object[2];
subscript[0] = new Integer(index);
subscript[1] = value;
writeMethod.invoke(bean, subscript);
return;
}
}
// Otherwise, the underlying property must be an array
Method readMethod = descriptor.getReadMethod();
if (readMethod == null)
throw new NoSuchMethodException("Property '" + name +
"' has no getter method");
// Call the property getter to get the array
Object array = readMethod.invoke(bean, new Object[0]);
if (!array.getClass().isArray())
throw new IllegalArgumentException("Property '" + name +
"' is not indexed");
// Modify the specified value
Array.set(array, index, value);
}
/**
* Set the value of the (possibly nested) property of the specified
* name, for the specified bean, with no type conversions.
*
* @param bean Bean whose property is to be modified
* @param name Possibly nested name of the property to be modified
* @param value Value to which the property is to be set
*
* @exception IllegalAccessException if the caller does not have
* access to the property accessor method
* @exception IllegalArgumentException if a nested reference to a
* property returns null
* @exception InvocationTargetException if the property accessor method
* throws an exception
* @exception NoSuchMethodException if an accessor method for this
* propety cannot be found
*/
public static void setNestedProperty(Object bean,
String name, Object value)
throws IllegalAccessException, InvocationTargetException,
NoSuchMethodException {
if (debug >= 1)
System.out.println("setNestedProperty('" + bean + ", " +
name + ", " + value + ")");
while (true) {
int delim = name.indexOf(NESTED_DELIM);
if (delim < 0)
break;
String next = name.substring(0, delim);
if (next.indexOf(INDEXED_DELIM) >= 0)
bean = getIndexedProperty(bean, next);
else
bean = getSimpleProperty(bean, next);
if (bean == null)
throw new IllegalArgumentException
("Null property value for '" +
name.substring(0, delim) + "'");
name = name.substring(delim + 1);
}
if (name.indexOf(INDEXED_DELIM) >= 0)
setIndexedProperty(bean, name, value);
else
setSimpleProperty(bean, name, value);
}
/**
* Set the value of the specified property of the specified bean,
* no matter which property reference format is used, with no
* type conversions.
*
* @param bean Bean whose property is to be modified
* @param name Possibly indexed and/or nested name of the property
* to be modified
* @param value Value to which this property is to be set
*
* @exception IllegalAccessException if the caller does not have
* access to the property accessor method
* @exception InvocationTargetException if the property accessor method
* throws an exception
* @exception NoSuchMethodException if an accessor method for this
* propety cannot be found
*/
public static void setProperty(Object bean, String name, Object value)
throws IllegalAccessException, InvocationTargetException,
NoSuchMethodException {
setNestedProperty(bean, name, value);
}
/**
* Set the value of the specified simple property of the specified bean,
* with no type conversions.
*
* @param bean Bean whose property is to be modified
* @param name Name of the property to be modified
* @param value Value to which the property should be set
*
* @exception IllegalAccessException if the caller does not have
* access to the property accessor method
* @exception IllegalArgumentException if the property name is
* nested or indexed
* @exception InvocationTargetException if the property accessor method
* throws an exception
* @exception NoSuchMethodException if an accessor method for this
* propety cannot be found
*/
public static void setSimpleProperty(Object bean,
String name, Object value)
throws IllegalAccessException, InvocationTargetException,
NoSuchMethodException {
if (debug >= 1)
System.out.println("setSimpleProperty('" + bean + ", " +
name + ", " + value + ")");
// Validate the syntax of the property name
if (name.indexOf(NESTED_DELIM) >= 0)
throw new IllegalArgumentException
("Nested property names are not allowed");
else if (name.indexOf(INDEXED_DELIM) >= 0)
throw new IllegalArgumentException
("Indexed property names are not allowed");
// Retrieve the property setter method for the specified property
PropertyDescriptor descriptor =
getPropertyDescriptor(bean, name);
if (descriptor == null)
throw new NoSuchMethodException("Unknown property '" +
name + "'");
Method writeMethod = getWriteMethod(descriptor);
if (writeMethod == null)
throw new NoSuchMethodException("Property '" + name +
"' has no setter method");
// Call the property setter method
Object values[] = new Object[1];
values[0] = value;
writeMethod.invoke(bean, values);
}
// -------------------------------------------------------- Private Methods
/**
* 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>.
*
* @param method The method that we wish to call
*/
private 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
String methodName = method.getName();
Class[] parameterTypes = method.getParameterTypes();
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) {
continue;
}
// We have found what we are looking for
return (method);
}
// We are out of luck
return (null);
}
/**
* Return an accessible property getter method for this property,
* if there is one; otherwise return <code>null</code>.
*
* @param descriptor Property descriptor to return a getter for
*/
private static Method getReadMethod(PropertyDescriptor descriptor) {
return (getAccessibleMethod(descriptor.getReadMethod()));
}
/**
* Return an accessible property setter method for this property,
* if there is one; otherwise return <code>null</code>.
*
* @param descriptor Property descriptor to return a setter for
*/
private static Method getWriteMethod(PropertyDescriptor descriptor) {
return (getAccessibleMethod(descriptor.getWriteMethod()));
}
}
1.1
jakarta-commons/beanutils/src/java/org/apache/commons/beanutils/package.html
Index: package.html
===================================================================
<html>
<head>
<title>Package Documentation for org.apache.commons.beanutils Package</title>
</head>
<body bgcolor="white">
<p>The <em>Bean Utilties</em> component of the Jakarta Commons subproject
offers low-level utility classes that assist in getting and setting property
values on Java classes that follow the naming design patterns outlined in the
JavaBeans Specification.</p>
</body>
</html>