binding factory locator

This commit is contained in:
Keith Donald 2009-07-23 13:31:06 +00:00
parent a3b57e2a84
commit 29768cb068
9 changed files with 104 additions and 7 deletions

View File

@ -19,7 +19,7 @@ import org.springframework.ui.alert.Alert;
import org.springframework.ui.alert.Severity; import org.springframework.ui.alert.Severity;
/** /**
* A binding between a source element and a model property. * A binding between one or more UI components and a model property.
* @author Keith Donald * @author Keith Donald
* @since 3.0 * @since 3.0
*/ */
@ -138,12 +138,12 @@ public interface Binding {
Binding getNestedBinding(String property); Binding getNestedBinding(String property);
/** /**
* If bound to an indexable Collection, either a {@link java.util.List} or an array. * If bound to an indexable collection, either a {@link java.util.List} or an array.
*/ */
boolean isList(); boolean isList();
/** /**
* If a List, get a Binding to a element in the List. * If a list, get a Binding to a element in the list..
* @param index the element index * @param index the element index
* @return the indexed binding * @return the indexed binding
* @throws IllegalStateException if not a list * @throws IllegalStateException if not a list
@ -151,7 +151,7 @@ public interface Binding {
Binding getListElementBinding(int index); Binding getListElementBinding(int index);
/** /**
* If bound to a {@link java.util.Map}. * If bound to a Map.
*/ */
boolean isMap(); boolean isMap();

View File

@ -0,0 +1,33 @@
/*
* 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;
/**
* 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
*/
public interface BindingFactoryLocator {
/**
* Get the BindingFactory for the model object.
* If no such BindingFactory exists, one is created and cached.
* Never returns <code>null</code>.
* @param model the model object
* @return the binding Factory
*/
public BindingFactory getBindingFactory(Object model);
}

View File

@ -35,10 +35,13 @@ public interface BindingContext {
Binding getBinding(String property); Binding getBinding(String property);
@SuppressWarnings("unchecked")
Formatter getFormatter(); Formatter getFormatter();
@SuppressWarnings("unchecked")
Formatter getElementFormatter(); Formatter getElementFormatter();
@SuppressWarnings("unchecked")
Formatter getKeyFormatter(); Formatter getKeyFormatter();
Binding getListElementBinding(int index); Binding getListElementBinding(int index);

View File

@ -92,6 +92,7 @@ public class GenericBinding implements Binding {
return bindingContext.getVisibleCondition().isTrue(); return bindingContext.getVisibleCondition().isTrue();
} }
@SuppressWarnings("unchecked")
public void applySourceValue(Object sourceValue) { public void applySourceValue(Object sourceValue) {
assertEditable(); assertEditable();
assertEnabled(); assertEnabled();
@ -119,7 +120,6 @@ public class GenericBinding implements Binding {
Map map = new LinkedHashMap(sourceValues.length); Map map = new LinkedHashMap(sourceValues.length);
for (int i = 0; i < sourceValues.length; i++) { for (int i = 0; i < sourceValues.length; i++) {
String entryString = sourceValues[i]; String entryString = sourceValues[i];
Object parsedValue;
try { try {
String[] keyValue = entryString.split("="); String[] keyValue = entryString.split("=");
Object parsedMapKey = keyFormatter.parse(keyValue[0], getLocale()); Object parsedMapKey = keyFormatter.parse(keyValue[0], getLocale());
@ -327,6 +327,7 @@ public class GenericBinding implements Binding {
// internal helpers // internal helpers
@SuppressWarnings("unchecked")
private String format(Object value, Formatter formatter) { private String format(Object value, Formatter formatter) {
Class<?> formattedType = getFormattedObjectType(formatter.getClass()); Class<?> formattedType = getFormattedObjectType(formatter.getClass());
value = bindingContext.getTypeConverter().convert(value, formattedType); value = bindingContext.getTypeConverter().convert(value, formattedType);
@ -337,6 +338,7 @@ public class GenericBinding implements Binding {
return LocaleContextHolder.getLocale(); return LocaleContextHolder.getLocale();
} }
@SuppressWarnings("unchecked")
private Class getFormattedObjectType(Class formatterClass) { private Class getFormattedObjectType(Class formatterClass) {
Class classToIntrospect = formatterClass; Class classToIntrospect = formatterClass;
while (classToIntrospect != null) { while (classToIntrospect != null) {
@ -365,6 +367,7 @@ public class GenericBinding implements Binding {
return null; return null;
} }
@SuppressWarnings("unchecked")
private Object coerseToValueType(Object parsed) { private Object coerseToValueType(Object parsed) {
TypeDescriptor targetType = valueModel.getValueTypeDescriptor(); TypeDescriptor targetType = valueModel.getValueTypeDescriptor();
TypeConverter converter = bindingContext.getTypeConverter(); TypeConverter converter = bindingContext.getTypeConverter();

View File

@ -25,7 +25,6 @@ import java.util.LinkedHashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import org.codehaus.groovy.binding.PropertyBinding;
import org.springframework.context.MessageSource; import org.springframework.context.MessageSource;
import org.springframework.core.GenericCollectionTypeResolver; import org.springframework.core.GenericCollectionTypeResolver;
import org.springframework.core.convert.TypeConverter; import org.springframework.core.convert.TypeConverter;
@ -446,7 +445,7 @@ public class GenericBindingFactory implements BindingFactory {
} }
public Binding getBinding(String property) { public Binding getBinding(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) {
elementType = model.getClass(); elementType = model.getClass();
@ -461,14 +460,17 @@ public class GenericBindingFactory implements BindingFactory {
return binding; return binding;
} }
@SuppressWarnings("unchecked")
public Formatter getFormatter() { public Formatter getFormatter() {
return listBindingContext.getElementFormatter(); return listBindingContext.getElementFormatter();
} }
@SuppressWarnings("unchecked")
public Formatter getElementFormatter() { public Formatter getElementFormatter() {
return null; return null;
} }
@SuppressWarnings("unchecked")
public Formatter getKeyFormatter() { public Formatter getKeyFormatter() {
return null; return null;
} }
@ -520,6 +522,7 @@ public class GenericBindingFactory implements BindingFactory {
return mapBindingContext.getTypeConverter(); return mapBindingContext.getTypeConverter();
} }
@SuppressWarnings("unchecked")
public Binding getBinding(String property) { public Binding getBinding(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();
@ -536,14 +539,17 @@ public class GenericBindingFactory implements BindingFactory {
return binding; return binding;
} }
@SuppressWarnings("unchecked")
public Formatter getFormatter() { public Formatter getFormatter() {
return mapBindingContext.getElementFormatter(); return mapBindingContext.getElementFormatter();
} }
@SuppressWarnings("unchecked")
public Formatter getElementFormatter() { public Formatter getElementFormatter() {
return null; return null;
} }
@SuppressWarnings("unchecked")
public Formatter getKeyFormatter() { public Formatter getKeyFormatter() {
return null; return null;
} }

View File

@ -0,0 +1,45 @@
/*
* 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.IdentityHashMap;
import java.util.Map;
import org.springframework.ui.binding.BindingFactory;
import org.springframework.ui.binding.BindingFactoryLocator;
/**
* BindingFactoryLocator implementation that uses a {@link IdentityHashMap} to map models to BindingFactories.
* @author Keith Donald
*/
public class GenericBindingFactoryLocator implements BindingFactoryLocator {
private Map<Object, BindingFactory> bindingFactories = new IdentityHashMap<Object, BindingFactory>();
public void put(BindingFactory bindingFactory) {
bindingFactories.put(bindingFactory.getModel(), bindingFactory);
}
public BindingFactory getBindingFactory(Object model) {
BindingFactory factory = bindingFactories.get(model);
if (factory == null) {
factory = new GenericBindingFactory(model);
bindingFactories.put(model, factory);
}
return factory;
}
}

View File

@ -21,12 +21,14 @@ import org.springframework.core.convert.TypeDescriptor;
class ListElementValueModel implements ValueModel { class ListElementValueModel implements ValueModel {
@SuppressWarnings("unchecked")
private List list; private List list;
private int index; private int index;
private Class<?> elementType; private Class<?> elementType;
@SuppressWarnings("unchecked")
public ListElementValueModel(int index, Class<?> elementType, List list) { public ListElementValueModel(int index, Class<?> elementType, List list) {
this.index = index; this.index = index;
this.elementType = elementType; this.elementType = elementType;
@ -53,6 +55,7 @@ class ListElementValueModel implements ValueModel {
return true; return true;
} }
@SuppressWarnings("unchecked")
public void setValue(Object value) { public void setValue(Object value) {
list.set(index, value); list.set(index, value);
} }

View File

@ -25,8 +25,10 @@ public class MapValueValueModel implements ValueModel {
private Class<?> elementType; private Class<?> elementType;
@SuppressWarnings("unchecked")
private Map map; private Map map;
@SuppressWarnings("unchecked")
public MapValueValueModel(Object key, Class<?> elementType, Map map, BindingContext bindingContext) { public MapValueValueModel(Object key, Class<?> elementType, Map map, BindingContext bindingContext) {
this.key = key; this.key = key;
this.elementType = elementType; this.elementType = elementType;
@ -53,6 +55,7 @@ public class MapValueValueModel implements ValueModel {
return true; return true;
} }
@SuppressWarnings("unchecked")
public void setValue(Object value) { public void setValue(Object value) {
map.put(key, value); map.put(key, value);
} }

View File

@ -15,6 +15,7 @@
*/ */
package org.springframework.ui.binding.support; package org.springframework.ui.binding.support;
@SuppressWarnings("serial")
public class PropertyNotFoundException extends RuntimeException { public class PropertyNotFoundException extends RuntimeException {
private String property; private String property;