net.sourceforge.stripes.controller
Class DefaultActionBeanPropertyBinder

java.lang.Object
  extended by net.sourceforge.stripes.controller.DefaultActionBeanPropertyBinder
All Implemented Interfaces:
ConfigurableComponent, ActionBeanPropertyBinder

public class DefaultActionBeanPropertyBinder
extends Object
implements ActionBeanPropertyBinder

Implementation of the ActionBeanPropertyBinder interface that uses Stripes' built in property expression support to perform JavaBean property binding. Several additions/enhancements are available above and beyond the standard JavaBean syntax. These include:

Since:
Stripes 1.4
Author:
Tim Fennell

Nested Class Summary
protected static class DefaultActionBeanPropertyBinder.Row
          An inner class that represents a "row" of form properties that all have the same index so that we can validate all those properties together.
 
Constructor Summary
DefaultActionBeanPropertyBinder()
           
 
Method Summary
 ValidationErrors bind(ActionBean bean, ActionBeanContext context, boolean validate)
           Loops through the parameters contained in the request and attempts to bind each one to the supplied ActionBean.
 void bind(ActionBean bean, String propertyName, Object propertyValue)
          Attempt to set the named property on the target bean.
protected  void bindMissingValuesAsNull(ActionBean bean, ActionBeanContext context)
          Uses a hidden field to determine what (if any) fields were present in the form but did not get submitted to the server.
protected  void bindNonNullValue(ActionBean bean, PropertyExpressionEvaluation propertyEvaluation, List<Object> valueOrValues, Class targetType, Class scalarType)
          Internal helper method to bind one or more values to a single property on an ActionBean.
protected  void bindNullValue(ActionBean bean, String property, Class<?> type)
          Internal helper method that determines what to do when no value was supplied for a given form field (but the field was present on the page).
protected  void checkSingleRequiredField(String name, String strippedName, String[] values, StripesRequestWrapper req, ValidationErrors errors)
           Checks to see if a single field's set of values are 'present', where that is defined as having one or more values, and where each value is a non-empty String after it has had white space trimmed from each end.
protected  List<Object> convert(ActionBean bean, ParameterName propertyName, String[] values, Class<?> declaredType, Class<?> scalarType, ValidationMetadata validationInfo, List<ValidationError> errors)
           Converts the String[] of values for a given parameter in the HttpServletRequest into the desired type of Object.
protected  void doExpressionValidation(ActionBean bean, ParameterName name, List<Object> values, ValidationMetadata validationInfo, ValidationErrors errors)
          Performs validation of attribute values using a JSP EL expression if one is defined in the @Validate annotation.
protected  void doPostConversionValidations(ActionBean bean, Map<ParameterName,List<Object>> convertedValues, ValidationErrors errors)
          Performs basic post-conversion validations on the properties of the ActionBean after they have been converted to their rich type by the type conversion system.
protected  void doPreConversionValidations(ParameterName propertyName, String[] values, ValidationMetadata validationInfo, List<ValidationError> errors)
          Performs several basic validations on the String value supplied in the HttpServletRequest, based on information provided in annotations on the ActionBean.
protected  Configuration getConfiguration()
          Returns the Configuration object that was passed to the init() method.
protected  Collection<String> getFieldsPresentInfo(ActionBean bean)
          In a lot of cases (and specifically during wizards) the Stripes form field writes out a hidden field containing a set of field names.
protected  SortedMap<ParameterName,String[]> getParameters(ActionBean bean)
          Converts the map of parameters in the request into a Map of ParameterName to String[].
protected  void handlePropertyBindingError(ActionBean bean, ParameterName name, List<Object> values, Exception e, ValidationErrors errors)
          Invoked whenever an exception is thrown when attempting to bind a property to an ActionBean.
 void init(Configuration configuration)
          Looks up and caches in a useful form the metadata necessary to perform validations as properties are bound to the bean.
protected  boolean isBindingAllowed(PropertyExpressionEvaluation eval)
           Checks to see if binding is permitted for the provided expression evaluation.
protected  String[] trim(String[] values, ValidationMetadata meta)
          Inspects the given ValidationMetadata object to determine if the given values should be trimmed.
protected  void validateRequiredFields(Map<ParameterName,String[]> parameters, ActionBean bean, ValidationErrors errors)
          Validates that all required fields have been submitted.
 
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
 

Constructor Detail

DefaultActionBeanPropertyBinder

public DefaultActionBeanPropertyBinder()
Method Detail

init

public void init(Configuration configuration)
          throws Exception
Looks up and caches in a useful form the metadata necessary to perform validations as properties are bound to the bean.

Specified by:
init in interface ConfigurableComponent
Parameters:
configuration - the Configuration object being used by Stripes
Throws:
Exception - should be thrown if the component cannot be configured well enough to use.

