* @param context the ActionBeanContext of the current request
* @param validate true indicates that validation should be run, false indicates that only type
* conversion should occur
*/
public ValidationErrors bind(ActionBean bean, ActionBeanContext context, boolean validate) {
ValidationErrors fieldErrors = context.getValidationErrors();
Map<String, ValidationMetadata> validationInfos = this.configuration
.getValidationMetadataProvider().getValidationMetadata(bean.getClass());
// Take the ParameterMap and turn the keys into ParameterNames
Map<ParameterName, String[]> parameters = getParameters(bean);
// Run the required validation first to catch fields that weren't even submitted
if (validate) {
validateRequiredFields(parameters, bean, fieldErrors);
}
// Converted values for all fields are accumulated in this map to make post-conversion
// validation go a little easier
Map<ParameterName, List<Object>> allConvertedFields = new TreeMap<ParameterName, List<Object>>();
// First we bind all the regular parameters
for (Map.Entry<ParameterName, String[]> entry : parameters.entrySet()) {
List<Object> convertedValues = null;
ParameterName name = entry.getKey();
try {
String pname = name.getName(); // exact name of the param in the request
if (!StripesConstants.SPECIAL_URL_KEYS.contains(pname)
&& !fieldErrors.containsKey(pname)) {
log.trace("Running binding for property with name: ", name);
// Determine the target type
ValidationMetadata validationInfo = validationInfos.get(name.getStrippedName());
PropertyExpressionEvaluation eval;
try {
eval = new PropertyExpressionEvaluation(PropertyExpression
.getExpression(pname), bean);
}
catch (Exception e) {
if (pname.equals(context.getEventName()))
continue;
else
throw e;
}
Class<?> type = eval.getType();
Class<?> scalarType = eval.getScalarType();
// Check to see if binding into this expression is permitted
if (!isBindingAllowed(eval))
continue;
if (type == null
&& (validationInfo == null || validationInfo.converter() == null)) {
if (!pname.equals(context.getEventName())) {
log.trace("Could not find type for property '", name.getName(),
"' of '", bean.getClass().getSimpleName(),
"' probably because it's not ",
"a property of the bean. Skipping binding.");
}
continue;
}
String[] values = entry.getValue();
// Do Validation and type conversion
List<ValidationError> errors = new ArrayList<ValidationError>();
// If the property should be ignored, skip to the next property
if (validationInfo != null && validationInfo.ignore()) {
continue;
}
if (validate && validationInfo != null) {
doPreConversionValidations(name, values, validationInfo, errors);
}
// Only do type conversion if there aren't errors already
if (errors.isEmpty()) {
convertedValues = convert(bean, name, values, type, scalarType, validationInfo, errors);
allConvertedFields.put(name, convertedValues);
}
// If we have errors, save them, otherwise bind the parameter to the form
if (errors.size() > 0) {
fieldErrors.addAll(name.getName(), errors);
}
else if (convertedValues.size() > 0) {
bindNonNullValue(bean, eval, convertedValues, type, scalarType);
}
else {