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;
/**
* 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
* @since 3.0
*/
@ -138,12 +138,12 @@ public interface Binding {
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();
/**
* 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
* @return the indexed binding
* @throws IllegalStateException if not a list
@ -151,7 +151,7 @@ public interface Binding {
Binding getListElementBinding(int index);
/**
* If bound to a {@link java.util.Map}.
* If bound to a Map.
*/
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);
@SuppressWarnings("unchecked")
Formatter getFormatter();
@SuppressWarnings("unchecked")
Formatter getElementFormatter();
@SuppressWarnings("unchecked")
Formatter getKeyFormatter();
Binding getListElementBinding(int index);

View File

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

View File

@ -25,7 +25,6 @@ import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import org.codehaus.groovy.binding.PropertyBinding;
import org.springframework.context.MessageSource;
import org.springframework.core.GenericCollectionTypeResolver;
import org.springframework.core.convert.TypeConverter;
@ -446,7 +445,7 @@ public class GenericBindingFactory implements BindingFactory {
}
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();
if (elementType == null) {
elementType = model.getClass();
@ -461,14 +460,17 @@ public class GenericBindingFactory implements BindingFactory {
return binding;
}
@SuppressWarnings("unchecked")
public Formatter getFormatter() {
return listBindingContext.getElementFormatter();
}
@SuppressWarnings("unchecked")
public Formatter getElementFormatter() {
return null;
}
@SuppressWarnings("unchecked")
public Formatter getKeyFormatter() {
return null;
}
@ -520,6 +522,7 @@ public class GenericBindingFactory implements BindingFactory {
return mapBindingContext.getTypeConverter();
}
@SuppressWarnings("unchecked")
public Binding getBinding(String property) {
Object model = ((Map) mapBindingContext.binding.getValue()).get(key);
Class<?> elementType = mapBindingContext.getElementType();
@ -536,14 +539,17 @@ public class GenericBindingFactory implements BindingFactory {
return binding;
}
@SuppressWarnings("unchecked")
public Formatter getFormatter() {
return mapBindingContext.getElementFormatter();
}
@SuppressWarnings("unchecked")
public Formatter getElementFormatter() {
return null;
}
@SuppressWarnings("unchecked")
public Formatter getKeyFormatter() {
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 {
@SuppressWarnings("unchecked")
private List list;
private int index;
private Class<?> elementType;
@SuppressWarnings("unchecked")
public ListElementValueModel(int index, Class<?> elementType, List list) {
this.index = index;
this.elementType = elementType;
@ -53,6 +55,7 @@ class ListElementValueModel implements ValueModel {
return true;
}
@SuppressWarnings("unchecked")
public void setValue(Object value) {
list.set(index, value);
}

View File

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

View File

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