intermediate commit - wip bind and validate lifecycle
This commit is contained in:
parent
f05df17037
commit
97e7dfb398
|
|
@ -17,47 +17,81 @@ package org.springframework.ui;
|
||||||
|
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
|
import org.springframework.ui.binding.BindingResult;
|
||||||
import org.springframework.ui.binding.BindingResults;
|
import org.springframework.ui.binding.BindingResults;
|
||||||
import org.springframework.ui.binding.UserValues;
|
import org.springframework.ui.binding.UserValues;
|
||||||
import org.springframework.ui.binding.support.WebBinder;
|
import org.springframework.ui.binding.support.WebBinder;
|
||||||
|
import org.springframework.ui.message.MessageBuilder;
|
||||||
import org.springframework.ui.message.MessageContext;
|
import org.springframework.ui.message.MessageContext;
|
||||||
import org.springframework.ui.validation.ValidateResults;
|
import org.springframework.ui.validation.ValidationResults;
|
||||||
import org.springframework.ui.validation.Validator;
|
import org.springframework.ui.validation.Validator;
|
||||||
|
|
||||||
/**
|
|
||||||
* TODO Document WebBindAndValidateLifecycle.
|
|
||||||
*
|
|
||||||
* @author Keith Donald
|
|
||||||
* @since 3.0
|
|
||||||
*/
|
|
||||||
public class WebBindAndValidateLifecycle {
|
public class WebBindAndValidateLifecycle {
|
||||||
|
|
||||||
private final WebBinder binder;
|
private final WebBinder binder;
|
||||||
|
|
||||||
|
@SuppressWarnings("unused")
|
||||||
private final MessageContext messageContext;
|
private final MessageContext messageContext;
|
||||||
|
|
||||||
private ValidationDecider validationDecider = ValidationDecider.ALWAYS_VALIDATE;
|
private ValidationDecider validationDecider = ValidationDecider.ALWAYS_VALIDATE;
|
||||||
|
|
||||||
private Validator validator = null;
|
private Validator validator;
|
||||||
|
|
||||||
public WebBindAndValidateLifecycle(Object model, MessageContext messageContext) {
|
public WebBindAndValidateLifecycle(Object model, MessageContext messageContext) {
|
||||||
this.binder = new WebBinder(model);
|
this.binder = new WebBinder(model);
|
||||||
this.messageContext = messageContext;
|
this.messageContext = messageContext;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* TODO Document execute().
|
|
||||||
*
|
|
||||||
* @param userMap
|
|
||||||
*/
|
|
||||||
public void execute(Map<String, ? extends Object> userMap) {
|
public void execute(Map<String, ? extends Object> userMap) {
|
||||||
UserValues values = binder.createUserValues(userMap);
|
UserValues values = binder.createUserValues(userMap);
|
||||||
BindingResults bindingResults = binder.bind(values);
|
BindingResults bindingResults = binder.bind(values);
|
||||||
if (validationDecider.shouldValidateAfter(bindingResults)) {
|
if (validationDecider.shouldValidateAfter(bindingResults)) {
|
||||||
ValidateResults validationResults = validator.validate(binder.getModel(), bindingResults.successes()
|
ValidationResults validationResults = validator.validate(binder.getModel(), bindingResults.successes()
|
||||||
.properties());
|
.properties());
|
||||||
}
|
}
|
||||||
// TODO translate binding and validation results into messages
|
// TODO translate binding and validation results into messages
|
||||||
|
MessageBuilder builder = new MessageBuilder();
|
||||||
|
for (BindingResult result : bindingResults.failures()) {
|
||||||
|
builder.
|
||||||
|
code(modelPropertyError(result)).
|
||||||
|
code(propertyError(result)).
|
||||||
|
code(typeError(result)).
|
||||||
|
code(error(result)).
|
||||||
|
//argContextFactory(createContextFactory(bindingResult)).
|
||||||
|
// TODO arg names
|
||||||
|
// TODO el support including ability to setup evaluation context
|
||||||
|
//resolvableArg("label", getModelProperty(result)).
|
||||||
|
//arg("value", result.getUserValue()).
|
||||||
|
//arg("binding", binder.getBinding(result.getProperty())).
|
||||||
|
//args(result.getErrorArguments()).
|
||||||
|
build();
|
||||||
|
}
|
||||||
|
// TODO expose property Binding in EL context for property error message resolution?
|
||||||
|
}
|
||||||
|
|
||||||
|
private String modelPropertyError(BindingResult result) {
|
||||||
|
return getModelProperty(result) + "." + result.getErrorCode();
|
||||||
|
}
|
||||||
|
|
||||||
|
private String propertyError(BindingResult result) {
|
||||||
|
return result.getProperty() + "." + result.getErrorCode();
|
||||||
|
}
|
||||||
|
|
||||||
|
private String typeError(BindingResult result) {
|
||||||
|
return binder.getBinding(result.getProperty()).getType().getName() + "." + result.getErrorCode();
|
||||||
|
}
|
||||||
|
|
||||||
|
private String error(BindingResult result) {
|
||||||
|
return result.getErrorCode();
|
||||||
|
}
|
||||||
|
|
||||||
|
private String getModelProperty(BindingResult result) {
|
||||||
|
return getModel() + "." + result.getProperty();
|
||||||
|
}
|
||||||
|
|
||||||
|
private String getModel() {
|
||||||
|
// TODO would be nice if model name was module.ClassName by default where module is subpackage of app base package
|
||||||
|
return binder.getModel().getClass().getName();
|
||||||
}
|
}
|
||||||
|
|
||||||
interface ValidationDecider {
|
interface ValidationDecider {
|
||||||
|
|
|
||||||
|
|
@ -52,5 +52,10 @@ public interface Binding {
|
||||||
*/
|
*/
|
||||||
String[] getCollectionValues();
|
String[] getCollectionValues();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The type of the underlying property associated with this binding.
|
||||||
|
*/
|
||||||
|
Class<?>getType();
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
@ -259,7 +259,7 @@ public class GenericBinder implements Binder {
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isCollection() {
|
public boolean isCollection() {
|
||||||
Class type = getValueType();
|
Class type = getType();
|
||||||
TypeDescriptor<?> typeDesc = TypeDescriptor.valueOf(type);
|
TypeDescriptor<?> typeDesc = TypeDescriptor.valueOf(type);
|
||||||
return typeDesc.isCollection() || typeDesc.isArray();
|
return typeDesc.isCollection() || typeDesc.isArray();
|
||||||
}
|
}
|
||||||
|
|
@ -291,8 +291,8 @@ public class GenericBinder implements Binder {
|
||||||
|
|
||||||
// public impl only
|
// public impl only
|
||||||
|
|
||||||
public Class getValueType() {
|
public Class<?> getType() {
|
||||||
Class type;
|
Class<?> type;
|
||||||
try {
|
try {
|
||||||
type = property.getValueType(createEvaluationContext());
|
type = property.getValueType(createEvaluationContext());
|
||||||
} catch (EvaluationException e) {
|
} catch (EvaluationException e) {
|
||||||
|
|
|
||||||
|
|
@ -84,7 +84,7 @@ public class WebBinder extends GenericBinder {
|
||||||
}
|
}
|
||||||
|
|
||||||
protected Object getEmptyValue(BindingImpl binding) {
|
protected Object getEmptyValue(BindingImpl binding) {
|
||||||
Class<?> type = binding.getValueType();
|
Class<?> type = binding.getType();
|
||||||
if (boolean.class.equals(type) || Boolean.class.equals(type)) {
|
if (boolean.class.equals(type) || Boolean.class.equals(type)) {
|
||||||
return Boolean.FALSE;
|
return Boolean.FALSE;
|
||||||
} else {
|
} else {
|
||||||
|
|
|
||||||
|
|
@ -22,6 +22,6 @@ package org.springframework.ui.validation;
|
||||||
* @author Keith Donald
|
* @author Keith Donald
|
||||||
* @since 3.0
|
* @since 3.0
|
||||||
*/
|
*/
|
||||||
public interface ValidateResults {
|
public interface ValidationResults {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
@ -33,6 +33,6 @@ public interface Validator {
|
||||||
* @param properties
|
* @param properties
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
ValidateResults validate(Object model, List<String> properties);
|
ValidationResults validate(Object model, List<String> properties);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue