This commit is contained in:
Keith Donald 2009-07-23 13:55:39 +00:00
parent 14018541e2
commit a74422ed65
19 changed files with 50 additions and 173 deletions

View File

@ -18,6 +18,7 @@ package org.springframework.ui.binding;
/**
* A factory for model property bindings.
* @author Keith Donald
* @since 3.0
*/
public interface BindingFactory {

View File

@ -19,6 +19,7 @@ package org.springframework.ui.binding;
* A locator for BindingFactories indexed by their models.
* Makes it easy for clients to lookup BindingFactories for models the need to bind to.
* @author Keith Donald
* @since 3.0
*/
public interface BindingFactoryLocator {

View File

@ -18,6 +18,7 @@ package org.springframework.ui.binding;
/**
* Binding states.
* @author Keith Donald
* @since 3.0
*/
public enum BindingStatus {

View File

@ -18,6 +18,7 @@ package org.springframework.ui.binding;
/**
* Validation states.
* @author Keith Donald
* @since 3.0
*/
public enum ValidationStatus {

View File

@ -19,7 +19,6 @@ import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
class ArrayListBindingResults implements BindingResults {
private List<BindingResult> results;

View File

@ -21,6 +21,7 @@ import org.springframework.ui.binding.config.BindingRuleConfiguration;
* A SPI interface that lets you configure a model binder, then execute it.
* Hides details about the source of binder source values.
* @author Keith Donald
* @since 3.0
* @param <M> the type of model to bind to
*/
public interface BinderExecutor<M> {

View File

@ -16,14 +16,12 @@
package org.springframework.ui.binding.binder;
import org.springframework.ui.alert.Alert;
import org.springframework.ui.binding.Binding;
/**
* The result of a bind operation.
* @author Keith Donald
* @since 3.0
* @see Binder#bind(Map)
* @see Binding#setValue(Object)
* @see Binder#bind(java.util.Map)
*/
public interface BindingResult {

View File

@ -23,7 +23,7 @@ import java.util.Map;
* Indicates a client configuration error.
* @author Keith Donald
* @since 3.0
* @see Binder#bind(Map)
* @see Binder#bind(java.util.Map)
*/
@SuppressWarnings("serial")
public class MissingSourceValuesException extends RuntimeException {

View File

@ -21,6 +21,11 @@ import org.springframework.ui.binding.Binding;
import org.springframework.ui.binding.config.Condition;
import org.springframework.ui.format.Formatter;
/**
* A context that allows a Binding to query its BindingRule.
* @author Keith Donald
* @since 3.0
*/
public interface BindingContext {
MessageSource getMessageSource();
@ -33,7 +38,7 @@ public interface BindingContext {
Condition getVisibleCondition();
Binding getBinding(String property);
Binding getNestedBinding(String property);
@SuppressWarnings("unchecked")
Formatter getFormatter();

View File

@ -1,35 +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.support;
import org.springframework.ui.binding.config.Condition;
import org.springframework.ui.format.Formatter;
public interface BindingRule {
Formatter<?> getFormatter();
Formatter<?> getKeyFormatter();
Formatter<?> getElementFormatter();
Condition getEditableCondition();
Condition getEnabledCondition();
Condition getVisibleCondition();
}

View File

@ -1,44 +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.support;
import java.text.ParseException;
import java.util.Locale;
import org.springframework.ui.format.Formatter;
@SuppressWarnings("unchecked")
// TODO should this delegate to type converter...
class DefaultFormatter implements Formatter {
public static final Formatter INSTANCE = new DefaultFormatter();
public String format(Object object, Locale locale) {
if (object == null) {
return "";
} else {
return object.toString();
}
}
public Object parse(String formatted, Locale locale) throws ParseException {
if (formatted == "") {
return null;
} else {
return formatted;
}
}
}

View File

@ -22,7 +22,6 @@ import org.springframework.ui.format.Formatter;
/**
* A centralized registry of Formatters indexed by property types.
* TODO - consider moving to ui.format
* TODO - consider a general add(Formatter) method for simplicity
* @author Keith Donald
* @since 3.0
@ -51,11 +50,11 @@ public interface FormatterRegistry {
void add(Class<?> propertyType, Formatter<?> formatter);
/**
* Adds a Formatter that will format the values of properties of the provided type.
* @param propertyType the type
* Adds a Formatter that will format the values of collection properties of the provided type.
* @param type the type
* @param formatter the formatter
*/
void add(GenericCollectionPropertyType propertyType, Formatter<?> formatter);
void add(CollectionTypeDescriptor type, Formatter<?> formatter);
/**
* Adds a AnnotationFormatterFactory that will format values of properties annotated with a specific annotation.

View File

@ -288,7 +288,7 @@ public class GenericBinding implements Binding {
}
public Binding getNestedBinding(String property) {
return bindingContext.getBinding(property);
return bindingContext.getNestedBinding(property);
}
public boolean isList() {

View File

@ -226,7 +226,7 @@ public class GenericBindingFactory implements BindingFactory {
return visibleCondition;
}
public Binding getBinding(String property) {
public Binding getNestedBinding(String property) {
createValueIfNecessary();
return getBindingRule(property, binding.getValueType()).getBinding(binding.getValue());
}
@ -444,7 +444,7 @@ public class GenericBindingFactory implements BindingFactory {
return listBindingContext.getTypeConverter();
}
public Binding getBinding(String property) {
public Binding getNestedBinding(String property) {
Object model = ((List<?>) listBindingContext.binding.getValue()).get(index);
Class<?> elementType = listBindingContext.getElementType();
if (elementType == null) {
@ -523,7 +523,7 @@ public class GenericBindingFactory implements BindingFactory {
}
@SuppressWarnings("unchecked")
public Binding getBinding(String property) {
public Binding getNestedBinding(String property) {
Object model = ((Map) mapBindingContext.binding.getValue()).get(key);
Class<?> elementType = mapBindingContext.getElementType();
if (elementType == null) {

View File

@ -1,64 +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.support;
/**
* Specifies the element type of a generic collection type.
* @author Keith Donald
* @since 3.0
*/
public class GenericCollectionPropertyType {
private Class<?> collectionType;
private Class<?> elementType;
/**
* Creates a new generic collection property type
* @param collectionType the collection type
* @param elementType the element type
*/
public GenericCollectionPropertyType(Class<?> collectionType, Class<?> elementType) {
this.collectionType = collectionType;
this.elementType = elementType;
}
/**
* The collection type.
*/
public Class<?> getCollectionType() {
return collectionType;
}
/**
* The element type.
*/
public Class<?> getElementType() {
return elementType;
}
public boolean equals(Object o) {
if (!(o instanceof GenericCollectionPropertyType)) {
return false;
}
GenericCollectionPropertyType type = (GenericCollectionPropertyType) o;
return collectionType.equals(type.collectionType) && elementType.equals(type.elementType);
}
public int hashCode() {
return collectionType.hashCode() + elementType.hashCode();
}
}

View File

@ -55,16 +55,16 @@ public class GenericFormatterRegistry implements FormatterRegistry {
private Map<Class, Formatter> typeFormatters = new ConcurrentHashMap<Class, Formatter>();
private Map<GenericCollectionPropertyType, Formatter> collectionTypeFormatters = new ConcurrentHashMap<GenericCollectionPropertyType, Formatter>();
private Map<CollectionTypeDescriptor, Formatter> collectionTypeFormatters = new ConcurrentHashMap<CollectionTypeDescriptor, Formatter>();
private Map<Class, AnnotationFormatterFactory> annotationFormatters = new HashMap<Class, AnnotationFormatterFactory>();
private TypeConverter typeConverter = new DefaultTypeConverter();
public void setTypeConverter(TypeConverter typeConverter) {
this.typeConverter = typeConverter;
}
public Formatter<?> getFormatter(PropertyDescriptor property) {
Assert.notNull(property, "The PropertyDescriptor is required");
TypeDescriptor<?> propertyType = new TypeDescriptor(new MethodParameter(property.getReadMethod(), -1));
@ -78,8 +78,8 @@ public class GenericFormatterRegistry implements FormatterRegistry {
Formatter<?> formatter = null;
Class<?> type;
if (propertyType.isCollection() || propertyType.isArray()) {
GenericCollectionPropertyType collectionType = new GenericCollectionPropertyType(propertyType.getType(),
propertyType.getElementType());
CollectionTypeDescriptor collectionType = new CollectionTypeDescriptor(propertyType.getType(), propertyType
.getElementType());
formatter = collectionTypeFormatters.get(collectionType);
if (formatter != null) {
return formatter;
@ -126,7 +126,7 @@ public class GenericFormatterRegistry implements FormatterRegistry {
}
}
public void add(GenericCollectionPropertyType propertyType, Formatter<?> formatter) {
public void add(CollectionTypeDescriptor propertyType, Formatter<?> formatter) {
collectionTypeFormatters.put(propertyType, formatter);
}
@ -183,16 +183,16 @@ public class GenericFormatterRegistry implements FormatterRegistry {
private static class DefaultFormatter implements Formatter {
public static final Formatter DEFAULT_INSTANCE = new DefaultFormatter(null, null);
private Class<?> objectType;
private TypeConverter typeConverter;
public DefaultFormatter(Class<?> objectType, TypeConverter typeConverter) {
this.objectType = objectType;
this.typeConverter = typeConverter;
}
public String format(Object object, Locale locale) {
if (object == null) {
return "";
@ -221,14 +221,14 @@ public class GenericFormatterRegistry implements FormatterRegistry {
}
}
}
private static class DefaultCollectionFormatter implements Formatter {
private GenericCollectionPropertyType collectionType;
private CollectionTypeDescriptor collectionType;
private Formatter elementFormatter;
public DefaultCollectionFormatter(GenericCollectionPropertyType collectionType,
public DefaultCollectionFormatter(CollectionTypeDescriptor collectionType,
GenericFormatterRegistry formatterRegistry) {
this.collectionType = collectionType;
this.elementFormatter = collectionType.getElementType() != null ? formatterRegistry

View File

@ -15,7 +15,6 @@
*/
package org.springframework.ui.binding.support;
class ValueBuffer {
private Object value;

View File

@ -1,3 +1,18 @@
/*
* 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 org.springframework.core.convert.TypeDescriptor;

View File

@ -262,7 +262,7 @@ public class GenericBinderTests {
@Test
public void bindToListSingleString() {
GenericFormatterRegistry formatterRegistry = new GenericFormatterRegistry();
formatterRegistry.add(new GenericCollectionPropertyType(List.class, Address.class), new AddressListFormatter());
formatterRegistry.add(new CollectionTypeDescriptor(List.class, Address.class), new AddressListFormatter());
bindingFactory.setFormatterRegistry(formatterRegistry);
Map<String, String> values = new LinkedHashMap<String, String>();
values
@ -309,7 +309,7 @@ public class GenericBinderTests {
@Test
public void getListAsSingleString() {
GenericFormatterRegistry formatterRegistry = new GenericFormatterRegistry();
formatterRegistry.add(new GenericCollectionPropertyType(List.class, Address.class), new AddressListFormatter());
formatterRegistry.add(new CollectionTypeDescriptor(List.class, Address.class), new AddressListFormatter());
bindingFactory.setFormatterRegistry(formatterRegistry);
Address address1 = new Address();
address1.setStreet("s1");