com.primix.tapestry.util.prop
Class PropertyHelper

java.lang.Object
  |
  +--com.primix.tapestry.util.prop.PropertyHelper
Direct Known Subclasses:
BeanProviderHelper, ListenerMapHelper, MapHelper, PublicBeanPropertyHelper

public class PropertyHelper
extends java.lang.Object

Streamlines access to all the properties of a given JavaBean. Static methods acts as a factory for PropertyHelper instances, which are specific to a particular Bean class.

A PropertyHelper for a bean class simplifies getting and setting properties on the bean, handling (and caching) the lookup of methods as well as the dynamic invocation of those methods. It uses an instance of IPropertyAccessor for each property.

PropertyHelper allows properties to be specified in terms of a path. A path is a series of property names seperate by periods. So a property path of 'visit.user.address.street' is effectively the same as the code getVisit().getUser().getAddress().getStreet() (and just as likely to throw a NullPointerException).

Typical usage:

 ProperyHelper helper = PropertyHelper.forInstance(instance);
 helper.set(instance, "propertyName", newValue);
 

Only single-valued properties (not indexed properties) are supported, and a minimum of type checking is performed.

A mechanism exists to register custom PropertyHelper subclasses for specific classes. The two default registrations are PublicBeanPropertyHelper for the IPublicBean interface, and MapHelper for the Map interface.

Version:
$Id: PropertyHelper.java,v 1.18 2001/10/08 18:28:40 hship Exp $
Author:
Howard Ship

Field Summary
protected  java.util.Map accessors
          Map of PropertyAccessors for the helper's bean class.
protected  java.lang.Class beanClass
          The Java Beans class for which this helper is configured.
static char PATH_SEPERATOR
          The separator character used to divide up different properties in a nested property name.
 
Constructor Summary
protected PropertyHelper(java.lang.Class beanClass)
           
 
Method Summary
protected  void buildPropertyAccessors()
          Uses JavaBeans introspection to find all the properties of the bean class.
static PropertyHelper forClass(java.lang.Class beanClass)
          Factory method which returns a PropertyHelper for the given JavaBean class.
static PropertyHelper forInstance(java.lang.Object instance)
          A convienience method; simply invokes forClass(Class).
 java.lang.Object get(java.lang.Object object, java.lang.String propertyName)
          Returns the value of the named property for the given object.
 IPropertyAccessor getAccessor(java.lang.Object instance, java.lang.String propertyName)
          Finds an accessor for the given property name.
 IPropertyAccessor getAccessorPath(java.lang.Object instance, java.lang.String[] propertyPath)
          Finds an accessor using a split property path.
 java.util.Collection getAccessors(java.lang.Object instance)
          Returns a collection of IPropertyAccessor instances.
 java.lang.Object getPath(java.lang.Object object, java.lang.String propertyPath)
          Gets the value of a property from the given object.
 java.lang.Object getPath(java.lang.Object object, java.lang.String[] propertyPath)
          Gets the object, using a pre-split property path.
protected  java.util.Collection getSyntheticPropertyNames(java.lang.Object instance)
          Returns a Collection of the names of any synthetic properties.
 boolean isReadable(java.lang.Object instance, java.lang.String propertyName)
           
 boolean isWritable(java.lang.Object instance, java.lang.String propertyName)
           
static void register(java.lang.Class beanClass, java.lang.Class helperClass)
          Registers a particular PropertyHelper subclass as the correct class to use with a specific class of bean (or any class derived from the bean class).
 void set(java.lang.Object object, java.lang.String propertyName, java.lang.Object value)
          Sets the value of a property of the named object.
 void setPath(java.lang.Object object, java.lang.String[] propertyPath, java.lang.Object value)
          Changes the value of one of a bean's properties.
 void setPath(java.lang.Object object, java.lang.String propertyPath, java.lang.Object value)
          Changes the value of a some bean's property, by following a property path.
static java.lang.String[] splitPropertyPath(java.lang.String propertyPath)
          Splits a property path into an array of individual properties.
 java.lang.String toString()
           
 
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, wait, wait, wait
 

Field Detail

accessors

protected java.util.Map accessors
Map of PropertyAccessors for the helper's bean class. The keys are the names of the properties.

beanClass

protected java.lang.Class beanClass
The Java Beans class for which this helper is configured.

PATH_SEPERATOR

public static final char PATH_SEPERATOR
The separator character used to divide up different properties in a nested property name.
Constructor Detail

PropertyHelper

protected PropertyHelper(java.lang.Class beanClass)
Method Detail

