Keith Donald
16 years ago
4 changed files with 311 additions and 14 deletions
@ -0,0 +1,95 @@
@@ -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; |
||||
} |
||||
} |
||||
|
||||
} |
@ -0,0 +1,197 @@
@@ -0,0 +1,197 @@
|
||||
package org.springframework.ui.binding.support; |
||||
|
||||
import static org.junit.Assert.assertEquals; |
||||
|
||||
import java.math.BigDecimal; |
||||
import java.text.ParseException; |
||||
import java.util.Date; |
||||
import java.util.LinkedHashMap; |
||||
import java.util.List; |
||||
import java.util.Locale; |
||||
import java.util.Map; |
||||
|
||||
import org.junit.After; |
||||
import org.junit.Before; |
||||
import org.junit.Test; |
||||
import org.springframework.context.i18n.LocaleContextHolder; |
||||
import org.springframework.ui.binding.Binder; |
||||
import org.springframework.ui.binding.BindingConfiguration; |
||||
import org.springframework.ui.binding.BindingResult; |
||||
import org.springframework.ui.binding.UserValue; |
||||
import org.springframework.ui.format.date.DateFormatter; |
||||
import org.springframework.ui.format.number.CurrencyAnnotationFormatterFactory; |
||||
import org.springframework.ui.format.number.CurrencyFormat; |
||||
|
||||
public class WebBinderTests { |
||||
|
||||
@Before |
||||
public void setUp() { |
||||
LocaleContextHolder.setLocale(Locale.US); |
||||
} |
||||
|
||||
@After |
||||
public void tearDown() { |
||||
LocaleContextHolder.setLocale(null); |
||||
} |
||||
|
||||
@Test |
||||
public void bindUserValuesCreatedFromUserMap() throws ParseException { |
||||
Binder<TestBean> binder = new WebBinder<TestBean>(new TestBean()); |
||||
binder.add(new CurrencyAnnotationFormatterFactory()); |
||||
binder.add(new BindingConfiguration("date", new DateFormatter())); |
||||
Map<String, String> userMap = new LinkedHashMap<String, String>(); |
||||
userMap.put("string", "test"); |
||||
userMap.put("_integer", "doesn't matter"); |
||||
userMap.put("_bool", "doesn't matter"); |
||||
userMap.put("!date", "2009-06-10"); |
||||
userMap.put("!currency", "$5.00"); |
||||
userMap.put("_currency", "doesn't matter"); |
||||
userMap.put("_addresses", "doesn't matter"); |
||||
List<UserValue> values = binder.createUserValues(userMap); |
||||
List<BindingResult> results = binder.bind(values); |
||||
assertEquals(6, results.size()); |
||||
assertEquals("test", results.get(0).getUserValue()); |
||||
assertEquals(null, results.get(1).getUserValue()); |
||||
assertEquals(Boolean.FALSE, results.get(2).getUserValue()); |
||||
assertEquals("2009-06-10", results.get(3).getUserValue()); |
||||
assertEquals("$5.00", results.get(4).getUserValue()); |
||||
assertEquals(null, results.get(5).getUserValue()); |
||||
|
||||
assertEquals("test", binder.getModel().getString()); |
||||
assertEquals(0, binder.getModel().getInteger()); |
||||
assertEquals(new DateFormatter().parse("2009-06-10", Locale.US), binder.getModel().getDate()); |
||||
assertEquals(false, binder.getModel().isBool()); |
||||
assertEquals(new BigDecimal("5.00"), binder.getModel().getCurrency()); |
||||
assertEquals(null, binder.getModel().getAddresses()); |
||||
} |
||||
|
||||
public static enum FooEnum { |
||||
BAR, BAZ, BOOP; |
||||
} |
||||
|
||||
public static class TestBean { |
||||
private String string; |
||||
private int integer; |
||||
private boolean bool; |
||||
private Date date; |
||||
private FooEnum foo; |
||||
private BigDecimal currency; |
||||
private List<FooEnum> foos; |
||||
private List<Address> addresses; |
||||
|
||||
public String getString() { |
||||
return string; |
||||
} |
||||
|
||||
public void setString(String string) { |
||||
this.string = string; |
||||
} |
||||
|
||||
public int getInteger() { |
||||
return integer; |
||||
} |
||||
|
||||
public void setInteger(int integer) { |
||||
this.integer = integer; |
||||
} |
||||
|
||||
public boolean isBool() { |
||||
return bool; |
||||
} |
||||
|
||||
public void setBool(boolean bool) { |
||||
this.bool = bool; |
||||
} |
||||
|
||||
public Date getDate() { |
||||
return date; |
||||
} |
||||
|
||||
public void setDate(Date date) { |
||||
this.date = date; |
||||
} |
||||
|
||||
public FooEnum getFoo() { |
||||
return foo; |
||||
} |
||||
|
||||
public void setFoo(FooEnum foo) { |
||||
this.foo = foo; |
||||
} |
||||
|
||||
@CurrencyFormat |
||||
public BigDecimal getCurrency() { |
||||
return currency; |
||||
} |
||||
|
||||
public void setCurrency(BigDecimal currency) { |
||||
this.currency = currency; |
||||
} |
||||
|
||||
public List<FooEnum> getFoos() { |
||||
return foos; |
||||
} |
||||
|
||||
public void setFoos(List<FooEnum> foos) { |
||||
this.foos = foos; |
||||
} |
||||
|
||||
public List<Address> getAddresses() { |
||||
return addresses; |
||||
} |
||||
|
||||
public void setAddresses(List<Address> addresses) { |
||||
this.addresses = addresses; |
||||
} |
||||
|
||||
} |
||||
|
||||
public static class Address { |
||||
private String street; |
||||
private String city; |
||||
private String state; |
||||
private String zip; |
||||
private String country; |
||||
|
||||
public String getStreet() { |
||||
return street; |
||||
} |
||||
|
||||
public void setStreet(String street) { |
||||
this.street = street; |
||||
} |
||||
|
||||
public String getCity() { |
||||
return city; |
||||
} |
||||
|
||||
public void setCity(String city) { |
||||
this.city = city; |
||||
} |
||||
|
||||
public String getState() { |
||||
return state; |
||||
} |
||||
|
||||
public void setState(String state) { |
||||
this.state = state; |
||||
} |
||||
|
||||
public String getZip() { |
||||
return zip; |
||||
} |
||||
|
||||
public void setZip(String zip) { |
||||
this.zip = zip; |
||||
} |
||||
|
||||
public String getCountry() { |
||||
return country; |
||||
} |
||||
|
||||
public void setCountry(String country) { |
||||
this.country = country; |
||||
} |
||||
|
||||
} |
||||
} |
Loading…
Reference in new issue