net.sourceforge.stripes.util.bean
Class PropertyExpressionEvaluation

java.lang.Object
  extended by net.sourceforge.stripes.util.bean.PropertyExpressionEvaluation

public class PropertyExpressionEvaluation
extends Object

The dynamic partner to a PropertyExpression that represents the evaluation of the expression against a particular bean or starting object. When constructed the evaluation will examine type information on the bean and nested properties to create a chain of type information for the expression. The evaluation can then be used (repeatedly) to determine the type of the expression, retrieve it's value and set it's value - all against the supplied object.

Since:
Stripes 1.4
Author:
Tim Fennell

Constructor Summary
PropertyExpressionEvaluation(PropertyExpression expression, Object bean)
          Constructs a new PropertyExpressionEvaluation for the expression and bean supplied.
 
Method Summary
protected  Class<?> convertToClass(Type type, NodeEvaluation evaluation)
          Attempts to convert the Type object into a Class object.
 Object getBean()
          Fetches the bean which was supplied as the starting point for evaluation in the constructor to this evaluation.
protected  Type getBeanPropertyType(Class<?> beanClass, String property)
          Fetches the type of a property with the given name on the Class of the specified type.
 PropertyExpression getExpression()
          Fetches the expression of which this is an evaluation.
 NodeEvaluation getRootNode()
          Fetches the root (first) node in the evaluation, which can be used to traverse through the nodes in series.
 Class<?> getScalarType()
          Returns a scalar type appropriate to the expression evaluation.
 Class<?> getType()
          Fetches the type of value that can be get/set with this expression evaluation.
protected  Type getTypeVariableValue(NodeEvaluation evaluation, TypeVariable<?> typeVar)
          Scans backwards in the expression for the last node which contained a JavaBean type and attempts to use the type arguments to that class to find a match for the TypeParameter provided.
protected  Type getTypeViaInstances(NodeEvaluation end)
          Determines the type of the supplied node and sets appropriate information on the node.
 Object getValue()
          Fetches the value of this expression evaluated against the bean.
protected  Type getWildcardTypeBound(WildcardType wtype)
          Gets the preferred bound from the WildcardType provided.
 void setToNull()
          Sets the value of this expression to "null" for the bean.
 void setValue(Object propertyValue)
          Sets the value of the expression evaluated against the bean.
protected  Method untangleBridgeMethod(Method m)
          Deprecated. This method is no longer used. Bridge methods are handled transparently by ReflectUtil.getPropertyDescriptors(Class).
protected  void validateTypeInformation()
          Ensures no violations exist in the expression in the context of this evaluation.
 
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
 

Constructor Detail

PropertyExpressionEvaluation

public PropertyExpressionEvaluation(PropertyExpression expression,
                                    Object bean)
Constructs a new PropertyExpressionEvaluation for the expression and bean supplied. Loops through the expression creating NodeEvaluation objects corresponding to each node in the expression and then fills in type information so that it is accessible to all further calls.

Parameters:
expression - a PropertyExpression
bean - a non-null bean against which to evaluate the expression
Method Detail

getBean

public Object getBean()
Fetches the bean which was supplied as the starting point for evaluation in the constructor to this evaluation.

Returns:
the bean from which evaluation starts

getRootNode

public NodeEvaluation getRootNode()
Fetches the root (first) node in the evaluation, which can be used to traverse through the nodes in series.

Returns:
the root node in the evaluation

getExpression

public PropertyExpression getExpression()
Fetches the expression of which this is an evaluation.

Returns:
the expression being evaluated

validateTypeInformation

protected void validateTypeInformation()
Ensures no violations exist in the expression in the context of this evaluation. Currently, this ensures that no attempt is made to access a bean property via a bracket expression. Such an expression could be used to circumvent validations that use dot notation for the same property. See STS-841 for more information.


getBeanPropertyType

protected Type getBeanPropertyType(Class<?> beanClass,
                                   String property)
Fetches the type of a property with the given name on the Class of the specified type. Uses the methods first to fetch the generic type if a PropertyDescriptor can be found, otherwise looks for a public field and returns its generic type.

Parameters:
beanClass - the class of the JavaBean containing the property
property - the name of the property
Returns:
the Type if it can be determined, or null otherwise

untangleBridgeMethod

@Deprecated
protected Method untangleBridgeMethod(Method m)
Deprecated. This method is no longer used. Bridge methods are handled transparently by ReflectUtil.getPropertyDescriptors(Class).

Locates and returns a non-bridge method for the method supplied. In certain cases the Introspector will return PropertyDescriptors that contain bridge methods for read and write methods. This usually results from classes implementing generic interfaces that contain accessor method specifications with type parameters. Since the bridge methods have inappropriate/unhelpful return and parameter types it is necessary to locate the non-bridge method and use that instead.

