From 29768cb0682eb9dd0d8a39090ae5bad27f7b799d Mon Sep 17 00:00:00 2001 From: Keith Donald Date: Thu, 23 Jul 2009 13:31:06 +0000 Subject: [PATCH] binding factory locator --- .../springframework/ui/binding/Binding.java | 8 ++-- .../ui/binding/BindingFactoryLocator.java | 33 ++++++++++++++ .../ui/binding/support/BindingContext.java | 3 ++ .../ui/binding/support/GenericBinding.java | 5 ++- .../support/GenericBindingFactory.java | 10 ++++- .../support/GenericBindingFactoryLocator.java | 45 +++++++++++++++++++ .../support/ListElementValueModel.java | 3 ++ .../binding/support/MapValueValueModel.java | 3 ++ .../support/PropertyNotFoundException.java | 1 + 9 files changed, 104 insertions(+), 7 deletions(-) create mode 100644 org.springframework.context/src/main/java/org/springframework/ui/binding/BindingFactoryLocator.java create mode 100644 org.springframework.context/src/main/java/org/springframework/ui/binding/support/GenericBindingFactoryLocator.java diff --git a/org.springframework.context/src/main/java/org/springframework/ui/binding/Binding.java b/org.springframework.context/src/main/java/org/springframework/ui/binding/Binding.java index 694c8f83a96..620434f68f6 100644 --- a/org.springframework.context/src/main/java/org/springframework/ui/binding/Binding.java +++ b/org.springframework.context/src/main/java/org/springframework/ui/binding/Binding.java @@ -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(); diff --git a/org.springframework.context/src/main/java/org/springframework/ui/binding/BindingFactoryLocator.java b/org.springframework.context/src/main/java/org/springframework/ui/binding/BindingFactoryLocator.java new file mode 100644 index 00000000000..e880b6b66c4 --- /dev/null +++ b/org.springframework.context/src/main/java/org/springframework/ui/binding/BindingFactoryLocator.java @@ -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 null. + * @param model the model object + * @return the binding Factory + */ + public BindingFactory getBindingFactory(Object model); +} \ No newline at end of file diff --git a/org.springframework.context/src/main/java/org/springframework/ui/binding/support/BindingContext.java b/org.springframework.context/src/main/java/org/springframework/ui/binding/support/BindingContext.java index b976f14804b..bea8ace5a37 100644 --- a/org.springframework.context/src/main/java/org/springframework/ui/binding/support/BindingContext.java +++ b/org.springframework.context/src/main/java/org/springframework/ui/binding/support/BindingContext.java @@ -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); diff --git a/org.springframework.context/src/main/java/org/springframework/ui/binding/support/GenericBinding.java b/org.springframework.context/src/main/java/org/springframework/ui/binding/support/GenericBinding.java index 075db683281..41fbed97dc3 100644 --- a/org.springframework.context/src/main/java/org/springframework/ui/binding/support/GenericBinding.java +++ b/org.springframework.context/src/main/java/org/springframework/ui/binding/support/GenericBinding.java @@ -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(); diff --git a/org.springframework.context/src/main/java/org/springframework/ui/binding/support/GenericBindingFactory.java b/org.springframework.context/src/main/java/org/springframework/ui/binding/support/GenericBindingFactory.java index bbd9ace9030..8f7cb22232b 100644 --- a/org.springframework.context/src/main/java/org/springframework/ui/binding/support/GenericBindingFactory.java +++ b/org.springframework.context/src/main/java/org/springframework/ui/binding/support/GenericBindingFactory.java @@ -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; } diff --git a/org.springframework.context/src/main/java/org/springframework/ui/binding/support/GenericBindingFactoryLocator.java b/org.springframework.context/src/main/java/org/springframework/ui/binding/support/GenericBindingFactoryLocator.java new file mode 100644 index 00000000000..8c2805d9972 --- /dev/null +++ b/org.springframework.context/src/main/java/org/springframework/ui/binding/support/GenericBindingFactoryLocator.java @@ -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 bindingFactories = new IdentityHashMap(); + + 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; + } + +} diff --git a/org.springframework.context/src/main/java/org/springframework/ui/binding/support/ListElementValueModel.java b/org.springframework.context/src/main/java/org/springframework/ui/binding/support/ListElementValueModel.java index 28218bdb2ec..4e67860f646 100644 --- a/org.springframework.context/src/main/java/org/springframework/ui/binding/support/ListElementValueModel.java +++ b/org.springframework.context/src/main/java/org/springframework/ui/binding/support/ListElementValueModel.java @@ -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); } diff --git a/org.springframework.context/src/main/java/org/springframework/ui/binding/support/MapValueValueModel.java b/org.springframework.context/src/main/java/org/springframework/ui/binding/support/MapValueValueModel.java index 940d2554426..6f98f87b11f 100644 --- a/org.springframework.context/src/main/java/org/springframework/ui/binding/support/MapValueValueModel.java +++ b/org.springframework.context/src/main/java/org/springframework/ui/binding/support/MapValueValueModel.java @@ -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); } diff --git a/org.springframework.context/src/main/java/org/springframework/ui/binding/support/PropertyNotFoundException.java b/org.springframework.context/src/main/java/org/springframework/ui/binding/support/PropertyNotFoundException.java index c4fac86a736..7343d8e1abc 100644 --- a/org.springframework.context/src/main/java/org/springframework/ui/binding/support/PropertyNotFoundException.java +++ b/org.springframework.context/src/main/java/org/springframework/ui/binding/support/PropertyNotFoundException.java @@ -15,6 +15,7 @@ */ package org.springframework.ui.binding.support; +@SuppressWarnings("serial") public class PropertyNotFoundException extends RuntimeException { private String property;