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. * A factory for model property bindings.
* @author Keith Donald * @author Keith Donald
* @since 3.0
*/ */
public interface BindingFactory { public interface BindingFactory {

View File

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

View File

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

View File

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

View File

@ -19,7 +19,6 @@ import java.util.ArrayList;
import java.util.Iterator; import java.util.Iterator;
import java.util.List; import java.util.List;
class ArrayListBindingResults implements BindingResults { class ArrayListBindingResults implements BindingResults {
private List<BindingResult> results; 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. * A SPI interface that lets you configure a model binder, then execute it.
* Hides details about the source of binder source values. * Hides details about the source of binder source values.
* @author Keith Donald * @author Keith Donald
* @since 3.0
* @param <M> the type of model to bind to * @param <M> the type of model to bind to
*/ */
public interface BinderExecutor<M> { public interface BinderExecutor<M> {

View File

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

View File

@ -23,7 +23,7 @@ import java.util.Map;
* Indicates a client configuration error. * Indicates a client configuration error.
* @author Keith Donald * @author Keith Donald
* @since 3.0 * @since 3.0
* @see Binder#bind(Map) * @see Binder#bind(java.util.Map)
*/ */
@SuppressWarnings("serial") @SuppressWarnings("serial")
public class MissingSourceValuesException extends RuntimeException { 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.binding.config.Condition;
import org.springframework.ui.format.Formatter; 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 { public interface BindingContext {
MessageSource getMessageSource(); MessageSource getMessageSource();
@ -33,7 +38,7 @@ public interface BindingContext {
Condition getVisibleCondition(); Condition getVisibleCondition();
Binding getBinding(String property); Binding getNestedBinding(String property);
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
Formatter getFormatter(); 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. * A centralized registry of Formatters indexed by property types.
* TODO - consider moving to ui.format
* TODO - consider a general add(Formatter) method for simplicity * TODO - consider a general add(Formatter) method for simplicity
* @author Keith Donald * @author Keith Donald
* @since 3.0 * @since 3.0
@ -51,11 +50,11 @@ public interface FormatterRegistry {
void add(Class<?> propertyType, Formatter<?> formatter); void add(Class<?> propertyType, Formatter<?> formatter);
/** /**
* Adds a Formatter that will format the values of properties of the provided type. * Adds a Formatter that will format the values of collection properties of the provided type.
* @param propertyType the type * @param type the type
* @param formatter the formatter * @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. * 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) { public Binding getNestedBinding(String property) {
return bindingContext.getBinding(property); return bindingContext.getNestedBinding(property);
} }
public boolean isList() { public boolean isList() {

View File

@ -226,7 +226,7 @@ public class GenericBindingFactory implements BindingFactory {
return visibleCondition; return visibleCondition;
} }
public Binding getBinding(String property) { public Binding getNestedBinding(String property) {
createValueIfNecessary(); createValueIfNecessary();
return getBindingRule(property, binding.getValueType()).getBinding(binding.getValue()); return getBindingRule(property, binding.getValueType()).getBinding(binding.getValue());
} }
@ -444,7 +444,7 @@ public class GenericBindingFactory implements BindingFactory {
return listBindingContext.getTypeConverter(); return listBindingContext.getTypeConverter();
} }
public Binding getBinding(String property) { public Binding getNestedBinding(String property) {
Object model = ((List<?>) listBindingContext.binding.getValue()).get(index); Object model = ((List<?>) listBindingContext.binding.getValue()).get(index);
Class<?> elementType = listBindingContext.getElementType(); Class<?> elementType = listBindingContext.getElementType();
if (elementType == null) { if (elementType == null) {
@ -523,7 +523,7 @@ public class GenericBindingFactory implements BindingFactory {
} }
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
public Binding getBinding(String property) { public Binding getNestedBinding(String property) {
Object model = ((Map) mapBindingContext.binding.getValue()).get(key); Object model = ((Map) mapBindingContext.binding.getValue()).get(key);
Class<?> elementType = mapBindingContext.getElementType(); Class<?> elementType = mapBindingContext.getElementType();
if (elementType == null) { 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,7 +55,7 @@ public class GenericFormatterRegistry implements FormatterRegistry {
private Map<Class, Formatter> typeFormatters = new ConcurrentHashMap<Class, Formatter>(); 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 Map<Class, AnnotationFormatterFactory> annotationFormatters = new HashMap<Class, AnnotationFormatterFactory>();
@ -78,8 +78,8 @@ public class GenericFormatterRegistry implements FormatterRegistry {
Formatter<?> formatter = null; Formatter<?> formatter = null;
Class<?> type; Class<?> type;
if (propertyType.isCollection() || propertyType.isArray()) { if (propertyType.isCollection() || propertyType.isArray()) {
GenericCollectionPropertyType collectionType = new GenericCollectionPropertyType(propertyType.getType(), CollectionTypeDescriptor collectionType = new CollectionTypeDescriptor(propertyType.getType(), propertyType
propertyType.getElementType()); .getElementType());
formatter = collectionTypeFormatters.get(collectionType); formatter = collectionTypeFormatters.get(collectionType);
if (formatter != null) { if (formatter != null) {
return formatter; 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); collectionTypeFormatters.put(propertyType, formatter);
} }
@ -224,11 +224,11 @@ public class GenericFormatterRegistry implements FormatterRegistry {
private static class DefaultCollectionFormatter implements Formatter { private static class DefaultCollectionFormatter implements Formatter {
private GenericCollectionPropertyType collectionType; private CollectionTypeDescriptor collectionType;
private Formatter elementFormatter; private Formatter elementFormatter;
public DefaultCollectionFormatter(GenericCollectionPropertyType collectionType, public DefaultCollectionFormatter(CollectionTypeDescriptor collectionType,
GenericFormatterRegistry formatterRegistry) { GenericFormatterRegistry formatterRegistry) {
this.collectionType = collectionType; this.collectionType = collectionType;
this.elementFormatter = collectionType.getElementType() != null ? formatterRegistry this.elementFormatter = collectionType.getElementType() != null ? formatterRegistry

View File

@ -15,7 +15,6 @@
*/ */
package org.springframework.ui.binding.support; package org.springframework.ui.binding.support;
class ValueBuffer { class ValueBuffer {
private Object value; 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; package org.springframework.ui.binding.support;
import org.springframework.core.convert.TypeDescriptor; import org.springframework.core.convert.TypeDescriptor;

View File

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