When supplied with a non-bridge method, the method parameter passed in is returned immediately and no other work is performed.

Parameters:
m - a Method instance, potentially a bridge method
Returns:
a non-bridge method instance if one is locatable, otherwise the method passed in

getTypeViaInstances

protected Type getTypeViaInstances(NodeEvaluation end)
                            throws EvaluationException,
                                   NoSuchPropertyException

Determines the type of the supplied node and sets appropriate information on the node. The type is discovered by fetching (and instantiating if necessary) all prior values in the expression to determine the actual type of the prior node. The prior node is then examined to determine the type of the node provided.

After this method executes either 1) all necessary type information will be set on the node and the appropriate type object returned or 2) an exception will be thrown.

Parameters:
end - the node to instantiate up to and determine the type of
Returns:
the Type of the node if possible
Throws:
NoSuchPropertyException - if the previous node is a JavaBean (i.e. non-collection) node and does not contain a property with the corresponding name
EvaluationException - if the previous node is a List or Map and does not contain enough information to determine the type

convertToClass

protected Class<?> convertToClass(Type type,
                                  NodeEvaluation evaluation)
Attempts to convert the Type object into a Class object. Currently will extract the raw type from a ParameterizedType and the appropriate bound from a WildcardType. If the result after these operations is a Class object it will be cast and returned. Otherwise will return null.

Parameters:
type - the Type object to try and render as a Class
Returns:
the Class if one can be determined, otherwise null

getTypeVariableValue

protected Type getTypeVariableValue(NodeEvaluation evaluation,
                                    TypeVariable<?> typeVar)
Scans backwards in the expression for the last node which contained a JavaBean type and attempts to use the type arguments to that class to find a match for the TypeParameter provided. On it's way also collects information from any parameterized types and their super-types.

Parameters:
evaluation - the current NodeEvaluation
typeVar - the TypeVariable to try and find a more concrete type for
Returns:
the actual type argument for the type variable if possible, or null

getWildcardTypeBound

protected Type getWildcardTypeBound(WildcardType wtype)
Gets the preferred bound from the WildcardType provided. In the case of '? super SomeClass' then 'SomeClass' will be returned. In the case of '? extends AnotherClass' then 'AnotherClass' will be returned.

Parameters:
wtype - the WildcardType to fetch the bounds of
Returns:
the appropriate bound type

getType

public Class<?> getType()
Fetches the type of value that can be get/set with this expression evaluation. This is equivalent (though more efficient) to calling getValue().getClass(). If the type information on this expression is not complete then null will be returned.

Returns:
the Class of object that can be set/get with this evaluation or null

getScalarType

public Class<?> getScalarType()
Returns a scalar type appropriate to the expression evaluation. When getType() returns a scalar type then this method will return the identical class. However, when getType() returns an Array, a Collection or a Map this method will attempt to determine the type of element stored in that Array/Collection/Map and return that Class. If getType() returns null due to insufficient type information this method will also return null. Similarly if the type of item in the Array/Collection/May cannot be determined then String.class will be returned.

Returns:
The scalar type to which values should be converted in order to either be set using this expression or set into the Array/Collection/Map should this expression point at a non scalar property

getValue

public Object getValue()

Fetches the value of this expression evaluated against the bean. This is equivalent to calling the appropriate get() methods in sequence in order to fetch the property indicated by the expression.

If the property or any intermediate property in the expression is null this method will return null and will not alter the state of the object graph.

Returns:
the value stored on the bean for this expression/property

setValue

public void setValue(Object propertyValue)
              throws EvaluationException

Sets the value of the expression evaluated against the bean. This is loosely equivalent to calling the appropriate getter() on intermediate properties and then calling the appropriate setter on the final sub-property.

During set operations null intermediate nodes will be instantiated and linked into the object graph in order to persistently set the desired property. When this is not possible (e.g. because of a lack of default constructors) an exception will be thrown.

Parameters:
propertyValue - the value to be set for the property of the bean
Throws:
EvaluationException - if intermediate null properties cannot be instantiated

setToNull

public void setToNull()
               throws EvaluationException

Sets the value of this expression to "null" for the bean. In reality this is not always null, but the logical interpretation of "null" for a given type. For primitives the value is set to be the default value for the primitive type as used by the JVM when initializing instance variables. For Map entries the key is removed from the Map instead of leaving the key present with a null value.

If any intermediate properties in the expression are null this method will return immediately. The sole purpose of this method is to blank out a value if one is present. Therefore if no value is present, nothing will be changed.

Throws:
EvaluationException - if any exceptions are thrown during the process of nulling out


© Copyright 2005-2006, Stripes Development Team.