getConfiguration

protected Configuration getConfiguration()
Returns the Configuration object that was passed to the init() method.


bind

public ValidationErrors bind(ActionBean bean,
                             ActionBeanContext context,
                             boolean validate)

Loops through the parameters contained in the request and attempts to bind each one to the supplied ActionBean. Invokes validation for each of the properties on the bean before binding is attempted. Only fields which do not produce validation errors will be bound to the ActionBean.

Individual property binding is delegated to the other interface method, bind(ActionBean, String, Object), in order to allow for easy extension of this class.

Specified by:
bind in interface ActionBeanPropertyBinder
Parameters:
bean - the ActionBean whose properties are to be validated and bound
context - the ActionBeanContext of the current request
validate - true indicates that validation should be run, false indicates that only type conversion should occur

isBindingAllowed

protected boolean isBindingAllowed(PropertyExpressionEvaluation eval)

Checks to see if binding is permitted for the provided expression evaluation. Note that the expression is available through the getExpression() and the ActionBean is available through the getBean() method on the evaluation.

By default checks to ensure that the expression is not attempting to bind into the ActionBeanContext for security reasons.

Parameters:
eval - the expression evaluation to check for binding permission
Returns:
true if binding can/should proceed, false to veto binding

handlePropertyBindingError

protected void handlePropertyBindingError(ActionBean bean,
                                          ParameterName name,
                                          List<Object> values,
                                          Exception e,
                                          ValidationErrors errors)
Invoked whenever an exception is thrown when attempting to bind a property to an ActionBean. By default logs some information about the occurrence, but could be overridden to do more intelligent things based on the application.

Parameters:
bean - the ActionBean that was the subject of binding
name - the ParameterName object for the parameter being bound
values - the list of values being bound, potentially null if the error occurred when binding a null value
e - the exception raised during binding
errors - the validation errors object associated to the ActionBean

bindMissingValuesAsNull

protected void bindMissingValuesAsNull(ActionBean bean,
                                       ActionBeanContext context)
Uses a hidden field to determine what (if any) fields were present in the form but did not get submitted to the server. For each such field the value is "softly" set to null on the ActionBean. This is not uncommon for checkboxes, and also for multi-selects.

Parameters:
bean - the ActionBean being bound to
context - the current ActionBeanContext

getFieldsPresentInfo

protected Collection<String> getFieldsPresentInfo(ActionBean bean)
In a lot of cases (and specifically during wizards) the Stripes form field writes out a hidden field containing a set of field names. This is encrypted to stop the user from monkeying with it. This method retrieves the list of field names, decrypts it and splits it out into a Collection of field names.

Parameters:
bean - the current ActionBean
Returns:
a non-null (though possibly empty) list of field names

bindNonNullValue

protected void bindNonNullValue(ActionBean bean,
                                PropertyExpressionEvaluation propertyEvaluation,
                                List<Object> valueOrValues,
                                Class targetType,
                                Class scalarType)
                         throws Exception
Internal helper method to bind one or more values to a single property on an ActionBean. If the target type is an array of Collection, then all values are bound. If the target type is a scalar type then the first value in the List of values is bound.

Parameters:
bean - the ActionBean instance to which the property is being bound
propertyEvaluation - the property evaluation to be used to set the property
valueOrValues - a List containing one or more values
targetType - the declared type of the property on the ActionBean
Throws:
Exception - if the property cannot be bound for any reason

bindNullValue

protected void bindNullValue(ActionBean bean,
                             String property,
                             Class<?> type)
                      throws ExpressionException
Internal helper method that determines what to do when no value was supplied for a given form field (but the field was present on the page). In all cases if the property is already null, or intervening objects in a nested property are null, nothing is done. If the property is non-null, it will be set to null. Unless the property is a collection, in which case it will be clear()'d.

Parameters:
bean - the ActionBean to which properties are being bound
property - the name of the property being bound
type - the declared type of the property on the ActionBean
Throws:
ExpressionException - if the value cannot be manipulated for any reason

getParameters

protected SortedMap<ParameterName,String[]> getParameters(ActionBean bean)
Converts the map of parameters in the request into a Map of ParameterName to String[]. Returns a SortedMap so that when iterated over parameter names are accessed in order of length of parameter name.


bind

public void bind(ActionBean bean,
                 String propertyName,
                 Object propertyValue)
          throws Exception
Attempt to set the named property on the target bean. If the binding fails for any reason (property does not exist, type conversion not possible etc.) an exception will be thrown.

