removed user values in favor of simple map after code review
This commit is contained in:
@@ -24,7 +24,6 @@ import org.springframework.ui.format.Formatter;
|
||||
* Binds user-entered values to properties of a model object.
|
||||
* @author Keith Donald
|
||||
* @since 3.0
|
||||
* @param <M> The kind of model object this binder binds to
|
||||
* @see #configureBinding(BindingConfiguration)
|
||||
* @see #bind(UserValues)
|
||||
*/
|
||||
@@ -35,7 +34,7 @@ public interface Binder {
|
||||
* @return the model object
|
||||
*/
|
||||
Object getModel();
|
||||
|
||||
|
||||
/**
|
||||
* Configures if this binder is <i>strict</i>; a strict binder requires all bindings to be registered explicitly using {@link #configureBinding(BindingConfiguration)}.
|
||||
* An <i>optimistic</i> binder will implicitly create bindings as required to support {@link #bind(UserValues)} operations.
|
||||
@@ -64,6 +63,13 @@ public interface Binder {
|
||||
*/
|
||||
void registerFormatterFactory(AnnotationFormatterFactory<?, ?> factory);
|
||||
|
||||
/**
|
||||
* Configures the registry of Formatters to query when no explicit Formatter has been registered for a Binding.
|
||||
* Allows Formatters to be applied by property type and by property annotation.
|
||||
* @param registry the formatter registry
|
||||
*/
|
||||
void setFormatterRegistry(FormatterRegistry registry);
|
||||
|
||||
/**
|
||||
* Returns the binding for the property.
|
||||
* @param property the property path
|
||||
@@ -72,20 +78,10 @@ public interface Binder {
|
||||
Binding getBinding(String property);
|
||||
|
||||
/**
|
||||
* Bind values in the map to the properties of the model object.
|
||||
* @param values user-entered values to bind
|
||||
* Bind source values in the map to the properties of the model object.
|
||||
* @param values the source values to bind
|
||||
* @return the results of the binding operation
|
||||
*/
|
||||
BindingResults bind(UserValues values);
|
||||
|
||||
/**
|
||||
* Creates a {@link UserValue} list from a Map of user-submitted fields.
|
||||
* The Binder may apply transformations as part of the creation process.
|
||||
* For example, a Binder might insert empty or default values for fields that are not present.
|
||||
* As another example, a Binder might collapse multiple fields into a single {@link UserValue} object.
|
||||
* @param userMap the map of user-submitted fields
|
||||
* @return the UserValue list that can be passed to {@link #bind(UserValues)}.
|
||||
*/
|
||||
UserValues createUserValues(Map<String, ? extends Object> userMap);
|
||||
BindingResults bind(Map<String, ? extends Object> sourceValues);
|
||||
|
||||
}
|
||||
@@ -56,7 +56,7 @@ public interface Binding {
|
||||
/**
|
||||
* The type of the underlying property associated with this binding.
|
||||
*/
|
||||
Class<?>getType();
|
||||
Class<?> getType();
|
||||
|
||||
|
||||
}
|
||||
@@ -48,7 +48,7 @@ public class BindingConfiguration {
|
||||
}
|
||||
|
||||
/**
|
||||
* THe Formatter to use to format bound property values.
|
||||
* The Formatter to use to format bound property values.
|
||||
*/
|
||||
public Formatter<?> getFormatter() {
|
||||
return formatter;
|
||||
|
||||
@@ -32,11 +32,11 @@ public interface BindingResult {
|
||||
String getProperty();
|
||||
|
||||
/**
|
||||
* The raw user-entered value for which binding was attempted.
|
||||
* The raw source value for which binding was attempted.
|
||||
* If not a failure, this value was successfully bound to the model.
|
||||
* @see #isFailure()
|
||||
*/
|
||||
Object getUserValue();
|
||||
Object getSourceValue();
|
||||
|
||||
/**
|
||||
* Indicates if the binding failed.
|
||||
|
||||
@@ -1,54 +0,0 @@
|
||||
/*
|
||||
* Copyright 2004-2009 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.ui.binding;
|
||||
|
||||
/**
|
||||
* Holds a user-entered value to bind to a model property.
|
||||
* @author Keith Donald
|
||||
* @since 3.0
|
||||
* @see Binder#bind(List)
|
||||
*/
|
||||
public class UserValue {
|
||||
|
||||
private String property;
|
||||
|
||||
private Object value;
|
||||
|
||||
/**
|
||||
* Create a new user value
|
||||
* @param property the property associated with the value
|
||||
* @param value the actual user-entered value
|
||||
*/
|
||||
public UserValue(String property, Object value) {
|
||||
this.property = property;
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
/**
|
||||
* The property the user-entered value should bind to.
|
||||
*/
|
||||
public String getProperty() {
|
||||
return property;
|
||||
}
|
||||
|
||||
/**
|
||||
* The actual user-entered value.
|
||||
*/
|
||||
public Object getValue() {
|
||||
return value;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,90 +0,0 @@
|
||||
/*
|
||||
* Copyright 2004-2009 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.ui.binding;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* A holder for a list of UserValues.
|
||||
* TODO just use a map here
|
||||
* @author Keith Donald
|
||||
* @since 3.0
|
||||
* @see Binder#bind(UserValues)
|
||||
*/
|
||||
public class UserValues implements Iterable<UserValue> {
|
||||
|
||||
private List<UserValue> values;
|
||||
|
||||
/**
|
||||
* Creates a new user values list of the default size.
|
||||
*/
|
||||
public UserValues() {
|
||||
values = new ArrayList<UserValue>();
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new user values list of the size provided.
|
||||
*/
|
||||
public UserValues(int size) {
|
||||
values = new ArrayList<UserValue>(size);
|
||||
}
|
||||
|
||||
// implementing Iterable
|
||||
|
||||
public Iterator<UserValue> iterator() {
|
||||
return values.iterator();
|
||||
}
|
||||
|
||||
/**
|
||||
* The user values list.
|
||||
* The returned list is not modifiable.
|
||||
*/
|
||||
public List<UserValue> asList() {
|
||||
return Collections.unmodifiableList(values);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a new user value.
|
||||
* @param property the property the value should be bound to
|
||||
* @param value the actual user-entered value
|
||||
*/
|
||||
public void add(String property, Object value) {
|
||||
values.add(new UserValue(property, value));
|
||||
}
|
||||
|
||||
/**
|
||||
* The number of user values in the list.
|
||||
*/
|
||||
public int size() {
|
||||
return values.size();
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new UserValues list with a single element.
|
||||
* @param property the property
|
||||
* @param value the actual user-entered value
|
||||
* @return the singleton user value list
|
||||
*/
|
||||
public static UserValues single(String property, Object value) {
|
||||
UserValues values = new UserValues(1);
|
||||
values.add(property, value);
|
||||
return values;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -56,15 +56,13 @@ import org.springframework.ui.binding.BindingConfiguration;
|
||||
import org.springframework.ui.binding.BindingResult;
|
||||
import org.springframework.ui.binding.BindingResults;
|
||||
import org.springframework.ui.binding.FormatterRegistry;
|
||||
import org.springframework.ui.binding.UserValue;
|
||||
import org.springframework.ui.binding.UserValues;
|
||||
import org.springframework.ui.format.AnnotationFormatterFactory;
|
||||
import org.springframework.ui.format.Formatter;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
/**
|
||||
* A generic {@link Binder binder} suitable for use in most environments.
|
||||
* TODO - localization of alert messages using MessageResolver/MesageSource
|
||||
* TODO - localization of alert messages using MessageResolver/MessageSource
|
||||
* @author Keith Donald
|
||||
* @since 3.0
|
||||
* @see #configureBinding(BindingConfiguration)
|
||||
@@ -94,7 +92,7 @@ public class GenericBinder implements Binder {
|
||||
* @param model the model object containing properties this binder will bind to
|
||||
*/
|
||||
public GenericBinder(Object model) {
|
||||
Assert.notNull(model, "The model Object is reqyured");
|
||||
Assert.notNull(model, "The model Object is required");
|
||||
this.model = model;
|
||||
bindings = new HashMap<String, Binding>();
|
||||
int parserConfig = SpelExpressionParserConfiguration.CreateListsOnAttemptToIndexIntoNull
|
||||
@@ -148,25 +146,31 @@ public class GenericBinder implements Binder {
|
||||
}
|
||||
}
|
||||
|
||||
public BindingResults bind(UserValues values) {
|
||||
ArrayListBindingResults results = new ArrayListBindingResults(values.size());
|
||||
for (UserValue value : values) {
|
||||
BindingImpl binding = (BindingImpl) getBinding(value.getProperty());
|
||||
public BindingResults bind(Map<String, ? extends Object> sourceValues) {
|
||||
sourceValues = filter(sourceValues);
|
||||
ArrayListBindingResults results = new ArrayListBindingResults(sourceValues.size());
|
||||
for (Map.Entry<String, ? extends Object> sourceValue : sourceValues.entrySet()) {
|
||||
String property = sourceValue.getKey();
|
||||
Object value = sourceValue.getValue();
|
||||
BindingImpl binding = (BindingImpl) getBinding(property);
|
||||
if (binding != null) {
|
||||
results.add(binding.setValue(value.getValue()));
|
||||
results.add(binding.setValue(value));
|
||||
} else {
|
||||
results.add(new NoSuchBindingResult(value));
|
||||
results.add(new NoSuchBindingResult(property, value));
|
||||
}
|
||||
}
|
||||
}
|
||||
return results;
|
||||
}
|
||||
|
||||
public UserValues createUserValues(Map<String, ? extends Object> userMap) {
|
||||
UserValues values = new UserValues(userMap.size());
|
||||
for (Map.Entry<String, ? extends Object> entry : userMap.entrySet()) {
|
||||
values.add(entry.getKey(), entry.getValue());
|
||||
}
|
||||
return values;
|
||||
|
||||
// subclassing hooks
|
||||
|
||||
/**
|
||||
* Hook subclasses may use to filter the source values to bind.
|
||||
* @param sourceValues the original source values map provided by the caller
|
||||
* @return the filtered source values map that will be used to bind
|
||||
*/
|
||||
protected Map<String, ? extends Object> filter(Map<String, ? extends Object> sourceValues) {
|
||||
return sourceValues;
|
||||
}
|
||||
|
||||
// internal helpers
|
||||
@@ -458,18 +462,21 @@ public class GenericBinder implements Binder {
|
||||
}
|
||||
|
||||
static class NoSuchBindingResult implements BindingResult {
|
||||
private UserValue userValue;
|
||||
private String property;
|
||||
|
||||
public NoSuchBindingResult(UserValue userValue) {
|
||||
this.userValue = userValue;
|
||||
private Object sourceValue;
|
||||
|
||||
public NoSuchBindingResult(String property, Object sourceValue) {
|
||||
this.property = property;
|
||||
this.sourceValue = sourceValue;
|
||||
}
|
||||
|
||||
public String getProperty() {
|
||||
return userValue.getProperty();
|
||||
return property;
|
||||
}
|
||||
|
||||
public Object getUserValue() {
|
||||
return userValue.getValue();
|
||||
public Object getSourceValue() {
|
||||
return sourceValue;
|
||||
}
|
||||
|
||||
public boolean isFailure() {
|
||||
@@ -492,7 +499,7 @@ public class GenericBinder implements Binder {
|
||||
}
|
||||
|
||||
public String getMessage() {
|
||||
return "Failed to bind to property '" + userValue.getProperty() + "'; no binding has been added for the property";
|
||||
return "Failed to bind to property '" + property + "'; no binding has been added for the property";
|
||||
}
|
||||
};
|
||||
}
|
||||
@@ -513,7 +520,7 @@ public class GenericBinder implements Binder {
|
||||
return property;
|
||||
}
|
||||
|
||||
public Object getUserValue() {
|
||||
public Object getSourceValue() {
|
||||
return formatted;
|
||||
}
|
||||
|
||||
@@ -563,7 +570,7 @@ public class GenericBinder implements Binder {
|
||||
return property;
|
||||
}
|
||||
|
||||
public Object getUserValue() {
|
||||
public Object getSourceValue() {
|
||||
return formatted;
|
||||
}
|
||||
|
||||
@@ -651,7 +658,7 @@ public class GenericBinder implements Binder {
|
||||
return property;
|
||||
}
|
||||
|
||||
public Object getUserValue() {
|
||||
public Object getSourceValue() {
|
||||
return formatted;
|
||||
}
|
||||
|
||||
|
||||
@@ -15,11 +15,9 @@
|
||||
*/
|
||||
package org.springframework.ui.binding.support;
|
||||
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import org.springframework.ui.binding.UserValue;
|
||||
import org.springframework.ui.binding.UserValues;
|
||||
|
||||
/**
|
||||
* A binder designed for use in HTTP (web) environments.
|
||||
* Suited for binding user-provided HTTP query parameters to model properties.
|
||||
@@ -61,27 +59,27 @@ public class WebBinder extends GenericBinder {
|
||||
}
|
||||
|
||||
@Override
|
||||
public UserValues createUserValues(Map<String, ? extends Object> userMap) {
|
||||
UserValues values = new UserValues();
|
||||
for (Map.Entry<String, ? extends Object> entry : userMap.entrySet()) {
|
||||
protected Map<String, ? extends Object> filter(Map<String, ? extends Object> sourceValues) {
|
||||
LinkedHashMap<String, Object> filteredValues = new LinkedHashMap<String, Object>();
|
||||
for (Map.Entry<String, ? extends Object> entry : sourceValues.entrySet()) {
|
||||
String field = entry.getKey();
|
||||
Object value = entry.getValue();
|
||||
if (field.startsWith(defaultPrefix)) {
|
||||
field = field.substring(defaultPrefix.length());
|
||||
if (!userMap.containsKey(field)) {
|
||||
values.add(field, value);
|
||||
if (!sourceValues.containsKey(field)) {
|
||||
filteredValues.put(field, value);
|
||||
}
|
||||
} else if (field.startsWith(presentPrefix)) {
|
||||
field = field.substring(presentPrefix.length());
|
||||
if (!userMap.containsKey(field) && !userMap.containsKey(defaultPrefix + field)) {
|
||||
if (!sourceValues.containsKey(field) && !sourceValues.containsKey(defaultPrefix + field)) {
|
||||
value = getEmptyValue((BindingImpl) getBinding(field));
|
||||
values.add(field, value);
|
||||
filteredValues.put(field, value);
|
||||
}
|
||||
} else {
|
||||
values.add(entry.getKey(), entry.getValue());
|
||||
filteredValues.put(entry.getKey(), entry.getValue());
|
||||
}
|
||||
}
|
||||
return values;
|
||||
return filteredValues;
|
||||
}
|
||||
|
||||
protected Object getEmptyValue(BindingImpl binding) {
|
||||
|
||||
@@ -30,7 +30,6 @@ import org.springframework.ui.binding.BindingResults;
|
||||
import org.springframework.ui.binding.Bound;
|
||||
import org.springframework.ui.binding.FormatterRegistry;
|
||||
import org.springframework.ui.binding.Model;
|
||||
import org.springframework.ui.binding.UserValues;
|
||||
import org.springframework.ui.binding.support.WebBinder;
|
||||
import org.springframework.ui.validation.Validator;
|
||||
import org.springframework.util.StringUtils;
|
||||
@@ -62,8 +61,7 @@ public class WebBindAndValidateLifecycle {
|
||||
}
|
||||
|
||||
public void execute(Map<String, ? extends Object> userMap) {
|
||||
UserValues values = binder.createUserValues(userMap);
|
||||
BindingResults bindingResults = binder.bind(values);
|
||||
BindingResults bindingResults = binder.bind(userMap);
|
||||
if (validator != null && validationDecider.shouldValidateAfter(bindingResults)) {
|
||||
// TODO get validation results
|
||||
validator.validate(binder.getModel(), bindingResults.successes().properties());
|
||||
|
||||
Reference in New Issue
Block a user