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
BeanUtils
, but has been
separated because of the volume of code involved.
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
PropertyEditor
classes that have been registered, although
a convenient way to access the registered classes themselves is included.
For the purposes of this class, five formats for referencing a particular
property value of a bean are defined, with the layout of an identifying
String in parentheses:
- Simple (
name
) - The specified
name
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 BeanInfo
class, a property named "xyz"
will have a getter method named getXyz()
or (for boolean
properties only) isXyz()
, and a setter method named
setXyz()
. - Nested (
name1.name2.name3
) 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 name2
, and so on. The property value that
is ultimately retrieved or modified is the one identified by the
last name element. - Indexed (
name[index]
) - 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. List
objects are now also supported for read/write. You simply need to define
a getter that returns the List
- Mapped (
name(key)
) - The JavaBean
is assumed to have an property getter and setter methods with an
additional attribute of type java.lang.String
. - Combined (
name1.name2[index].name3(key)
) -
Combining mapped, nested, and indexed references is also
supported.
clearDescriptors
public void clearDescriptors()
Clear any cached property descriptors information for all classes
loaded by any class loaders. This is useful in cases where class
loaders are thrown away to implement class reloading.
copyProperties
public void copyProperties(Object dest,
Object orig)
throws IllegalAccessException,
InvocationTargetException,
NoSuchMethodException
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
BeanInfo
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.
If the origin "bean" is actually a
Map
, it is assumed
to contain String-valued
simple property names as the keys, pointing
at the corresponding property values that will be set in the destination
bean.
Note that this method is intended to perform
a "shallow copy" of the properties and so complex properties
(for example, nested ones) will not be copied.
dest
- Destination bean whose properties are modifiedorig
- Origin bean whose properties are retrieved
describe
public Map describe(Object bean)
throws IllegalAccessException,
InvocationTargetException,
NoSuchMethodException
Return the entire set of properties for which the specified bean
provides a read method. This map contains the unconverted property
values for all properties for which a read method is provided
(i.e. where the
getReadMethod()
returns non-null).
FIXME - Does not account for mapped properties.
bean
- Bean whose properties are to be extracted
findNextNestedIndex
private int findNextNestedIndex(String expression)
getIndexedProperty
public Object getIndexedProperty(Object bean,
String name)
throws IllegalAccessException,
InvocationTargetException,
NoSuchMethodException
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 IllegalArgumentException
will be
thrown. In addition to supporting the JavaBeans specification, this
method has been extended to support List
objects as well.
bean
- Bean whose property is to be extractedname
- propertyname[index]
of the property value
to be extracted
getIndexedProperty
public Object getIndexedProperty(Object bean,
String name,
int index)
throws IllegalAccessException,
InvocationTargetException,
NoSuchMethodException
Return the value of the specified indexed property of the specified
bean, with no type conversions. In addition to supporting the JavaBeans
specification, this method has been extended to support
List
objects as well.
bean
- Bean whose property is to be extractedname
- Simple property name of the property value to be extractedindex
- Index of the property value to be extracted
getMappedProperty
public Object getMappedProperty(Object bean,
String name)
throws IllegalAccessException,
InvocationTargetException,
NoSuchMethodException
Return the value of the specified mapped property of the
specified bean, with no type conversions. The key of the
required value must be included (in brackets) as a suffix to
the property name, or IllegalArgumentException
will be
thrown.
bean
- Bean whose property is to be extractedname
- propertyname(key)
of the property value
to be extracted
getMappedProperty
public Object getMappedProperty(Object bean,
String name,
String key)
throws IllegalAccessException,
InvocationTargetException,
NoSuchMethodException
Return the value of the specified mapped property of the specified
bean, with no type conversions.
bean
- Bean whose property is to be extractedname
- Mapped property name of the property value to be extractedkey
- Key of the property value to be extracted
getMappedPropertyDescriptors
public FastHashMap getMappedPropertyDescriptors(Class beanClass)
This method should not be exposed
Return the mapped property descriptors for this bean class.
FIXME - Does not work with DynaBeans.
beanClass
- Bean class to be introspected
getMappedPropertyDescriptors
public FastHashMap getMappedPropertyDescriptors(Object bean)
This method should not be exposed
Return the mapped property descriptors for this bean.
FIXME - Does not work with DynaBeans.
bean
- Bean to be introspected
getNestedProperty
public Object getNestedProperty(Object bean,
String name)
throws IllegalAccessException,
InvocationTargetException,
NoSuchMethodException
Return the value of the (possibly nested) property of the specified
name, for the specified bean, with no type conversions.
bean
- Bean whose property is to be extractedname
- Possibly nested name of the property to be extracted
getProperty
public Object getProperty(Object bean,
String name)
throws IllegalAccessException,
InvocationTargetException,
NoSuchMethodException
Return the value of the specified property of the specified bean,
no matter which property reference format is used, with no
type conversions.
bean
- Bean whose property is to be extractedname
- Possibly indexed and/or nested name of the property
to be extracted
getPropertyDescriptor
public PropertyDescriptor getPropertyDescriptor(Object bean,
String name)
throws IllegalAccessException,
InvocationTargetException,
NoSuchMethodException
Retrieve the property descriptor for the specified property of the
specified bean, or return
null
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.
FIXME - Does not work with DynaBeans.
bean
- Bean for which a property descriptor is requestedname
- Possibly indexed and/or nested name of the property for
which a property descriptor is requested
getPropertyDescriptors
public PropertyDescriptor[] getPropertyDescriptors(Class beanClass)
Retrieve the property descriptors for the specified class,
introspecting and caching them the first time a particular bean class
is encountered.
FIXME - Does not work with DynaBeans.
beanClass
- Bean class for which property descriptors are requested
getPropertyDescriptors
public PropertyDescriptor[] getPropertyDescriptors(Object bean)
Retrieve the property descriptors for the specified bean,
introspecting and caching them the first time a particular bean class
is encountered.
FIXME - Does not work with DynaBeans.
bean
- Bean for which property descriptors are requested
getPropertyEditorClass
public Class getPropertyEditorClass(Object bean,
String name)
throws IllegalAccessException,
InvocationTargetException,
NoSuchMethodException
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
getPropertyDescriptor()
,
so if the last element of a name reference is indexed, the property
editor for the underlying property's class is returned.
Note that
null
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.
FIXME - Does not work with DynaBeans.
bean
- Bean for which a property descriptor is requestedname
- Possibly indexed and/or nested name of the property for
which a property descriptor is requested
getPropertyType
public Class getPropertyType(Object bean,
String name)
throws IllegalAccessException,
InvocationTargetException,
NoSuchMethodException
Return the Java Class representing the property type of the specified
property, or null
if there is no such property for the
specified bean. This method follows the same name resolution rules
used by getPropertyDescriptor()
, 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, null
is returned.
bean
- Bean for which a property descriptor is requestedname
- Possibly indexed and/or nested name of the property for
which a property descriptor is requested
getReadMethod
public Method getReadMethod(PropertyDescriptor descriptor)
Return an accessible property getter method for this property,
if there is one; otherwise return
null
.
FIXME - Does not work with DynaBeans.
descriptor
- Property descriptor to return a getter for
getSimpleProperty
public Object getSimpleProperty(Object bean,
String name)
throws IllegalAccessException,
InvocationTargetException,
NoSuchMethodException
Return the value of the specified simple property of the specified
bean, with no type conversions.
bean
- Bean whose property is to be extractedname
- Name of the property to be extracted
getWriteMethod
public Method getWriteMethod(PropertyDescriptor descriptor)
Return an accessible property setter method for this property,
if there is one; otherwise return
null
.
FIXME - Does not work with DynaBeans.
descriptor
- Property descriptor to return a setter for
invokeMethod
private Object invokeMethod(Method method,
Object bean,
Object[] values)
throws IllegalAccessException,
InvocationTargetException
This just catches and wraps IllegalArgumentException.
isReadable
public boolean isReadable(Object bean,
String name)
Return true
if the specified property name identifies
a readable property on the specified bean; otherwise, return
false
.
bean
- Bean to be examined (may be a DynaBean
name
- Property name to be evaluated
isWriteable
public boolean isWriteable(Object bean,
String name)
Return true
if the specified property name identifies
a writeable property on the specified bean; otherwise, return
false
.
bean
- Bean to be examined (may be a DynaBean
name
- Property name to be evaluated
setIndexedProperty
public void setIndexedProperty(Object bean,
String name,
Object value)
throws IllegalAccessException,
InvocationTargetException,
NoSuchMethodException
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 IllegalArgumentException
will be
thrown. In addition to supporting the JavaBeans specification, this
method has been extended to support List
objects as well.
bean
- Bean whose property is to be modifiedname
- propertyname[index]
of the property value
to be modifiedvalue
- Value to which the specified property element
should be set
setIndexedProperty
public void setIndexedProperty(Object bean,
String name,
int index,
Object value)
throws IllegalAccessException,
InvocationTargetException,
NoSuchMethodException
Set the value of the specified indexed property of the specified
bean, with no type conversions. In addition to supporting the JavaBeans
specification, this method has been extended to support
List
objects as well.
bean
- Bean whose property is to be setname
- Simple property name of the property value to be setindex
- Index of the property value to be setvalue
- Value to which the indexed property element is to be set
setMappedProperty
public void setMappedProperty(Object bean,
String name,
Object value)
throws IllegalAccessException,
InvocationTargetException,
NoSuchMethodException
Set the value of the specified mapped property of the
specified bean, with no type conversions. The key of the
value to set must be included (in brackets) as a suffix to
the property name, or IllegalArgumentException
will be
thrown.
bean
- Bean whose property is to be setname
- propertyname(key)
of the property value
to be setvalue
- The property value to be set
setMappedProperty
public void setMappedProperty(Object bean,
String name,
String key,
Object value)
throws IllegalAccessException,
InvocationTargetException,
NoSuchMethodException
Set the value of the specified mapped property of the specified
bean, with no type conversions.
bean
- Bean whose property is to be setname
- Mapped property name of the property value to be setkey
- Key of the property value to be setvalue
- The property value to be set
setNestedProperty
public void setNestedProperty(Object bean,
String name,
Object value)
throws IllegalAccessException,
InvocationTargetException,
NoSuchMethodException
Set the value of the (possibly nested) property of the specified
name, for the specified bean, with no type conversions.
bean
- Bean whose property is to be modifiedname
- Possibly nested name of the property to be modifiedvalue
- Value to which the property is to be set
setProperty
public void setProperty(Object bean,
String name,
Object value)
throws IllegalAccessException,
InvocationTargetException,
NoSuchMethodException
Set the value of the specified property of the specified bean,
no matter which property reference format is used, with no
type conversions.
bean
- Bean whose property is to be modifiedname
- Possibly indexed and/or nested name of the property
to be modifiedvalue
- Value to which this property is to be set
setSimpleProperty
public void setSimpleProperty(Object bean,
String name,
Object value)
throws IllegalAccessException,
InvocationTargetException,
NoSuchMethodException
Set the value of the specified simple property of the specified bean,
with no type conversions.
bean
- Bean whose property is to be modifiedname
- Name of the property to be modifiedvalue
- Value to which the property should be set