added web binder

This commit is contained in:
Keith Donald
2009-06-10 14:38:59 +00:00
parent 37eb0feb2b
commit be75a43c62
4 changed files with 311 additions and 14 deletions

View File

@@ -25,7 +25,7 @@ public interface Binding {
* The formatted value to display in the user interface.
*/
String getValue();
/**
* Set the property associated with this binding to the value provided.
* The value may be a formatted String, a formatted String[] if a collection binding, or an Object of a type that can be coersed to the underlying property type.
@@ -51,5 +51,6 @@ public interface Binding {
* When a collection binding, the formatted values to display in the user interface.
*/
String[] getCollectionValues();
}

View File

@@ -55,7 +55,7 @@ import org.springframework.ui.format.Formatter;
* Binds user-entered values to properties of a model object.
* @author Keith Donald
*
* @param <T> The type of model object this binder binds to
* @param <M> The type of model object this binder binds to
* @see #add(BindingConfiguration)
* @see #bind(Map)
*/
@@ -214,12 +214,7 @@ public class GenericBinder<M> implements Binder<M> {
}
public boolean isCollection() {
Class type;
try {
type = getValueType();
} catch (EvaluationException e) {
throw new IllegalArgumentException("Failed to get property expression value type - this should not happen", e);
}
Class type = getValueType();
TypeDescriptor<?> typeDesc = TypeDescriptor.valueOf(type);
return typeDesc.isCollection() || typeDesc.isArray();
}
@@ -248,7 +243,19 @@ public class GenericBinder<M> implements Binder<M> {
}
return formattedValues;
}
// public impl only
public Class getValueType() {
Class type;
try {
type = property.getValueType(createEvaluationContext());
} catch (EvaluationException e) {
throw new IllegalArgumentException("Failed to get property expression value type - this should not happen", e);
}
return type;
}
// internal helpers
private BindingResult setStringValue(String formatted) {
@@ -303,7 +310,7 @@ public class GenericBinder<M> implements Binder<M> {
if (formatter != null) {
return formatter;
} else {
Class<?> type = getValueType();
Class<?> type = property.getValueType(createEvaluationContext());
Formatter<?> formatter = typeFormatters.get(type);
if (formatter != null) {
return formatter;
@@ -320,9 +327,6 @@ public class GenericBinder<M> implements Binder<M> {
}
}
private Class<?> getValueType() throws EvaluationException {
return property.getValueType(createEvaluationContext());
}
private Annotation[] getAnnotations() throws EvaluationException {
return property.getValueTypeDescriptor(createEvaluationContext()).getAnnotations();

View File

@@ -0,0 +1,95 @@
/*
* 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.support;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import org.springframework.ui.binding.UserValue;
/**
* A binder designed for use in HTTP (web) environments.
* Suited for binding user-provided HTTP query parameters to model properties.
* @author Keith Donald
* @param <M> The type of model object this binder binds to
* @see #setFieldDefaultPrefix(String)
* @see #setFieldMarkerPrefix(String)
*/
public class WebBinder<M> extends GenericBinder<M> {
private String fieldMarkerPrefix = "_";
private String fieldDefaultPrefix = "!";
/**
* Creates a new web binder for the model object.
* @param model the model object containing properties this binder will bind to
*/
public WebBinder(M model) {
super(model);
}
/**
* Configure the prefix for determining default field values.
* Default is '!'.
*/
public void setFieldDefaultPrefix(String fieldDefaultPrefix) {
this.fieldDefaultPrefix = fieldDefaultPrefix;
}
/**
* Configure the prefix for determining empty fields.
* Default is '_'.
*/
public void setFieldMarkerPrefix(String fieldMarkerPrefix) {
this.fieldMarkerPrefix = fieldMarkerPrefix;
}
@Override
public List<UserValue> createUserValues(Map<String, ? extends Object> userMap) {
List<UserValue> values = new ArrayList<UserValue>();
for (Map.Entry<String, ? extends Object> entry : userMap.entrySet()) {
String field = entry.getKey();
Object value = entry.getValue();
if (field.startsWith(fieldDefaultPrefix)) {
field = field.substring(fieldDefaultPrefix.length());
if (!userMap.containsKey(field)) {
values.add(new UserValue(field, value));
}
} else if (field.startsWith(fieldMarkerPrefix)) {
field = field.substring(fieldMarkerPrefix.length());
if (!userMap.containsKey(field) && !userMap.containsKey(fieldDefaultPrefix + field)) {
value = getEmptyValue((BindingImpl) getBinding(field));
values.add(new UserValue(field, value));
}
} else {
values.add(new UserValue(entry.getKey(), entry.getValue()));
}
}
return values;
}
protected Object getEmptyValue(BindingImpl binding) {
Class<?> type = binding.getValueType();
if (boolean.class.equals(type) || Boolean.class.equals(type)) {
return Boolean.FALSE;
} else {
return null;
}
}
}