Specified by:
bind in interface ActionBeanPropertyBinder
Parameters:
bean - the ActionBean on to which the property is to be bound
propertyName - the name of the property to be bound (simple or complex)
propertyValue - the value of the target property
Throws:
Exception - thrown if the property cannot be bound for any reason

validateRequiredFields

protected void validateRequiredFields(Map<ParameterName,String[]> parameters,
                                      ActionBean bean,
                                      ValidationErrors errors)
Validates that all required fields have been submitted. This is done by looping through the set of validation annotations and checking that each field marked as required was submitted in the request and submitted with a non-empty value.


checkSingleRequiredField

protected void checkSingleRequiredField(String name,
                                        String strippedName,
                                        String[] values,
                                        StripesRequestWrapper req,
                                        ValidationErrors errors)

Checks to see if a single field's set of values are 'present', where that is defined as having one or more values, and where each value is a non-empty String after it has had white space trimmed from each end.

For any fields that fail validation, creates a ScopedLocaliableError that uses the stripped name of the field to find localized info (e.g. foo.bar instead of foo[1].bar). The error is bound to the actual field on the form though, e.g. foo[1].bar.

Parameters:
name - the name of the parameter verbatim from the request
strippedName - the name of the parameter with any indexing removed from it
values - the String[] of values that was submitted in the request
errors - a ValidationErrors object into which errors can be placed

doPreConversionValidations

protected void doPreConversionValidations(ParameterName propertyName,
                                          String[] values,
                                          ValidationMetadata validationInfo,
                                          List<ValidationError> errors)
Performs several basic validations on the String value supplied in the HttpServletRequest, based on information provided in annotations on the ActionBean.

Parameters:
propertyName - the name of the property being validated (used for constructing errors)
values - the String[] of values from the request being validated
validationInfo - the ValidationMetadata for the property being validated
errors - a collection of errors to be populated with any validation errors discovered

doPostConversionValidations

protected void doPostConversionValidations(ActionBean bean,
                                           Map<ParameterName,List<Object>> convertedValues,
                                           ValidationErrors errors)
Performs basic post-conversion validations on the properties of the ActionBean after they have been converted to their rich type by the type conversion system. Validates single properties in isolation from other properties.

Parameters:
bean - the ActionBean that is undergoing validation and binding
convertedValues - a map of ParameterName to all converted values for each field
errors - the validation errors object to put errors in to

doExpressionValidation

protected void doExpressionValidation(ActionBean bean,
                                      ParameterName name,
                                      List<Object> values,
                                      ValidationMetadata validationInfo,
                                      ValidationErrors errors)
Performs validation of attribute values using a JSP EL expression if one is defined in the @Validate annotation. The expression is evaluated once for each value converted. See ExpressionValidator for details on how this is implemented.

Parameters:
bean - the ActionBean who's property is being validated
name - the name of the property being validated
values - the non-null post-conversion values for the property
validationInfo - the validation metadata for the property
errors - the validation errors object to add errors to

convert

protected List<Object> convert(ActionBean bean,
                               ParameterName propertyName,
                               String[] values,
                               Class<?> declaredType,
                               Class<?> scalarType,
                               ValidationMetadata validationInfo,
                               List<ValidationError> errors)
                        throws Exception

Converts the String[] of values for a given parameter in the HttpServletRequest into the desired type of Object. If a converter is declared using an annotation for the property (or getter/setter) then that converter will be used - if it does not convert to the right type an exception will be logged and values will not be converted. If no Converter was specified then a default converter will be looked up based on the target type of the property. If there is no default converter, then a Constructor will be looked for on the target type which takes a single String parameter. If such a Constructor exists it will be invoked.

Only parameter values that are non-null and do not equal the empty String will be converted and returned. So an input array with one entry equaling the empty string, [""], will result in an empty List being returned. Similarly, if a length three array is passed in with one item equaling the empty String, a List of length two will be returned.

Parameters:
bean - the ActionBean on which the property to convert exists
propertyName - the name of the property being converted
values - a String array of values to attempt conversion of
declaredType - the declared type of the ActionBean property
scalarType - if the declaredType is a collection, map or array then this will be the type contained within the collection/map value/array, otherwise the same as declaredType
validationInfo - the validation metadata for the property if defined
errors - a List into which ValidationError objects will be populated for any errors discovered during conversion.
Returns:
List a List of objects containing only objects of the desired type. It is not guaranteed to be the same length as the values array passed in.
Throws:
Exception

trim

protected String[] trim(String[] values,
                        ValidationMetadata meta)
Inspects the given ValidationMetadata object to determine if the given values should be trimmed. If so, then the trimmed values are returned. Otherwise, the values are returned unchanged. If meta is null, then the default action is taken, and the values are trimmed. Either values or meta (or both) may be null.



? Copyright 2005-2006, Stripes Development Team.