/** * Binds data to this form - that is, handles form submission. * * @param data data to submit * @return a copy of this form filled with the new data */ public Form<T> bind(Map<String, String> data, String... allowedFields) { DataBinder dataBinder = null; Map<String, String> objectData = data; if (rootName == null) { dataBinder = new DataBinder(blankInstance()); } else { dataBinder = new DataBinder(blankInstance(), rootName); objectData = new HashMap<String, String>(); for (String key : data.keySet()) { if (key.startsWith(rootName + ".")) { objectData.put(key.substring(rootName.length() + 1), data.get(key)); } } } if (allowedFields.length > 0) { dataBinder.setAllowedFields(allowedFields); } SpringValidatorAdapter validator = new SpringValidatorAdapter(play.data.validation.Validation.getValidator()); dataBinder.setValidator(validator); dataBinder.setConversionService(play.data.format.Formatters.conversion); dataBinder.setAutoGrowNestedPaths(true); dataBinder.bind(new MutablePropertyValues(objectData)); Set<ConstraintViolation<Object>> validationErrors; if (groups != null) { validationErrors = validator.validate(dataBinder.getTarget(), groups); } else { validationErrors = validator.validate(dataBinder.getTarget()); } BindingResult result = dataBinder.getBindingResult(); for (ConstraintViolation<Object> violation : validationErrors) { String field = violation.getPropertyPath().toString(); FieldError fieldError = result.getFieldError(field); if (fieldError == null || !fieldError.isBindingFailure()) { try { result.rejectValue( field, violation.getConstraintDescriptor().getAnnotation().annotationType().getSimpleName(), getArgumentsForConstraint( result.getObjectName(), field, violation.getConstraintDescriptor()), violation.getMessage()); } catch (NotReadablePropertyException ex) { throw new IllegalStateException( "JSR-303 validated property '" + field + "' does not have a corresponding accessor for data binding - " + "check your DataBinder's configuration (bean property versus direct field access)", ex); } } } if (result.hasErrors()) { Map<String, List<ValidationError>> errors = new HashMap<String, List<ValidationError>>(); for (FieldError error : result.getFieldErrors()) { String key = error.getObjectName() + "." + error.getField(); if (key.startsWith("target.") && rootName == null) { key = key.substring(7); } List<Object> arguments = new ArrayList<Object>(); for (Object arg : error.getArguments()) { if (!(arg instanceof org.springframework.context.support.DefaultMessageSourceResolvable)) { arguments.add(arg); } } if (!errors.containsKey(key)) { errors.put(key, new ArrayList<ValidationError>()); } errors .get(key) .add( new ValidationError( key, error.isBindingFailure() ? "error.invalid" : error.getDefaultMessage(), arguments)); } return new Form(rootName, backedType, data, errors, None(), groups); } else { Object globalError = null; if (result.getTarget() != null) { try { java.lang.reflect.Method v = result.getTarget().getClass().getMethod("validate"); globalError = v.invoke(result.getTarget()); } catch (NoSuchMethodException e) { } catch (Throwable e) { throw new RuntimeException(e); } } if (globalError != null) { Map<String, List<ValidationError>> errors = new HashMap<String, List<ValidationError>>(); if (globalError instanceof String) { errors.put("", new ArrayList<ValidationError>()); errors.get("").add(new ValidationError("", (String) globalError, new ArrayList())); } else if (globalError instanceof List) { errors.put("", (List<ValidationError>) globalError); } else if (globalError instanceof Map) { errors = (Map<String, List<ValidationError>>) globalError; } return new Form(rootName, backedType, data, errors, None(), groups); } return new Form( rootName, backedType, new HashMap<String, String>(data), new HashMap<String, List<ValidationError>>(errors), Some((T) result.getTarget()), groups); } }