buildPropertyAccessors

protected void buildPropertyAccessors()
Uses JavaBeans introspection to find all the properties of the bean class. This method sets the accessors variable (it will have been null), and adds all the well-defined JavaBeans properties.

Subclasses may invoke this method before adding thier own accessors.

This method is invoked from within a synchronized block. Subclasses do not have to worry about synchronization.


forInstance

public static PropertyHelper forInstance(java.lang.Object instance)
A convienience method; simply invokes forClass(Class).

forClass

public static PropertyHelper forClass(java.lang.Class beanClass)
Factory method which returns a PropertyHelper for the given JavaBean class.

Finding the right helper class involves a sequential lookup, first for an exact match, then for an exact match on the superclass, the a search by interface. If no specific match is found, then PropertyHelper itself is used, which is the most typical case.

See Also:
register(Class, Class)

get

public java.lang.Object get(java.lang.Object object,
                            java.lang.String propertyName)
Returns the value of the named property for the given object.

propertyName must be a simple property name, not a path, use getPath(Object,String) to use a property path.


getPath

public java.lang.Object getPath(java.lang.Object object,
                                java.lang.String propertyPath)
Gets the value of a property from the given object. Splits the propertyPath into an array of properties, and invokes getPath(Object,String[]).
Parameters:
object - The object to retrieve a property from.
propertyPath - a list of properties to get, seperated by periods

getPath

public java.lang.Object getPath(java.lang.Object object,
                                java.lang.String[] propertyPath)
Gets the object, using a pre-split property path.

getAccessor

public IPropertyAccessor getAccessor(java.lang.Object instance,
                                     java.lang.String propertyName)
Finds an accessor for the given property name. Returns the accessor if the class has the named property, or null otherwise.
Parameters:
propertyName - the simple property name of the property to get.

getAccessorPath

public IPropertyAccessor getAccessorPath(java.lang.Object instance,
                                         java.lang.String[] propertyPath)
Finds an accessor using a split property path.
Since:
1.0.5

isReadable

public boolean isReadable(java.lang.Object instance,
                          java.lang.String propertyName)

isWritable

public boolean isWritable(java.lang.Object instance,
                          java.lang.String propertyName)

register

public static void register(java.lang.Class beanClass,
                            java.lang.Class helperClass)
Registers a particular PropertyHelper subclass as the correct class to use with a specific class of bean (or any class derived from the bean class). An interface may be specified as well, in which case beans that match the interface (i.e., implement the interface directly or indirectly) will use the registered helper class.

set

public void set(java.lang.Object object,
                java.lang.String propertyName,
                java.lang.Object value)
Sets the value of a property of the named object. propertyName must be a simple propertyName, not a property path (use setPath(Object,String,Object) instead.
Parameters:
object - the object to change
propertyName - the name of the property to change
value - the value to assign to the property

setPath

public void setPath(java.lang.Object object,
                    java.lang.String propertyPath,
                    java.lang.Object value)
Changes the value of a some bean's property, by following a property path. Splits the propertyPath and invokes setPath(Object,String[],Object).

setPath

public void setPath(java.lang.Object object,
                    java.lang.String[] propertyPath,
                    java.lang.Object value)
Changes the value of one of a bean's properties. For all but the last property in the path, this works like just like getPath(Object,String[]), since the goal for those properties is to traverse to the correct object.

On the final property in the path, we update instead of reading, just like set(Object,String,Object).


toString

public java.lang.String toString()
Overrides:
toString in class java.lang.Object

splitPropertyPath

public static java.lang.String[] splitPropertyPath(java.lang.String propertyPath)
Splits a property path into an array of individual properties.
Since:
1.0.1

getAccessors

public java.util.Collection getAccessors(java.lang.Object instance)
Returns a collection of IPropertyAccessor instances.

These are generated from the "natural" JavaBeans properties. Many subclasses create "synthesized" properties, which should be added to the result and returned.

The collection returned may be modified freely. Subclasses should invoke this implementation, then add additional values as necessary.

TODO: Deal with conflicts between natural and synthesized properties.

Since:
1.0.6

getSyntheticPropertyNames

protected java.util.Collection getSyntheticPropertyNames(java.lang.Object instance)
Returns a Collection of the names of any synthetic properties.

Subclasses should override this to interrogate the instance in an appropriate way, so as to extract this list of properties. For example, MapHelper casts the instance to Map, and returns the map's keySet.

Subclasses may override this implementation without invoking it. This implementation returns null.

Since:
1.0.6