Brought spring-binding code to formatting conventions

This commit is contained in:
Ben Hale
2007-08-13 16:22:21 +00:00
parent 59c2d3779b
commit 63da2ec88d
84 changed files with 985 additions and 1226 deletions

View File

@@ -23,16 +23,15 @@ import java.util.NoSuchElementException;
import org.springframework.util.Assert;
/**
* Iterator that combines multiple other iterators. This is a simple implementation
* that just maintains a list of iterators which are invoked in sequence untill
* all iterators are exhausted.
* Iterator that combines multiple other iterators. This is a simple implementation that just maintains a list of
* iterators which are invoked in sequence untill all iterators are exhausted.
*
* @author Erwin Vervaet
*/
public class CompositeIterator implements Iterator {
private List iterators = new LinkedList();
private boolean inUse = false;
/**
@@ -40,7 +39,7 @@ public class CompositeIterator implements Iterator {
*/
public CompositeIterator() {
}
/**
* Add given iterator to this composite.
*/
@@ -54,8 +53,8 @@ public class CompositeIterator implements Iterator {
public boolean hasNext() {
inUse = true;
for (Iterator it = iterators.iterator(); it.hasNext(); ) {
if (((Iterator)it.next()).hasNext()) {
for (Iterator it = iterators.iterator(); it.hasNext();) {
if (((Iterator) it.next()).hasNext()) {
return true;
}
}
@@ -64,8 +63,8 @@ public class CompositeIterator implements Iterator {
public Object next() {
inUse = true;
for (Iterator it = iterators.iterator(); it.hasNext(); ) {
Iterator iterator = (Iterator)it.next();
for (Iterator it = iterators.iterator(); it.hasNext();) {
Iterator iterator = (Iterator) it.next();
if (iterator.hasNext()) {
return iterator.next();
}
@@ -75,5 +74,5 @@ public class CompositeIterator implements Iterator {
public void remove() {
throw new UnsupportedOperationException("Remove is not supported");
}
}
}

View File

@@ -21,8 +21,8 @@ import java.util.Map;
import org.springframework.util.Assert;
/**
* A simple, generic decorator for getting attributes out of a map. May be
* instantiated directly or used as a base class as a convenience.
* A simple, generic decorator for getting attributes out of a map. May be instantiated directly or used as a base class
* as a convenience.
*
* @author Keith Donald
*/
@@ -43,14 +43,13 @@ public class MapAccessor implements MapAdaptable {
}
// implementing MapAdaptable
public Map asMap() {
return map;
}
/**
* Returns a value in the map, returning the defaultValue if no value was
* found.
* Returns a value in the map, returning the defaultValue if no value was found.
* @param key the key
* @param defaultValue the default
* @return the attribute value
@@ -63,27 +62,24 @@ public class MapAccessor implements MapAdaptable {
}
/**
* Returns a value in the map, asserting it is of the required type if
* present and returning <code>null</code> if not found.
* Returns a value in the map, asserting it is of the required type if present and returning <code>null</code> if
* not found.
* @param key the key
* @param requiredType the required type
* @return the value
* @throws IllegalArgumentException if the key is present but the value is
* not of the required type
* @throws IllegalArgumentException if the key is present but the value is not of the required type
*/
public Object get(Object key, Class requiredType) throws IllegalArgumentException {
return get(key, requiredType, null);
}
/**
* Returns a value in the map of the specified type, returning the
* defaultValue if no value is found.
* Returns a value in the map of the specified type, returning the defaultValue if no value is found.
* @param key the key
* @param requiredType the required type
* @param defaultValue the default
* @return the attribute value
* @throws IllegalArgumentException if the key is present but the value is
* not of the required type
* @throws IllegalArgumentException if the key is present but the value is not of the required type
*/
public Object get(Object key, Class requiredType, Object defaultValue) {
if (!map.containsKey(key)) {
@@ -93,8 +89,7 @@ public class MapAccessor implements MapAdaptable {
}
/**
* Returns a value in the map, throwing an exception if the attribute is not
* present and of the correct type.
* Returns a value in the map, throwing an exception if the attribute is not present and of the correct type.
* @param key the key
* @return the value
*/
@@ -104,8 +99,7 @@ public class MapAccessor implements MapAdaptable {
}
/**
* Returns an value in the map, asserting it is present and of the required
* type.
* Returns an value in the map, asserting it is present and of the required type.
* @param key the key
* @param requiredType the required type
* @return the value
@@ -116,217 +110,195 @@ public class MapAccessor implements MapAdaptable {
}
/**
* Returns a string value in the map, returning <code>null</code> if no
* value was found.
* Returns a string value in the map, returning <code>null</code> if no value was found.
* @param key the key
* @return the string value
* @throws IllegalArgumentException if the key is present but the value is
* not a string
* @throws IllegalArgumentException if the key is present but the value is not a string
*/
public String getString(Object key) throws IllegalArgumentException {
return getString(key, null);
}
/**
* Returns a string value in the map, returning the defaultValue if no value
* was found.
* Returns a string value in the map, returning the defaultValue if no value was found.
* @param key the key
* @param defaultValue the default
* @return the string value
* @throws IllegalArgumentException if the key is present but the value is
* not a string
* @throws IllegalArgumentException if the key is present but the value is not a string
*/
public String getString(Object key, String defaultValue) throws IllegalArgumentException {
if (!map.containsKey(key)) {
return defaultValue;
}
return (String)assertKeyValueOfType(key, String.class);
return (String) assertKeyValueOfType(key, String.class);
}
/**
* Returns a string value in the map, throwing an exception if the attribute
* is not present and of the correct type.
* Returns a string value in the map, throwing an exception if the attribute is not present and of the correct type.
* @param key the key
* @return the string value
* @throws IllegalArgumentException if the key is not present or present but
* the value is not a string
* @throws IllegalArgumentException if the key is not present or present but the value is not a string
*/
public String getRequiredString(Object key) throws IllegalArgumentException {
assertContainsKey(key);
return (String)assertKeyValueOfType(key, String.class);
return (String) assertKeyValueOfType(key, String.class);
}
/**
* Returns a collection value in the map, returning <code>null</code> if
* no value was found.
* Returns a collection value in the map, returning <code>null</code> if no value was found.
* @param key the key
* @return the collection value
* @throws IllegalArgumentException if the key is present but the value is
* not a collection
* @throws IllegalArgumentException if the key is present but the value is not a collection
*/
public Collection getCollection(Object key) throws IllegalArgumentException {
if (!map.containsKey(key)) {
return null;
}
return (Collection)assertKeyValueOfType(key, Collection.class);
return (Collection) assertKeyValueOfType(key, Collection.class);
}
/**
* Returns a collection value in the map, asserting it is of the required
* type if present and returning <code>null</code> if not found.
* Returns a collection value in the map, asserting it is of the required type if present and returning
* <code>null</code> if not found.
* @param key the key
* @return the collection value
* @throws IllegalArgumentException if the key is present but the value is
* not a collection
* @throws IllegalArgumentException if the key is present but the value is not a collection
*/
public Collection getCollection(Object key, Class requiredType) throws IllegalArgumentException {
if (!map.containsKey(key)) {
return null;
}
assertAssignableTo(Collection.class, requiredType);
return (Collection)assertKeyValueOfType(key, requiredType);
return (Collection) assertKeyValueOfType(key, requiredType);
}
/**
* Returns a collection value in the map, throwing an exception if not
* found.
* Returns a collection value in the map, throwing an exception if not found.
* @param key the key
* @return the collection value
* @throws IllegalArgumentException if the key is not present or present but
* the value is not a collection
* @throws IllegalArgumentException if the key is not present or present but the value is not a collection
*/
public Collection getRequiredCollection(Object key) throws IllegalArgumentException {
assertContainsKey(key);
return (Collection)assertKeyValueOfType(key, Collection.class);
return (Collection) assertKeyValueOfType(key, Collection.class);
}
/**
* Returns a collection value in the map, asserting it is of the required
* type if present and throwing an exception if not found.
* Returns a collection value in the map, asserting it is of the required type if present and throwing an exception
* if not found.
* @param key the key
* @return the collection value
* @throws IllegalArgumentException if the key is not present or present but
* the value is not a collection of the required type
* @throws IllegalArgumentException if the key is not present or present but the value is not a collection of the
* required type
*/
public Collection getRequiredCollection(Object key, Class requiredType) throws IllegalArgumentException {
assertContainsKey(key);
assertAssignableTo(Collection.class, requiredType);
return (Collection)assertKeyValueOfType(key, requiredType);
return (Collection) assertKeyValueOfType(key, requiredType);
}
/**
* Returns a array value in the map, asserting it is of the required type if
* present and returning <code>null</code> if not found.
* Returns a array value in the map, asserting it is of the required type if present and returning <code>null</code>
* if not found.
* @param key the key
* @return the array value
* @throws IllegalArgumentException if the key is present but the value is
* not an array of the required type
* @throws IllegalArgumentException if the key is present but the value is not an array of the required type
*/
public Object[] getArray(Object key, Class requiredType) throws IllegalArgumentException {
assertAssignableTo(Object[].class, requiredType);
if (!map.containsKey(key)) {
return null;
}
return (Object[])assertKeyValueOfType(key, requiredType);
return (Object[]) assertKeyValueOfType(key, requiredType);
}
/**
* Returns an array value in the map, asserting it is of the required type
* if present and throwing an exception if not found.
* Returns an array value in the map, asserting it is of the required type if present and throwing an exception if
* not found.
* @param key the key
* @return the array value
* @throws IllegalArgumentException if the key is not present or present but
* the value is not a array of the required type
* @throws IllegalArgumentException if the key is not present or present but the value is not a array of the
* required type
*/
public Object[] getRequiredArray(Object key, Class requiredType) throws IllegalArgumentException {
assertContainsKey(key);
assertAssignableTo(Object[].class, requiredType);
return (Object[])assertKeyValueOfType(key, requiredType);
return (Object[]) assertKeyValueOfType(key, requiredType);
}
/**
* Returns a number value in the map that is of the specified type,
* returning <code>null</code> if no value was found.
* Returns a number value in the map that is of the specified type, returning <code>null</code> if no value was
* found.
* @param key the key
* @param requiredType the required number type
* @return the numbervalue
* @throws IllegalArgumentException if the key is present but the value is
* not a number of the required type
* @throws IllegalArgumentException if the key is present but the value is not a number of the required type
*/
public Number getNumber(Object key, Class requiredType) throws IllegalArgumentException {
return getNumber(key, requiredType, null);
}
/**
* Returns a number attribute value in the map of the specified type,
* returning the defaultValue if no value was found.
* Returns a number attribute value in the map of the specified type, returning the defaultValue if no value was
* found.
* @param key the attribute name
* @return the number value
* @param defaultValue the default
* @throws IllegalArgumentException if the key is present but the value is
* not a number of the required type
* @throws IllegalArgumentException if the key is present but the value is not a number of the required type
*/
public Number getNumber(Object key, Class requiredType, Number defaultValue) throws IllegalArgumentException {
if (!map.containsKey(key)) {
return defaultValue;
}
assertAssignableTo(Number.class, requiredType);
return (Number)assertKeyValueOfType(key, requiredType);
return (Number) assertKeyValueOfType(key, requiredType);
}
/**
* Returns a number value in the map, throwing an exception if the attribute
* is not present and of the correct type.
* Returns a number value in the map, throwing an exception if the attribute is not present and of the correct type.
* @param key the key
* @return the number value
* @throws IllegalArgumentException if the key is not present or present but
* the value is not a number of the required type
* @throws IllegalArgumentException if the key is not present or present but the value is not a number of the
* required type
*/
public Number getRequiredNumber(Object key, Class requiredType) throws IllegalArgumentException {
assertContainsKey(key);
return (Number)assertKeyValueOfType(key, requiredType);
return (Number) assertKeyValueOfType(key, requiredType);
}
/**
* Returns an integer value in the map, returning <code>null</code> if no
* value was found.
* Returns an integer value in the map, returning <code>null</code> if no value was found.
* @param key the key
* @return the integer value
* @throws IllegalArgumentException if the key is present but the value is
* not an integer
* @throws IllegalArgumentException if the key is present but the value is not an integer
*/
public Integer getInteger(Object key) throws IllegalArgumentException {
return getInteger(key, null);
}
/**
* Returns an integer value in the map, returning the defaultValue if no
* value was found.
* Returns an integer value in the map, returning the defaultValue if no value was found.
* @param key the key
* @param defaultValue the default
* @return the integer value
* @throws IllegalArgumentException if the key is present but the value is
* not an integer
* @throws IllegalArgumentException if the key is present but the value is not an integer
*/
public Integer getInteger(Object key, Integer defaultValue) throws IllegalArgumentException {
return (Integer)getNumber(key, Integer.class, defaultValue);
return (Integer) getNumber(key, Integer.class, defaultValue);
}
/**
* Returns an integer value in the map, throwing an exception if the value
* is not present and of the correct type.
* Returns an integer value in the map, throwing an exception if the value is not present and of the correct type.
* @param key the attribute name
* @return the integer attribute value
* @throws IllegalArgumentException if the key is not present or present but
* the value is not an integer
* @throws IllegalArgumentException if the key is not present or present but the value is not an integer
*/
public Integer getRequiredInteger(Object key) throws IllegalArgumentException {
return (Integer)getRequiredNumber(key, Integer.class);
return (Integer) getRequiredNumber(key, Integer.class);
}
/**
* Returns a long value in the map, returning <code>null</code> if no
* value was found.
* Returns a long value in the map, returning <code>null</code> if no value was found.
* @param key the key
* @return the long value
* @throws IllegalArgumentException if the key is present but not a long
@@ -336,69 +308,59 @@ public class MapAccessor implements MapAdaptable {
}
/**
* Returns a long value in the map, returning the defaultValue if no value
* was found.
* Returns a long value in the map, returning the defaultValue if no value was found.
* @param key the key
* @param defaultValue the default
* @return the long attribute value
* @throws IllegalArgumentException if the key is present but the value is
* not a long
* @throws IllegalArgumentException if the key is present but the value is not a long
*/
public Long getLong(Object key, Long defaultValue) throws IllegalArgumentException {
return (Long)getNumber(key, Long.class, defaultValue);
return (Long) getNumber(key, Long.class, defaultValue);
}
/**
* Returns a long value in the map, throwing an exception if the value is
* not present and of the correct type.
* Returns a long value in the map, throwing an exception if the value is not present and of the correct type.
* @param key the key
* @return the long attribute value
* @throws IllegalArgumentException if the key is not present or present but
* the value is not a long
* @throws IllegalArgumentException if the key is not present or present but the value is not a long
*/
public Long getRequiredLong(Object key) throws IllegalArgumentException {
return (Long)getRequiredNumber(key, Long.class);
return (Long) getRequiredNumber(key, Long.class);
}
/**
* Returns a boolean value in the map, returning <code>null</code> if no
* value was found.
* Returns a boolean value in the map, returning <code>null</code> if no value was found.
* @param key the key
* @return the boolean value
* @throws IllegalArgumentException if the key is present but the value is
* not a boolean
* @throws IllegalArgumentException if the key is present but the value is not a boolean
*/
public Boolean getBoolean(Object key) throws IllegalArgumentException {
return getBoolean(key, null);
}
/**
* Returns a boolean value in the map, returning the defaultValue if no
* value was found.
* Returns a boolean value in the map, returning the defaultValue if no value was found.
* @param key the key
* @param defaultValue the default
* @return the boolean value
* @throws IllegalArgumentException if the key is present but the value is
* not a boolean
* @throws IllegalArgumentException if the key is present but the value is not a boolean
*/
public Boolean getBoolean(Object key, Boolean defaultValue) throws IllegalArgumentException {
if (!map.containsKey(key)) {
return defaultValue;
}
return (Boolean)assertKeyValueOfType(key, Boolean.class);
return (Boolean) assertKeyValueOfType(key, Boolean.class);
}
/**
* Returns a boolean value in the map, throwing an exception if the value is
* not present and of the correct type.
* Returns a boolean value in the map, throwing an exception if the value is not present and of the correct type.
* @param key the attribute
* @return the boolean value
* @throws IllegalArgumentException if the key is not present or present but
* the value is not a boolean
* @throws IllegalArgumentException if the key is not present or present but the value is not a boolean
*/
public Boolean getRequiredBoolean(Object key) throws IllegalArgumentException {
assertContainsKey(key);
return (Boolean)assertKeyValueOfType(key, Boolean.class);
return (Boolean) assertKeyValueOfType(key, Boolean.class);
}
/**
@@ -414,8 +376,7 @@ public class MapAccessor implements MapAdaptable {
}
/**
* Indicates if the attribute is present in the attribute map and of the
* required type.
* Indicates if the attribute is present in the attribute map and of the required type.
* @param key the attribute name
* @return true if present and of the required type, false if not present.
*/
@@ -423,8 +384,7 @@ public class MapAccessor implements MapAdaptable {
if (map.containsKey(key)) {
assertKeyValueOfType(key, requiredType);
return true;
}
else {
} else {
return false;
}
}

View File

@@ -25,11 +25,11 @@ import java.util.Map;
public interface MapAdaptable {
/**
* Returns this object's contents as a {@link Map}. The returned map may or
* may not be modifiable depending on this implementation.
* Returns this object's contents as a {@link Map}. The returned map may or may not be modifiable depending on this
* implementation.
* <p>
* Warning: this operation may be called frequently; if so care should be
* taken so that the map contents (if calculated) be cached as appropriate.
* Warning: this operation may be called frequently; if so care should be taken so that the map contents (if
* calculated) be cached as appropriate.
* @return the object's contents as a map
*/
public Map asMap();

View File

@@ -18,20 +18,18 @@ package org.springframework.binding.collection;
import java.util.Map;
/**
* A simple subinterface of {@link Map} that exposes a mutex that
* application code can synchronize on.
* A simple subinterface of {@link Map} that exposes a mutex that application code can synchronize on.
* <p>
* Expected to be implemented by Maps that are backed by shared objects that
* require synchronization between multiple threads. An example would be the
* HTTP session map.
* Expected to be implemented by Maps that are backed by shared objects that require synchronization between multiple
* threads. An example would be the HTTP session map.
*
* @author Keith Donald
*/
public interface SharedMap extends Map {
/**
* Returns the shared mutex that may be synchronized on using a
* synchronized block. The returned mutex is guaranteed to be non-null.
* Returns the shared mutex that may be synchronized on using a synchronized block. The returned mutex is guaranteed
* to be non-null.
*
* Example usage:
*

View File

@@ -23,9 +23,8 @@ import java.util.Set;
import org.springframework.core.style.ToStringCreator;
/**
* A map decorator that implements <code>SharedMap</code>. By default, simply
* returns the map itself as the mutex. Subclasses may override to return a
* different mutex object.
* A map decorator that implements <code>SharedMap</code>. By default, simply returns the map itself as the mutex.
* Subclasses may override to return a different mutex object.
*
* @author Keith Donald
*/
@@ -43,7 +42,7 @@ public class SharedMapDecorator implements SharedMap, Serializable {
public SharedMapDecorator(Map map) {
this.map = map;
}
// implementing Map
public void clear() {
@@ -93,7 +92,7 @@ public class SharedMapDecorator implements SharedMap, Serializable {
public Collection values() {
return map.values();
}
// implementing SharedMap
public Object getMutex() {

View File

@@ -22,24 +22,24 @@ import java.util.NoSuchElementException;
import java.util.Set;
/**
* Base class for map adapters whose keys are String values. Concrete
* classes need only implement the abstract hook methods defined by this class.
* Base class for map adapters whose keys are String values. Concrete classes need only implement the abstract hook
* methods defined by this class.
*
* @author Keith Donald
*/
public abstract class StringKeyedMapAdapter implements Map {
private Set keySet;
private Collection values;
private Set entrySet;
// implementing Map
public void clear() {
for (Iterator it = getAttributeNames(); it.hasNext();) {
removeAttribute((String)it.next());
removeAttribute((String) it.next());
}
}
@@ -52,7 +52,7 @@ public abstract class StringKeyedMapAdapter implements Map {
return false;
}
for (Iterator it = getAttributeNames(); it.hasNext();) {
Object aValue = getAttribute((String)it.next());
Object aValue = getAttribute((String) it.next());
if (value.equals(aValue)) {
return true;
}
@@ -85,7 +85,7 @@ public abstract class StringKeyedMapAdapter implements Map {
public void putAll(Map map) {
for (Iterator it = map.entrySet().iterator(); it.hasNext();) {
Entry entry = (Entry)it.next();
Entry entry = (Entry) it.next();
setAttribute(entry.getKey().toString(), entry.getValue());
}
}
@@ -109,40 +109,38 @@ public abstract class StringKeyedMapAdapter implements Map {
public Collection values() {
return (values != null) ? values : (values = new Values());
}
// hook methods
/**
* Hook method that needs to be implemented by concrete subclasses.
* Gets a value associated with a key.
* Hook method that needs to be implemented by concrete subclasses. Gets a value associated with a key.
* @param key the key to lookup
* @return the associated value, or null if none
*/
protected abstract Object getAttribute(String key);
/**
* Hook method that needs to be implemented by concrete subclasses.
* Puts a key-value pair in the map, overwriting any possible earlier
* value associated with the same key.
* Hook method that needs to be implemented by concrete subclasses. Puts a key-value pair in the map, overwriting
* any possible earlier value associated with the same key.
* @param key the key to associate the value with
* @param value the value to associate with the key
*/
protected abstract void setAttribute(String key, Object value);
/**
* Hook method that needs to be implemented by concrete subclasses.
* Removes a key and its associated value from the map.
* Hook method that needs to be implemented by concrete subclasses. Removes a key and its associated value from the
* map.
* @param key the key to remove
*/
protected abstract void removeAttribute(String key);
/**
* Hook method that needs to be implemented by concrete subclasses.
* Returns an enumeration listing all keys known to the map.
* Hook method that needs to be implemented by concrete subclasses. Returns an enumeration listing all keys known to
* the map.
* @return the key enumeration
*/
protected abstract Iterator getAttributeNames();
// internal helper classes
private abstract class AbstractSet extends java.util.AbstractSet {
@@ -233,7 +231,7 @@ public abstract class StringKeyedMapAdapter implements Map {
if (!(o instanceof Entry)) {
return false;
}
Entry entry = (Entry)o;
Entry entry = (Entry) o;
Object key = entry.getKey();
Object value = entry.getValue();
if (key == null || value == null) {
@@ -246,13 +244,13 @@ public abstract class StringKeyedMapAdapter implements Map {
if (!(o instanceof Entry)) {
return false;
}
Entry entry = (Entry)o;
Entry entry = (Entry) o;
Object key = entry.getKey();
Object value = entry.getValue();
if (key == null || value == null || !value.equals(StringKeyedMapAdapter.this.get(key))) {
return false;
}
return StringKeyedMapAdapter.this.remove(((Entry)o).getKey()) != null;
return StringKeyedMapAdapter.this.remove(((Entry) o).getKey()) != null;
}
}

View File

@@ -18,13 +18,10 @@ package org.springframework.binding.convert;
/**
* A context object with two main responsibities:
* <ol>
* <li>Exposing information to a converter to influence
* a type conversion attempt.
* <li>Providing operations for recording progress or
* errors during the type conversion process.
* <li>Exposing information to a converter to influence a type conversion attempt.
* <li>Providing operations for recording progress or errors during the type conversion process.
* </ol>
* Empty for now; subclasses may define their own custom context behavior
* accessible by a converter with a downcast.
* Empty for now; subclasses may define their own custom context behavior accessible by a converter with a downcast.
*
* @author Keith Donald
*/

View File

@@ -23,15 +23,14 @@ import org.springframework.core.NestedRuntimeException;
* @author Keith Donald
*/
public class ConversionException extends NestedRuntimeException {
/**
* The source type we tried to convert from
*/
private Class sourceClass;
/**
* The value we tried to convert.
* Transient because we cannot guarantee that the value is Serializable.
* The value we tried to convert. Transient because we cannot guarantee that the value is Serializable.
*/
private transient Object value;
@@ -77,7 +76,7 @@ public class ConversionException extends NestedRuntimeException {
this.value = value;
this.targetClass = targetClass;
}
/**
* Creates a new conversion exception.
* @param sourceClass the source type
@@ -90,7 +89,7 @@ public class ConversionException extends NestedRuntimeException {
this.value = null; // not available
this.targetClass = targetClass;
}
/**
* Creates a new conversion exception.
* @param sourceClass the source type
@@ -102,7 +101,7 @@ public class ConversionException extends NestedRuntimeException {
this.value = null; // not available
this.targetClass = null; // not available
}
/**
* Creates a new conversion exception.
* @param sourceClass the source type
@@ -116,7 +115,7 @@ public class ConversionException extends NestedRuntimeException {
this.value = value;
this.targetClass = targetClass;
}
/**
* Returns the source type.
*/

View File

@@ -19,11 +19,11 @@ import org.springframework.core.style.ToStringCreator;
import org.springframework.util.Assert;
/**
* A command object that is parameterized with the information necessary to
* perform a conversion of a source input to a target output.
* A command object that is parameterized with the information necessary to perform a conversion of a source input to a
* target output.
* <p>
* Specifically, encapsulates knowledge about how to convert source objects to a
* specific target type using a specific converter.
* Specifically, encapsulates knowledge about how to convert source objects to a specific target type using a specific
* converter.
*
* @author Keith Donald
*/
@@ -74,7 +74,7 @@ public class ConversionExecutor {
public Class getTargetClass() {
return targetClass;
}
/**
* Returns the converter that will perform the conversion.
* @return the converter
@@ -94,8 +94,7 @@ public class ConversionExecutor {
/**
* Execute the conversion for the provided source object.
* @param source the source object to convert
* @param context the conversion context, useful for influencing the
* behavior of the converter
* @param context the conversion context, useful for influencing the behavior of the converter
*/
public Object execute(Object source, ConversionContext context) throws ConversionException {
if (getTargetClass().isInstance(source)) {
@@ -103,8 +102,8 @@ public class ConversionExecutor {
return source;
}
if (source != null && !getSourceClass().isInstance(source)) {
throw new ConversionException(getSourceClass(), source, getTargetClass(),
"Source object '" + source + "' is expected to be an instance of " + getSourceClass());
throw new ConversionException(getSourceClass(), source, getTargetClass(), "Source object '" + source
+ "' is expected to be an instance of " + getSourceClass());
}
return converter.convert(source, targetClass, context);
}
@@ -113,7 +112,7 @@ public class ConversionExecutor {
if (!(o instanceof ConversionExecutor)) {
return false;
}
ConversionExecutor other = (ConversionExecutor)o;
ConversionExecutor other = (ConversionExecutor) o;
return sourceClass.equals(other.sourceClass) && targetClass.equals(other.targetClass);
}

View File

@@ -16,52 +16,44 @@
package org.springframework.binding.convert;
/**
* A service interface for retrieving type conversion executors. The returned
* command objects are thread-safe and may be safely cached for use by client
* code.
* A service interface for retrieving type conversion executors. The returned command objects are thread-safe and may be
* safely cached for use by client code.
*
* @author Keith Donald
*/
public interface ConversionService {
/**
* Return a conversion executor command object capable of converting source
* objects of the specified <code>sourceClass</code> to instances of the
* <code>targetClass</code>.
* Return a conversion executor command object capable of converting source objects of the specified
* <code>sourceClass</code> to instances of the <code>targetClass</code>.
* <p>
* The returned ConversionExecutor is thread-safe and may safely be cached
* for use in client code.
* The returned ConversionExecutor is thread-safe and may safely be cached for use in client code.
* @param sourceClass the source class to convert from
* @param targetClass the target class to convert to
* @return the executor that can execute instance conversion, never null
* @throws ConversionException an exception occured retrieving a converter
* for the source-to-target pair
* @throws ConversionException an exception occured retrieving a converter for the source-to-target pair
*/
public ConversionExecutor getConversionExecutor(Class sourceClass, Class targetClass)
throws ConversionException;
public ConversionExecutor getConversionExecutor(Class sourceClass, Class targetClass) throws ConversionException;
/**
* Return a conversion executor command object capable of converting source
* objects of the specified <code>sourceClass</code> to target objects of
* the type associated with the specified alias.
* Return a conversion executor command object capable of converting source objects of the specified
* <code>sourceClass</code> to target objects of the type associated with the specified alias.
* @param sourceClass the sourceClass
* @param targetAlias the target alias
* @return the conversion executor, or null if the alias cannot be found
* @throws ConversionException an exception occured retrieving a converter
* for the source-to-target pair
* @throws ConversionException an exception occured retrieving a converter for the source-to-target pair
*/
public ConversionExecutor getConversionExecutorByTargetAlias(Class sourceClass, String targetAlias)
throws ConversionException;
/**
* Return all conversion executors capable of converting source objects of
* the the specified <code>sourceClass</code>.
* Return all conversion executors capable of converting source objects of the the specified
* <code>sourceClass</code>.
* @param sourceClass the source class to convert from
* @return the matching conversion executors
* @throws ConversionException an exception occured retrieving the converters
*/
public ConversionExecutor[] getConversionExecutorsForSource(Class sourceClass)
throws ConversionException;
public ConversionExecutor[] getConversionExecutorsForSource(Class sourceClass) throws ConversionException;
/**
* Return the class with the specified alias.

View File

@@ -16,8 +16,8 @@
package org.springframework.binding.convert;
/**
* A type converter converts objects from one type to another. They may support
* conversion of multiple source types to multiple target types.
* A type converter converts objects from one type to another. They may support conversion of multiple source types to
* multiple target types.
* <p>
* Implementations of this interface are thread-safe.
*
@@ -38,14 +38,11 @@ public interface Converter {
public Class[] getTargetClasses();
/**
* Convert the provided source object argument to an instance of the
* specified target class.
* @param source the source object to convert, its class must be one of the
* supported <code>sourceClasses</code>
* @param targetClass the target class to convert the source to, must be one
* of the supported <code>targetClasses</code>
* @param context an optional conversion context that may be used to
* influence the conversion process
* Convert the provided source object argument to an instance of the specified target class.
* @param source the source object to convert, its class must be one of the supported <code>sourceClasses</code>
* @param targetClass the target class to convert the source to, must be one of the supported
* <code>targetClasses</code>
* @param context an optional conversion context that may be used to influence the conversion process
* @return the converted object, an instance of the target type
* @throws ConversionException an exception occured during the conversion
*/

View File

@@ -27,42 +27,36 @@ import org.springframework.binding.convert.Converter;
public abstract class AbstractConverter implements Converter {
/**
* Convenience convert method that converts the provided source to the first
* target object supported by this converter. Useful when a converter only
* supports conversion to a single target.
* Convenience convert method that converts the provided source to the first target object supported by this
* converter. Useful when a converter only supports conversion to a single target.
* @param source the source to convert
* @return the converted object
* @throws ConversionException an exception occured converting the source
* value
* @throws ConversionException an exception occured converting the source value
*/
public Object convert(Object source) throws ConversionException {
return convert(source, getTargetClasses()[0], null);
}
/**
* Convenience convert method that converts the provided source to the
* target class specified with an empty conversion context.
* Convenience convert method that converts the provided source to the target class specified with an empty
* conversion context.
* @param source the source to convert
* @param targetClass the target class to convert the source to, must be one
* of the supported <code>targetClasses</code>
* @param targetClass the target class to convert the source to, must be one of the supported
* <code>targetClasses</code>
* @return the converted object
* @throws ConversionException an exception occured converting the source
* value
* @throws ConversionException an exception occured converting the source value
*/
public Object convert(Object source, Class targetClass) throws ConversionException {
return convert(source, targetClass, null);
}
/**
* Convenience convert method that converts the provided source to the first
* target object supported by this converter. Useful when a converter only
* supports conversion to a single target.
* Convenience convert method that converts the provided source to the first target object supported by this
* converter. Useful when a converter only supports conversion to a single target.
* @param source the source to convert
* @param context the conversion context, useful for influencing the
* behavior of the converter
* @param context the conversion context, useful for influencing the behavior of the converter
* @return the converted object
* @throws ConversionException an exception occured converting the source
* value
* @throws ConversionException an exception occured converting the source value
*/
public Object convert(Object source, ConversionContext context) throws ConversionException {
return convert(source, getTargetClasses()[0], context);
@@ -71,11 +65,9 @@ public abstract class AbstractConverter implements Converter {
public Object convert(Object source, Class targetClass, ConversionContext context) throws ConversionException {
try {
return doConvert(source, targetClass, context);
}
catch (ConversionException e) {
} catch (ConversionException e) {
throw e;
}
catch (Throwable e) {
} catch (Throwable e) {
// wrap in a ConversionException
if (targetClass == null) {
targetClass = getTargetClasses()[0];
@@ -85,15 +77,12 @@ public abstract class AbstractConverter implements Converter {
}
/**
* Template method subclasses should override to actually perform the type
* conversion.
* Template method subclasses should override to actually perform the type conversion.
* @param source the source to convert from
* @param targetClass the target type to convert to
* @param context an optional conversion context that may be used to
* influence the conversion process, could be null
* @param context an optional conversion context that may be used to influence the conversion process, could be null
* @return the converted source value
* @throws Exception an exception occured, will be wrapped in a conversion
* exception if necessary
* @throws Exception an exception occured, will be wrapped in a conversion exception if necessary
*/
protected abstract Object doConvert(Object source, Class targetClass, ConversionContext context) throws Exception;

View File

@@ -18,9 +18,8 @@ package org.springframework.binding.convert.support;
import org.springframework.binding.format.FormatterFactory;
/**
* A converter that delegates to a formatter to perform the conversion.
* Formatters are typically not thread safe, so we use a FormatterFactory that
* is expected to provide us with thread-safe instances as necessary.
* A converter that delegates to a formatter to perform the conversion. Formatters are typically not thread safe, so we
* use a FormatterFactory that is expected to provide us with thread-safe instances as necessary.
*
* @author Keith Donald
*/

View File

@@ -25,16 +25,15 @@ import org.springframework.binding.convert.ConversionService;
import org.springframework.util.Assert;
/**
* A conversion service that delegates to an ordered chain of other conversion
* services. The first correct reply received from a conversion service in
* the chain is returned to the caller.
* A conversion service that delegates to an ordered chain of other conversion services. The first correct reply
* received from a conversion service in the chain is returned to the caller.
*
* @author Erwin Vervaet
*/
public class CompositeConversionService implements ConversionService {
private ConversionService[] chain;
/**
* Create a new composite conversion service.
* @param conversionServices the conversion services in the chain
@@ -43,28 +42,24 @@ public class CompositeConversionService implements ConversionService {
Assert.notNull(conversionServices, "The conversion services chain is required");
this.chain = conversionServices;
}
/**
* Returns the conversion services in the chain managed by this
* composite conversion service.
* Returns the conversion services in the chain managed by this composite conversion service.
*/
public ConversionService[] getConversionServices() {
return chain;
}
public ConversionExecutor getConversionExecutor(Class sourceClass, Class targetClass)
throws ConversionException {
public ConversionExecutor getConversionExecutor(Class sourceClass, Class targetClass) throws ConversionException {
for (int i = 0; i < chain.length; i++) {
try {
return chain[i].getConversionExecutor(sourceClass, targetClass);
}
catch (ConversionException e) {
} catch (ConversionException e) {
// ignore and try the next conversion service in the chain
}
}
throw new ConversionException(sourceClass, targetClass,
"No converter registered to convert from sourceClass '" + sourceClass +
"' to target class '" + targetClass + "'");
throw new ConversionException(sourceClass, targetClass, "No converter registered to convert from sourceClass '"
+ sourceClass + "' to target class '" + targetClass + "'");
}
public ConversionExecutor getConversionExecutorByTargetAlias(Class sourceClass, String targetAlias)
@@ -76,29 +71,25 @@ public class CompositeConversionService implements ConversionService {
if (res != null) {
return res;
}
}
catch (ConversionException e) {
} catch (ConversionException e) {
exceptionThrown = true;
}
}
if (exceptionThrown) {
throw new ConversionException(sourceClass,
"No converter registered to convert from sourceClass '" + sourceClass +
"' to aliased target type '" + targetAlias + "'");
}
else {
throw new ConversionException(sourceClass, "No converter registered to convert from sourceClass '"
+ sourceClass + "' to aliased target type '" + targetAlias + "'");
} else {
// alias was not recognized by any conversion service in the chain
return null;
}
}
public ConversionExecutor[] getConversionExecutorsForSource(Class sourceClass)
throws ConversionException {
public ConversionExecutor[] getConversionExecutorsForSource(Class sourceClass) throws ConversionException {
Set executors = new HashSet();
for (int i = 0; i < chain.length; i++) {
executors.addAll(Arrays.asList(chain[i].getConversionExecutorsForSource(sourceClass)));
}
return (ConversionExecutor[])executors.toArray(new ConversionExecutor[executors.size()]);
return (ConversionExecutor[]) executors.toArray(new ConversionExecutor[executors.size()]);
}
public Class getClassByAlias(String alias) throws ConversionException {
@@ -108,8 +99,7 @@ public class CompositeConversionService implements ConversionService {
if (res != null) {
return res;
}
}
catch (ConversionException e) {
} catch (ConversionException e) {
// ignore and try the next conversion service in the chain
}
}

View File

@@ -18,16 +18,14 @@ package org.springframework.binding.convert.support;
import org.springframework.binding.convert.ConversionService;
/**
* Marker interface that denotes an object has a dependency on a conversion
* service that is expected to be fulfilled.
* Marker interface that denotes an object has a dependency on a conversion service that is expected to be fulfilled.
*
* @author Keith Donald
*/
public interface ConversionServiceAware {
/**
* Set the conversion service this object should be made aware of (as it
* presumably depends on it).
* Set the conversion service this object should be made aware of (as it presumably depends on it).
*
* @param conversionService the conversion service
*/

View File

@@ -20,8 +20,7 @@ import org.springframework.binding.convert.ConversionService;
import org.springframework.binding.expression.Expression;
/**
* Base class for converters that use other converters to convert things, thus
* they are conversion-service aware.
* Base class for converters that use other converters to convert things, thus they are conversion-service aware.
*
* @author Keith Donald
*/
@@ -33,8 +32,8 @@ public abstract class ConversionServiceAwareConverter extends AbstractConverter
private ConversionService conversionService;
/**
* Default constructor, expectes to conversion service to be injected
* using {@link #setConversionService(ConversionService)}.
* Default constructor, expectes to conversion service to be injected using
* {@link #setConversionService(ConversionService)}.
*/
protected ConversionServiceAwareConverter() {
}
@@ -61,8 +60,7 @@ public abstract class ConversionServiceAwareConverter extends AbstractConverter
}
/**
* Returns a conversion executor capable of converting string objects to the
* specified target class.
* Returns a conversion executor capable of converting string objects to the specified target class.
* @param targetClass the target class
* @return the conversion executor, never null
*/
@@ -71,19 +69,17 @@ public abstract class ConversionServiceAwareConverter extends AbstractConverter
}
/**
* Returns a conversion executor capable of converting string objects to the
* target class aliased by the provided alias.
* Returns a conversion executor capable of converting string objects to the target class aliased by the provided
* alias.
* @param targetAlias the target class alias, e.g "long" or "float"
* @return the conversion executor, or <code>null</code> if no suitable
* converter exists for alias
* @return the conversion executor, or <code>null</code> if no suitable converter exists for alias
*/
protected ConversionExecutor fromStringToAliased(String targetAlias) {
return getConversionService().getConversionExecutorByTargetAlias(String.class, targetAlias);
}
/**
* Returns a conversion executor capable of converting objects from one
* class to another.
* Returns a conversion executor capable of converting objects from one class to another.
* @param sourceClass the source class to convert from
* @param targetClass the target class to convert to
* @return the conversion executor, never null
@@ -93,12 +89,12 @@ public abstract class ConversionServiceAwareConverter extends AbstractConverter
}
/**
* Helper that parsers the given expression string into an expression, using
* the installed String-&gt;Expression converter.
* Helper that parsers the given expression string into an expression, using the installed String-&gt;Expression
* converter.
* @param expressionString the expression string to parse
* @return the parsed, evaluatable expression
*/
protected Expression parseExpression(String expressionString) {
return (Expression)fromStringTo(Expression.class).execute(expressionString);
return (Expression) fromStringTo(Expression.class).execute(expressionString);
}
}

View File

@@ -23,9 +23,8 @@ import org.springframework.util.Assert;
/**
* Adapts a Converter to the PropertyEditor interface.
* <p>
* Note: with a converter, only forward conversion from-string-to-value is
* supported. Value-to-string conversion is not supported. If you need this
* capability, use a Formatter with a FormatterPropertyEditor adapter.
* Note: with a converter, only forward conversion from-string-to-value is supported. Value-to-string conversion is not
* supported. If you need this capability, use a Formatter with a FormatterPropertyEditor adapter.
*
* @see org.springframework.binding.format.Formatter
* @see org.springframework.binding.format.support.FormatterPropertyEditor

View File

@@ -24,12 +24,10 @@ import org.springframework.binding.convert.ConversionService;
import org.springframework.util.Assert;
/**
* Registers all 'from string' converters known to a conversion service with
* a Spring bean factory.
* Registers all 'from string' converters known to a conversion service with a Spring bean factory.
* <p>
* Acts as bean factory post processor, registering property editor adapters for
* each supported conversion with a <code>java.lang.String sourceClass</code>.
* This makes for very convenient use with the Spring container.
* Acts as bean factory post processor, registering property editor adapters for each supported conversion with a
* <code>java.lang.String sourceClass</code>. This makes for very convenient use with the Spring container.
*
* @author Keith Donald
*/

View File

@@ -22,17 +22,15 @@ import org.springframework.binding.format.support.SimpleFormatterFactory;
import org.springframework.core.enums.LabeledEnum;
/**
* Default, local implementation of a conversion service. Will automatically
* register <i>from string</i> converters for a number of standard Java
* types like Class, Number, Boolean and so on.
* Default, local implementation of a conversion service. Will automatically register <i>from string</i> converters for
* a number of standard Java types like Class, Number, Boolean and so on.
*
* @author Keith Donald
*/
public class DefaultConversionService extends GenericConversionService {
/**
* Creates a new default conversion service, installing the default
* converters.
* Creates a new default conversion service, installing the default converters.
*/
public DefaultConversionService() {
addDefaultConverters();
@@ -46,7 +44,7 @@ public class DefaultConversionService extends GenericConversionService {
addConverter(new TextToNumber(new SimpleFormatterFactory()));
addConverter(new TextToBoolean());
addConverter(new TextToLabeledEnum());
// we're not using addDefaultAlias here for efficiency reasons
addAlias("string", String.class);
addAlias("short", Short.class);

View File

@@ -33,24 +33,21 @@ import org.springframework.util.ClassUtils;
import org.springframework.util.StringUtils;
/**
* Base implementation of a conversion service. Initially empty, e.g. no converters
* are registered by default.
* Base implementation of a conversion service. Initially empty, e.g. no converters are registered by default.
*
* @author Keith Donald
*/
public class GenericConversionService implements ConversionService {
/**
* An indexed map of converters. Each entry key is a source class that can
* be converted from, and each entry value is a map of target classes that
* can be convertered to, ultimately mapping to a specific converter that
* can perform the source->target conversion.
* An indexed map of converters. Each entry key is a source class that can be converted from, and each entry value
* is a map of target classes that can be convertered to, ultimately mapping to a specific converter that can
* perform the source->target conversion.
*/
private Map sourceClassConverters = new HashMap();
/**
* A map of string aliases to convertible classes. Allows lookup of
* converters by alias.
* A map of string aliases to convertible classes. Allows lookup of converters by alias.
*/
private Map aliasMap = new HashMap();
@@ -74,16 +71,15 @@ public class GenericConversionService implements ConversionService {
}
/**
* Add given converter to this conversion service. If the converter is
* {@link ConversionServiceAware}, it will get the conversion service
* injected.
* Add given converter to this conversion service. If the converter is {@link ConversionServiceAware}, it will get
* the conversion service injected.
*/
public void addConverter(Converter converter) {
Class[] sourceClasses = converter.getSourceClasses();
Class[] targetClasses = converter.getTargetClasses();
for (int i = 0; i < sourceClasses.length; i++) {
Class sourceClass = sourceClasses[i];
Map sourceMap = (Map)sourceClassConverters.get(sourceClass);
Map sourceMap = (Map) sourceClassConverters.get(sourceClass);
if (sourceMap == null) {
sourceMap = new HashMap();
sourceClassConverters.put(sourceClass, sourceMap);
@@ -94,14 +90,13 @@ public class GenericConversionService implements ConversionService {
}
}
if (converter instanceof ConversionServiceAware) {
((ConversionServiceAware)converter).setConversionService(this);
((ConversionServiceAware) converter).setConversionService(this);
}
}
/**
* Add all given converters. If the converters are
* {@link ConversionServiceAware}, they will get the conversion service
* injected.
* Add all given converters. If the converters are {@link ConversionServiceAware}, they will get the conversion
* service injected.
*/
public void addConverters(Converter[] converters) {
for (int i = 0; i < converters.length; i++) {
@@ -110,9 +105,8 @@ public class GenericConversionService implements ConversionService {
}
/**
* Add given converter with an alias to the conversion service. If the
* converter is {@link ConversionServiceAware}, it will get the conversion
* service injected.
* Add given converter with an alias to the conversion service. If the converter is {@link ConversionServiceAware},
* it will get the conversion service injected.
*/
public void addConverter(Converter converter, String alias) {
aliasMap.put(alias, converter);
@@ -127,8 +121,8 @@ public class GenericConversionService implements ConversionService {
}
/**
* Generate a conventions based alias for given target type. For instance,
* "java.lang.Boolean" will get the "boolean" alias.
* Generate a conventions based alias for given target type. For instance, "java.lang.Boolean" will get the
* "boolean" alias.
*/
public void addDefaultAlias(Class targetType) {
addAlias(StringUtils.uncapitalize(ClassUtils.getShortName(targetType)), targetType);
@@ -148,16 +142,14 @@ public class GenericConversionService implements ConversionService {
if (converter != null) {
// we found a converter
return new ConversionExecutor(sourceClass, targetClass, converter);
}
else {
} else {
if (parent != null) {
// try the parent
return parent.getConversionExecutor(sourceClass, targetClass);
}
else {
} else {
throw new ConversionException(sourceClass, targetClass,
"No converter registered to convert from sourceClass '" + sourceClass +
"' to target class '" + targetClass + "'");
"No converter registered to convert from sourceClass '" + sourceClass + "' to target class '"
+ targetClass + "'");
}
}
}
@@ -172,18 +164,15 @@ public class GenericConversionService implements ConversionService {
if (parent != null) {
// try the parent
return parent.getConversionExecutorByTargetAlias(sourceClass, alias);
}
else {
} else {
// not aliased
return null;
}
}
else if (targetType instanceof Class) {
return getConversionExecutor(sourceClass, (Class)targetType);
}
else {
} else if (targetType instanceof Class) {
return getConversionExecutor(sourceClass, (Class) targetType);
} else {
Assert.isInstanceOf(Converter.class, targetType, "Not a converter: ");
Converter conv = (Converter)targetType;
Converter conv = (Converter) targetType;
return new ConversionExecutor(sourceClass, Object.class, conv);
}
}
@@ -195,23 +184,22 @@ public class GenericConversionService implements ConversionService {
if (parent != null) {
// use the parent
return parent.getConversionExecutorsForSource(sourceClass);
}
else {
} else {
// no converters for source class
return new ConversionExecutor[0];
}
}
else {
} else {
Set executors = new HashSet();
if (parent != null) {
executors.addAll(Arrays.asList(parent.getConversionExecutorsForSource(sourceClass)));
}
Iterator it = sourceTargetConverters.entrySet().iterator();
while (it.hasNext()) {
Map.Entry entry = (Map.Entry)it.next();
executors.add(new ConversionExecutor(sourceClass, (Class)entry.getKey(), (Converter)entry.getValue()));
Map.Entry entry = (Map.Entry) it.next();
executors
.add(new ConversionExecutor(sourceClass, (Class) entry.getKey(), (Converter) entry.getValue()));
}
return (ConversionExecutor[])executors.toArray(new ConversionExecutor[executors.size()]);
return (ConversionExecutor[]) executors.toArray(new ConversionExecutor[executors.size()]);
}
}
@@ -220,28 +208,26 @@ public class GenericConversionService implements ConversionService {
Object clazz = aliasMap.get(alias);
if (clazz != null) {
Assert.isInstanceOf(Class.class, clazz, "Not a Class alias '" + alias + "': ");
return (Class)clazz;
}
else {
return (Class) clazz;
} else {
if (parent != null) {
// try parent service
return parent.getClassByAlias(alias);
}
else {
// try parent service
return parent.getClassByAlias(alias);
} else {
// alias does not index a class, return null
return null;
}
}
}
// internal helpers
private Map findConvertersForSource(Class sourceClass) {
LinkedList classQueue = new LinkedList();
classQueue.addFirst(sourceClass);
while (!classQueue.isEmpty()) {
sourceClass = (Class)classQueue.removeLast();
Map sourceTargetConverters = (Map)sourceClassConverters.get(sourceClass);
sourceClass = (Class) classQueue.removeLast();
Map sourceTargetConverters = (Map) sourceClassConverters.get(sourceClass);
if (sourceTargetConverters != null && !sourceTargetConverters.isEmpty()) {
return sourceTargetConverters;
}
@@ -261,8 +247,8 @@ public class GenericConversionService implements ConversionService {
LinkedList classQueue = new LinkedList();
classQueue.addFirst(targetClass);
while (!classQueue.isEmpty()) {
targetClass = (Class)classQueue.removeLast();
Converter converter = (Converter)sourceTargetConverters.get(targetClass);
targetClass = (Class) classQueue.removeLast();
Converter converter = (Converter) sourceTargetConverters.get(targetClass);
if (converter != null) {
return converter;
}
@@ -277,13 +263,12 @@ public class GenericConversionService implements ConversionService {
}
return null;
}
// subclassing support
/**
* Returns an indexed map of converters. Each entry key is a source class that
* can be converted from, and each entry value is a map of target classes that
* can be convertered to, ultimately mapping to a specific converter that can
* Returns an indexed map of converters. Each entry key is a source class that can be converted from, and each entry
* value is a map of target classes that can be convertered to, ultimately mapping to a specific converter that can
* perform the source->target conversion.
*/
protected Map getSourceClassConverters() {
@@ -291,8 +276,8 @@ public class GenericConversionService implements ConversionService {
}
/**
* Returns a map of known aliases. Each entry key is a String alias and the
* associated value is either a target class or a converter.
* Returns a map of known aliases. Each entry key is a String alias and the associated value is either a target
* class or a converter.
*/
protected Map getAliasMap() {
return aliasMap;

View File

@@ -19,8 +19,7 @@ import org.springframework.binding.convert.ConversionContext;
import org.springframework.util.StringUtils;
/**
* Converts a textual representation of a boolean object to a <code>Boolean</code>
* instance.
* Converts a textual representation of a boolean object to a <code>Boolean</code> instance.
*
* @author Keith Donald
*/
@@ -54,8 +53,8 @@ public class TextToBoolean extends AbstractConverter {
}
/**
* Create a text to boolean converter. Take given <i>special</i> string representations
* of true and false into account.
* Create a text to boolean converter. Take given <i>special</i> string representations of true and false into
* account.
* @param trueString special true string to consider
* @param falseString special false string to consider
*/
@@ -73,27 +72,22 @@ public class TextToBoolean extends AbstractConverter {
}
protected Object doConvert(Object source, Class targetClass, ConversionContext context) throws Exception {
String text = (String)source;
String text = (String) source;
if (!StringUtils.hasText(text)) {
return null;
}
else if (this.trueString != null && text.equalsIgnoreCase(this.trueString)) {
} else if (this.trueString != null && text.equalsIgnoreCase(this.trueString)) {
return Boolean.TRUE;
}
else if (this.falseString != null && text.equalsIgnoreCase(this.falseString)) {
} else if (this.falseString != null && text.equalsIgnoreCase(this.falseString)) {
return Boolean.FALSE;
}
else if (this.trueString == null
} else if (this.trueString == null
&& (text.equalsIgnoreCase(VALUE_TRUE) || text.equalsIgnoreCase(VALUE_ON)
|| text.equalsIgnoreCase(VALUE_YES) || text.equals(VALUE_1))) {
return Boolean.TRUE;
}
else if (this.falseString == null
} else if (this.falseString == null
&& (text.equalsIgnoreCase(VALUE_FALSE) || text.equalsIgnoreCase(VALUE_OFF)
|| text.equalsIgnoreCase(VALUE_NO) || text.equals(VALUE_0))) {
return Boolean.FALSE;
}
else {
} else {
throw new IllegalArgumentException("Invalid boolean value [" + text + "]");
}
}

View File

@@ -21,8 +21,7 @@ import org.springframework.util.ClassUtils;
import org.springframework.util.StringUtils;
/**
* Converts a textual representation of a class object to a <code>Class</code>
* instance.
* Converts a textual representation of a class object to a <code>Class</code> instance.
*
* @author Keith Donald
*/
@@ -41,19 +40,17 @@ public class TextToClass extends ConversionServiceAwareConverter {
}
protected Object doConvert(Object source, Class targetClass, ConversionContext context) throws Exception {
String text = (String)source;
String text = (String) source;
if (StringUtils.hasText(text)) {
String classNameOrAlias = text.trim();
if (classNameOrAlias.startsWith(CLASS_PREFIX)) {
return ClassUtils.forName(text.substring(CLASS_PREFIX.length()));
}
else if (classNameOrAlias.startsWith(ALIAS_PREFIX)) {
} else if (classNameOrAlias.startsWith(ALIAS_PREFIX)) {
String alias = text.substring(ALIAS_PREFIX.length());
Class clazz = getConversionService().getClassByAlias(alias);
Assert.notNull(clazz, "No class found associated with type alias '" + alias + "'");
return clazz;
}
else {
} else {
// try first an aliased based lookup
if (getConversionService() != null) {
Class aliasedClass = getConversionService().getClassByAlias(classNameOrAlias);
@@ -64,8 +61,7 @@ public class TextToClass extends ConversionServiceAwareConverter {
// treat as a class name
return ClassUtils.forName(classNameOrAlias);
}
}
else {
} else {
return null;
}
}

View File

@@ -62,11 +62,10 @@ public class TextToExpression extends AbstractConverter {
}
protected Object doConvert(Object source, Class targetClass, ConversionContext context) throws Exception {
String expressionString = (String)source;
String expressionString = (String) source;
if (getExpressionParser().isDelimitedExpression(expressionString)) {
return getExpressionParser().parseExpression((String)source);
}
else {
return getExpressionParser().parseExpression((String) source);
} else {
return new StaticExpression(expressionString);
}
}

View File

@@ -20,8 +20,7 @@ import org.springframework.binding.format.support.LabeledEnumFormatter;
import org.springframework.core.enums.LabeledEnum;
/**
* Converter that converts textual representations of enum
* instances to a specific instance of <code>LabeledEnum</code>.
* Converter that converts textual representations of enum instances to a specific instance of <code>LabeledEnum</code>.
*
* @author Keith Donald
*/
@@ -38,6 +37,6 @@ public class TextToLabeledEnum extends AbstractConverter {
}
protected Object doConvert(Object source, Class targetClass, ConversionContext context) throws Exception {
return labeledEnumFormatter.parseValue((String)source, targetClass);
return labeledEnumFormatter.parseValue((String) source, targetClass);
}
}

View File

@@ -23,8 +23,8 @@ import org.springframework.binding.format.FormatterFactory;
import org.springframework.binding.format.support.SimpleFormatterFactory;
/**
* Converts textual representations of numbers to a <code>Number</code>
* specialization. Delegates to a synchronized formatter to parse text strings.
* Converts textual representations of numbers to a <code>Number</code> specialization. Delegates to a synchronized
* formatter to parse text strings.
*
* @author Keith Donald
*/
@@ -55,6 +55,6 @@ public class TextToNumber extends AbstractFormattingConverter {
}
protected Object doConvert(Object source, Class targetClass, ConversionContext context) throws Exception {
return getFormatterFactory().getNumberFormatter(targetClass).parseValue((String)source, targetClass);
return getFormatterFactory().getNumberFormatter(targetClass).parseValue((String) source, targetClass);
}
}

View File

@@ -77,7 +77,6 @@ public class EvaluationAttempt {
}
protected ToStringCreator createToString(ToStringCreator creator) {
return creator.append("expression", expression).append("target", target).append("context",
context);
return creator.append("expression", expression).append("target", target).append("context", context);
}
}

View File

@@ -20,10 +20,8 @@ import java.util.Map;
/**
* A context object with two main responsibities:
* <ol>
* <li>Exposing information to an expression to influence
* an evaluation attempt.
* <li>Providing operations for recording progress or
* errors during the expression evaluation process.
* <li>Exposing information to an expression to influence an evaluation attempt.
* <li>Providing operations for recording progress or errors during the expression evaluation process.
* </ol>
*
* @author Keith Donald

View File

@@ -25,8 +25,7 @@ import org.springframework.core.NestedRuntimeException;
public class EvaluationException extends NestedRuntimeException {
/**
* The evaluation attempt that failed.
* Transient because an EvaluationAttempt is not serializable.
* The evaluation attempt that failed. Transient because an EvaluationAttempt is not serializable.
*/
private transient EvaluationAttempt evaluationAttempt;

View File

@@ -16,17 +16,16 @@
package org.springframework.binding.expression;
/**
* Evaluates a single parsed expression on the provided input object in the
* specified context. This provides a common abstraction for expression
* evaluation independent of any language like OGNL or Spring's BeanWrapper.
* Evaluates a single parsed expression on the provided input object in the specified context. This provides a common
* abstraction for expression evaluation independent of any language like OGNL or Spring's BeanWrapper.
*
* @author Keith Donald
*/
public interface Expression {
/**
* Evaluate the expression encapsulated by this evaluator against the
* provided target object and return the result of the evaluation.
* Evaluate the expression encapsulated by this evaluator against the provided target object and return the result
* of the evaluation.
* @param target the target of the expression
* @param context the expression evaluation context
* @return the evaluation result

View File

@@ -16,24 +16,23 @@
package org.springframework.binding.expression;
/**
* Parses expression strings, returing a configured evaluator instance capable
* of performing parsed expression evaluation in a thread safe way.
* Parses expression strings, returing a configured evaluator instance capable of performing parsed expression
* evaluation in a thread safe way.
*
* @author Keith Donald
*/
public interface ExpressionParser {
/**
* Is this expression string delimited in a manner that indicates it is a
* parseable expression? For example "${expression}".
* Is this expression string delimited in a manner that indicates it is a parseable expression? For example
* "${expression}".
* @param expressionString the proposed expression string
* @return true if yes, false if not
*/
public boolean isDelimitedExpression(String expressionString);
/**
* Parse the provided expression string, returning an evaluator capable of
* evaluating it against input.
* Parse the provided expression string, returning an evaluator capable of evaluating it against input.
* @param expressionString the parseable expression string
* @return the evaluator for the parsed expression
* @throws ParserException an exception occured during parsing
@@ -41,13 +40,12 @@ public interface ExpressionParser {
public Expression parseExpression(String expressionString) throws ParserException;
/**
* Parse the provided settable expression string, returning an evaluator
* capable of evaluating its value as well as setting its value.
* Parse the provided settable expression string, returning an evaluator capable of evaluating its value as well as
* setting its value.
* @param expressionString the parseable expression string
* @return the evaluator for the parsed expression
* @throws ParserException an exception occured during parsing
* @throws UnsupportedOperationException this parser does not support
* settable expressions
* @throws UnsupportedOperationException this parser does not support settable expressions
*/
public SettableExpression parseSettableExpression(String expressionString) throws ParserException,
UnsupportedOperationException;

View File

@@ -25,7 +25,7 @@ import org.springframework.core.style.ToStringCreator;
public class SetValueAttempt extends EvaluationAttempt {
/**
* The new value.
* The new value.
*/
private Object value;

View File

@@ -16,16 +16,14 @@
package org.springframework.binding.expression;
/**
* An evaluator that is capable of setting a value on a target object at the
* path defined by this expression.
* An evaluator that is capable of setting a value on a target object at the path defined by this expression.
*
* @author Keith Donald
*/
public interface SettableExpression extends Expression {
/**
* Evaluate this expression against the target object to set its value to
* the value provided.
* Evaluate this expression against the target object to set its value to the value provided.
* @param target the target object
* @param value the new value to be set
* @param context the evaluation context

View File

@@ -12,43 +12,43 @@ import javax.el.VariableMapper;
*/
public class DefaultELContextFactory implements ELContextFactory {
/**
* Configures and returns a simple EL context to use to parse EL expressions.
* @return The configured simple ELContext instance.
*/
public ELContext getParseContext() {
return new SimpleELContext();
}
/**
* Configures and returns a simple EL context to use to evaluate EL expressions on the given base target object.
* @return The configured simple ELContext instance.
*/
public ELContext getEvaluationContext(Object target) {
return new SimpleELContext(target);
}
private static class SimpleELContext extends ELContext {
private DefaultELResolver resolver = new DefaultELResolver();
public SimpleELContext() {
/**
* Configures and returns a simple EL context to use to parse EL expressions.
* @return The configured simple ELContext instance.
*/
public ELContext getParseContext() {
return new SimpleELContext();
}
public SimpleELContext(Object target) {
this.resolver.setTarget(target);
/**
* Configures and returns a simple EL context to use to evaluate EL expressions on the given base target object.
* @return The configured simple ELContext instance.
*/
public ELContext getEvaluationContext(Object target) {
return new SimpleELContext(target);
}
public ELResolver getELResolver() {
return resolver;
}
private static class SimpleELContext extends ELContext {
private DefaultELResolver resolver = new DefaultELResolver();
public FunctionMapper getFunctionMapper() {
return null;
}
public SimpleELContext() {
public VariableMapper getVariableMapper() {
return null;
}
public SimpleELContext(Object target) {
this.resolver.setTarget(target);
}
public ELResolver getELResolver() {
return resolver;
}
public FunctionMapper getFunctionMapper() {
return null;
}
public VariableMapper getVariableMapper() {
return null;
}
}
}
}

View File

@@ -24,56 +24,56 @@ import org.springframework.util.Assert;
*/
public class DefaultELResolver extends CompositeELResolver {
private Object target;
private Object target;
public DefaultELResolver() {
configureResolvers();
}
public Class getType(ELContext context, Object base, Object property) {
return super.getType(context, adaptIfNecessary(base), property);
}
public Object getValue(ELContext context, Object base, Object property) {
Assert.notNull(target, "The DefaultELResolver must have a target base property set.");
if (base == null) {
return super.getValue(context, target, property);
} else {
return super.getValue(context, adaptIfNecessary(base), property);
public DefaultELResolver() {
configureResolvers();
}
}
public void setValue(ELContext context, Object base, Object property, Object val) {
Assert.notNull(target, "The DefaultELResolver must have a target base property set.");
if (base == null) {
super.setValue(context, target, property, val);
} else {
super.setValue(context, adaptIfNecessary(base), property, val);
public Class getType(ELContext context, Object base, Object property) {
return super.getType(context, adaptIfNecessary(base), property);
}
}
public Object getTarget() {
return target;
}
public void setTarget(Object target) {
this.target = adaptIfNecessary(target);
}
private Object adaptIfNecessary(Object base) {
if (base instanceof MapAdaptable) {
return ((MapAdaptable) base).asMap();
} else {
return base;
public Object getValue(ELContext context, Object base, Object property) {
Assert.notNull(target, "The DefaultELResolver must have a target base property set.");
if (base == null) {
return super.getValue(context, target, property);
} else {
return super.getValue(context, adaptIfNecessary(base), property);
}
}
}
private void configureResolvers() {
add(new ArrayELResolver());
add(new ListELResolver());
add(new MapELResolver());
add(new ResourceBundleELResolver());
add(new BeanELResolver());
}
public void setValue(ELContext context, Object base, Object property, Object val) {
Assert.notNull(target, "The DefaultELResolver must have a target base property set.");
if (base == null) {
super.setValue(context, target, property, val);
} else {
super.setValue(context, adaptIfNecessary(base), property, val);
}
}
public Object getTarget() {
return target;
}
public void setTarget(Object target) {
this.target = adaptIfNecessary(target);
}
private Object adaptIfNecessary(Object base) {
if (base instanceof MapAdaptable) {
return ((MapAdaptable) base).asMap();
} else {
return base;
}
}
private void configureResolvers() {
add(new ArrayELResolver());
add(new ListELResolver());
add(new MapELResolver());
add(new ResourceBundleELResolver());
add(new BeanELResolver());
}
}

View File

@@ -10,19 +10,19 @@ import javax.el.ELResolver;
*/
public interface ELContextFactory {
/**
* Configures and returns an {@link ELContext} to be used in parsing EL expressions.
* @return ELContext The configured ELContext instance for parsing expressions.
*/
public ELContext getParseContext();
/**
* Configures and returns an {@link ELContext} to be used in parsing EL expressions.
* @return ELContext The configured ELContext instance for parsing expressions.
*/
public ELContext getParseContext();
/**
* Configures and returns an {@link ELContext} to be used in evaluating EL expressions on the given base target
* object. In certain environments the target will be null and the base object of the expression is expected to be
* resolved via the ELContext's {@link ELResolver} chain.
* @param target The base object for the expression evaluation.
* @return ELContext The configured ELContext instance for evaluating expressions.
*/
public ELContext getEvaluationContext(Object target);
/**
* Configures and returns an {@link ELContext} to be used in evaluating EL expressions on the given base target
* object. In certain environments the target will be null and the base object of the expression is expected to be
* resolved via the ELContext's {@link ELResolver} chain.
* @param target The base object for the expression evaluation.
* @return ELContext The configured ELContext instance for evaluating expressions.
*/
public ELContext getEvaluationContext(Object target);
}

View File

@@ -16,67 +16,67 @@ import org.springframework.binding.expression.SettableExpression;
*/
public class ELExpression implements SettableExpression {
private ELContextFactory factory;
private ELContextFactory factory;
private ValueExpression expression;
private ValueExpression expression;
public ELExpression(ELContextFactory factory, ValueExpression expression) {
this.factory = factory;
this.expression = expression;
}
public void evaluateToSet(Object target, Object value, EvaluationContext context) throws EvaluationException {
ELContext ctx = getELContext(target);
try {
expression.setValue(ctx, value);
} catch (ELException ex) {
throw new EvaluationException(new EvaluationAttempt(this, target, context), ex);
public ELExpression(ELContextFactory factory, ValueExpression expression) {
this.factory = factory;
this.expression = expression;
}
}
public Object evaluate(Object target, EvaluationContext context) throws EvaluationException {
ELContext ctx = getELContext(target);
try {
return expression.getValue(ctx);
} catch (ELException ex) {
throw new EvaluationException(new EvaluationAttempt(this, target, context), ex);
public void evaluateToSet(Object target, Object value, EvaluationContext context) throws EvaluationException {
ELContext ctx = getELContext(target);
try {
expression.setValue(ctx, value);
} catch (ELException ex) {
throw new EvaluationException(new EvaluationAttempt(this, target, context), ex);
}
}
}
protected Class getType(Object target, EvaluationContext context) throws EvaluationException {
ELContext ctx = getELContext(target);
try {
return expression.getType(ctx);
} catch (ELException ex) {
throw new EvaluationException(new EvaluationAttempt(this, target, context), ex);
public Object evaluate(Object target, EvaluationContext context) throws EvaluationException {
ELContext ctx = getELContext(target);
try {
return expression.getValue(ctx);
} catch (ELException ex) {
throw new EvaluationException(new EvaluationAttempt(this, target, context), ex);
}
}
}
/**
* Retrieves an {@link ELContext} instance, configured with a DefaultELResolver if no other resolvers have been
* configured.
*
* @return {@link ELContext} The thread-bound {@link ELContext} instance.
*/
protected ELContext getELContext(Object target) {
ELContext ctx = factory.getEvaluationContext(target);
return ctx;
}
public int hashCode() {
return expression.hashCode();
}
public boolean equals(Object o) {
if (!(o instanceof ELExpression)) {
return false;
protected Class getType(Object target, EvaluationContext context) throws EvaluationException {
ELContext ctx = getELContext(target);
try {
return expression.getType(ctx);
} catch (ELException ex) {
throw new EvaluationException(new EvaluationAttempt(this, target, context), ex);
}
}
ELExpression other = (ELExpression) o;
return expression.equals(other.expression);
}
public String toString() {
return expression.getExpressionString();
}
/**
* Retrieves an {@link ELContext} instance, configured with a DefaultELResolver if no other resolvers have been
* configured.
*
* @return {@link ELContext} The thread-bound {@link ELContext} instance.
*/
protected ELContext getELContext(Object target) {
ELContext ctx = factory.getEvaluationContext(target);
return ctx;
}
public int hashCode() {
return expression.hashCode();
}
public boolean equals(Object o) {
if (!(o instanceof ELExpression)) {
return false;
}
ELExpression other = (ELExpression) o;
return expression.equals(other.expression);
}
public String toString() {
return expression.getExpressionString();
}
}

View File

@@ -15,110 +15,110 @@ import org.springframework.binding.expression.SettableExpression;
*/
public class ELExpressionParser implements ExpressionParser {
/**
* The expression prefix for deferred EL expressions.
*/
private static final String DEFERRED_EL_EXPRESSION_PREFIX = "#{";
/**
* The expression prefix for deferred EL expressions.
*/
private static final String DEFERRED_EL_EXPRESSION_PREFIX = "#{";
/**
* The expression suffix for deferred EL expressions.
*/
private static final String DEFERRED_EL_EXPRESSION_SUFFIX = "}";
/**
* The expression suffix for deferred EL expressions.
*/
private static final String DEFERRED_EL_EXPRESSION_SUFFIX = "}";
/**
* The marked expression delimiter prefix.
*/
private String expressionPrefix = DEFERRED_EL_EXPRESSION_PREFIX;
/**
* The marked expression delimiter prefix.
*/
private String expressionPrefix = DEFERRED_EL_EXPRESSION_PREFIX;
/**
* The marked expression delimiter suffix.
*/
private String expressionSuffix = DEFERRED_EL_EXPRESSION_SUFFIX;
/**
* The marked expression delimiter suffix.
*/
private String expressionSuffix = DEFERRED_EL_EXPRESSION_SUFFIX;
/**
* The {@link ELContextFactory} for retrieving a configured ELContext.
*/
private ELContextFactory contextFactory;
/**
* The {@link ELContextFactory} for retrieving a configured ELContext.
*/
private ELContextFactory contextFactory;
/**
* The ExpressionFactory for constructing EL expressions
*/
private ExpressionFactory expressionFactory;
/**
* The ExpressionFactory for constructing EL expressions
*/
private ExpressionFactory expressionFactory;
/**
* Creates a new EL expression parser for standalone usage.
*/
public ELExpressionParser(ExpressionFactory expressionFactory) {
this.expressionFactory = expressionFactory;
this.contextFactory = new DefaultELContextFactory();
}
/**
* Creates a new EL expression parser with a custom context factory for a specific environment.
*
* @param contextFactory the context factory
*/
public ELExpressionParser(ExpressionFactory expressionFactory, ELContextFactory contextFactory) {
this.expressionFactory = expressionFactory;
this.contextFactory = contextFactory;
}
/**
* Check whether or not given criteria are expressed as an expression.
*/
public boolean isDelimitedExpression(String expressionString) {
int prefixIndex = expressionString.indexOf(expressionPrefix);
if (prefixIndex == -1) {
return false;
/**
* Creates a new EL expression parser for standalone usage.
*/
public ELExpressionParser(ExpressionFactory expressionFactory) {
this.expressionFactory = expressionFactory;
this.contextFactory = new DefaultELContextFactory();
}
int suffixIndex = expressionString.indexOf(expressionSuffix, prefixIndex);
if (suffixIndex == -1) {
return false;
} else {
if (suffixIndex == prefixIndex + expressionPrefix.length()) {
return false;
} else {
return true;
}
}
}
public final Expression parseExpression(String expressionString) throws ParserException {
if (!isDelimitedExpression(expressionString)) {
expressionString = expressionPrefix + expressionString + expressionSuffix;
/**
* Creates a new EL expression parser with a custom context factory for a specific environment.
*
* @param contextFactory the context factory
*/
public ELExpressionParser(ExpressionFactory expressionFactory, ELContextFactory contextFactory) {
this.expressionFactory = expressionFactory;
this.contextFactory = contextFactory;
}
return doParseExpression(expressionString);
}
public final SettableExpression parseSettableExpression(String expressionString) throws ParserException,
UnsupportedOperationException {
if (!isDelimitedExpression(expressionString)) {
expressionString = expressionPrefix + expressionString + expressionSuffix;
/**
* Check whether or not given criteria are expressed as an expression.
*/
public boolean isDelimitedExpression(String expressionString) {
int prefixIndex = expressionString.indexOf(expressionPrefix);
if (prefixIndex == -1) {
return false;
}
int suffixIndex = expressionString.indexOf(expressionSuffix, prefixIndex);
if (suffixIndex == -1) {
return false;
} else {
if (suffixIndex == prefixIndex + expressionPrefix.length()) {
return false;
} else {
return true;
}
}
}
return doParseSettableExpression(expressionString);
}
/**
* Parses the expression string into an EL value expression.
* @param expressionString
* @throws ParserException
*/
protected Expression doParseExpression(String expressionString) throws ParserException {
return doParseSettableExpression(expressionString);
}
/**
* Parses the expression string into an EL value expression.
* @param expressionString
* @throws ParserException
*/
protected SettableExpression doParseSettableExpression(String expressionString) throws ParserException {
ELContext ctx = contextFactory.getParseContext();
try {
return new ELExpression(contextFactory, expressionFactory.createValueExpression(ctx, expressionString,
Object.class));
} catch (ELException ex) {
throw new ParserException(expressionString, ex);
public final Expression parseExpression(String expressionString) throws ParserException {
if (!isDelimitedExpression(expressionString)) {
expressionString = expressionPrefix + expressionString + expressionSuffix;
}
return doParseExpression(expressionString);
}
public final SettableExpression parseSettableExpression(String expressionString) throws ParserException,
UnsupportedOperationException {
if (!isDelimitedExpression(expressionString)) {
expressionString = expressionPrefix + expressionString + expressionSuffix;
}
return doParseSettableExpression(expressionString);
}
/**
* Parses the expression string into an EL value expression.
* @param expressionString
* @throws ParserException
*/
protected Expression doParseExpression(String expressionString) throws ParserException {
return doParseSettableExpression(expressionString);
}
/**
* Parses the expression string into an EL value expression.
* @param expressionString
* @throws ParserException
*/
protected SettableExpression doParseSettableExpression(String expressionString) throws ParserException {
ELContext ctx = contextFactory.getParseContext();
try {
return new ELExpression(contextFactory, expressionFactory.createValueExpression(ctx, expressionString,
Object.class));
} catch (ELException ex) {
throw new ParserException(expressionString, ex);
}
}
}
}

View File

@@ -31,9 +31,8 @@ import org.springframework.util.Assert;
/**
* Evaluates a parsed Ognl expression.
* <p>
* IMPLEMENTATION NOTE: Ognl 2.6.7 expression objects do not respect equality
* properly, so the equality operations defined within this class do not
* function properly.
* IMPLEMENTATION NOTE: Ognl 2.6.7 expression objects do not respect equality properly, so the equality operations
* defined within this class do not function properly.
*
* @author Keith Donald
*/
@@ -71,14 +70,12 @@ class OgnlExpression implements SettableExpression {
Map contextAttributes = (context != null ? context.getAttributes() : Collections.EMPTY_MAP);
try {
return Ognl.getValue(expression, contextAttributes, target);
}
catch (OgnlException e) {
} catch (OgnlException e) {
if (e.getReason() != null && e.getReason() != e) {
// unwrap the OgnlException since the actual exception is wrapped inside it
// and there is not generic (getCause) way to get to it later on
throw new EvaluationException(new EvaluationAttempt(this, target, context), e.getReason());
}
else {
} else {
throw new EvaluationException(new EvaluationAttempt(this, target, context), e);
}
}
@@ -89,8 +86,7 @@ class OgnlExpression implements SettableExpression {
Map contextAttributes = (context != null ? context.getAttributes() : Collections.EMPTY_MAP);
try {
Ognl.setValue(expression, contextAttributes, target, value);
}
catch (OgnlException e) {
} catch (OgnlException e) {
throw new EvaluationException(new SetValueAttempt(this, target, value, context), e);
}
}

View File

@@ -39,8 +39,7 @@ public class OgnlExpressionParser extends AbstractExpressionParser {
public SettableExpression doParseSettableExpression(String expressionString) throws ParserException {
try {
return new OgnlExpression(Ognl.parseExpression(expressionString));
}
catch (OgnlException e) {
} catch (OgnlException e) {
throw new ParserException(expressionString, e);
}
}

View File

@@ -91,12 +91,10 @@ public abstract class AbstractExpressionParser implements ExpressionParser {
int suffixIndex = expressionString.indexOf(getExpressionSuffix(), prefixIndex);
if (suffixIndex == -1) {
return false;
}
else {
} else {
if (suffixIndex == prefixIndex + getExpressionPrefix().length()) {
return false;
}
else {
} else {
return true;
}
}
@@ -106,30 +104,27 @@ public abstract class AbstractExpressionParser implements ExpressionParser {
Expression[] expressions = parseExpressions(expressionString);
if (expressions.length == 1) {
return expressions[0];
}
else {
} else {
return new CompositeStringExpression(expressions);
}
}
public final SettableExpression parseSettableExpression(String expressionString)
throws ParserException, UnsupportedOperationException {
public final SettableExpression parseSettableExpression(String expressionString) throws ParserException,
UnsupportedOperationException {
expressionString = expressionString.trim();
// a settable expression should just be a single expression
if (expressionString.startsWith(getExpressionPrefix()) && expressionString.endsWith(getExpressionSuffix())) {
expressionString = expressionString.substring(getExpressionPrefix().length(),
expressionString.length() - getExpressionSuffix().length());
expressionString = expressionString.substring(getExpressionPrefix().length(), expressionString.length()
- getExpressionSuffix().length());
}
return doParseSettableExpression(expressionString);
}
/**
* Helper that parses given expression string using the configured parser.
* The expression string can contain any number of expressions all contained
* in "${...}" markers. For instance: "foo${expr0}bar${expr1}". The static
* pieces of text will also be returned as Expressions that just return that
* static piece of text. As a result, evaluating all returned expressions
* and concatenating the results produces the complete evaluated string.
* Helper that parses given expression string using the configured parser. The expression string can contain any
* number of expressions all contained in "${...}" markers. For instance: "foo${expr0}bar${expr1}". The static
* pieces of text will also be returned as Expressions that just return that static piece of text. As a result,
* evaluating all returned expressions and concatenating the results produces the complete evaluated string.
* @param expressionString the expression string
* @return the parsed expressions
* @throws ParserException when the expressions cannot be parsed
@@ -146,74 +141,64 @@ public abstract class AbstractExpressionParser implements ExpressionParser {
expressions.add(new StaticExpression(expressionString.substring(startIdx, prefixIndex)));
startIdx = prefixIndex;
}
int nextPrefixIndex = expressionString.indexOf(getExpressionPrefix(),
prefixIndex + getExpressionPrefix().length());
int nextPrefixIndex = expressionString.indexOf(getExpressionPrefix(), prefixIndex
+ getExpressionPrefix().length());
int suffixIndex;
if (nextPrefixIndex == -1) {
if (nextPrefixIndex == -1) {
// this is the last expression in the expression string
suffixIndex = expressionString.lastIndexOf(getExpressionSuffix());
}
else {
suffixIndex = expressionString.lastIndexOf(getExpressionSuffix());
} else {
// another expression exists after this one in the expression string
suffixIndex = expressionString.lastIndexOf(getExpressionSuffix(), nextPrefixIndex);
}
suffixIndex = expressionString.lastIndexOf(getExpressionSuffix(), nextPrefixIndex);
}
if (suffixIndex < (prefixIndex + getExpressionPrefix().length())) {
throw new ParserException(expressionString, "No ending suffix '" + getExpressionSuffix()
+ "' for expression starting at character " + prefixIndex + ": "
+ expressionString.substring(prefixIndex), null);
}
else if (suffixIndex == prefixIndex + getExpressionPrefix().length()) {
} else if (suffixIndex == prefixIndex + getExpressionPrefix().length()) {
throw new ParserException(expressionString, "No expression defined within delimiter '"
+ getExpressionPrefix() + getExpressionSuffix() + "' at character " + prefixIndex,
null);
}
else {
+ getExpressionPrefix() + getExpressionSuffix() + "' at character " + prefixIndex, null);
} else {
String expr = expressionString.substring(prefixIndex + getExpressionPrefix().length(),
suffixIndex);
expressions.add(doParseExpression(expr));
startIdx = suffixIndex + 1;
}
}
else {
} else {
if (startIdx == 0) {
// treat entire string as one expression
expressions.add(doParseExpression(expressionString));
}
else {
} else {
// no more ${expressions} found in string
expressions.add(new StaticExpression(expressionString.substring(startIdx)));
}
startIdx = expressionString.length();
}
}
}
else {
} else {
expressions.add(new StaticExpression(expressionString));
}
return (Expression[]) expressions.toArray(new Expression[expressions.size()]);
}
// template methods
/**
* Template method for parsing a filtered expression string. Subclasses should
* override.
* Template method for parsing a filtered expression string. Subclasses should override.
* @param expressionString the expression string
* @return the parsed expression
* @throws ParserException an exception occured during parsing
*/
protected abstract Expression doParseExpression(String expressionString) throws ParserException;
/**
* Template method for parsing a filtered settable expression string. Subclasses
* should override.
* Template method for parsing a filtered settable expression string. Subclasses should override.
* @param expressionString the expression string
* @return the parsed expression
* @throws ParserException an exception occured during parsing
* @throws UnsupportedOperationException this parser does not support
* settable expressions
* @throws UnsupportedOperationException this parser does not support settable expressions
*/
protected abstract SettableExpression doParseSettableExpression(String expressionString)
throws ParserException, UnsupportedOperationException;
protected abstract SettableExpression doParseSettableExpression(String expressionString) throws ParserException,
UnsupportedOperationException;
}

View File

@@ -48,15 +48,14 @@ class BeanWrapperExpression implements SettableExpression {
if (!(o instanceof BeanWrapperExpression)) {
return false;
}
BeanWrapperExpression other = (BeanWrapperExpression)o;
BeanWrapperExpression other = (BeanWrapperExpression) o;
return expression.equals(other.expression);
}
public Object evaluate(Object target, EvaluationContext context) throws EvaluationException {
try {
return new BeanWrapperImpl(target).getPropertyValue(expression);
}
catch (BeansException e) {
} catch (BeansException e) {
throw new EvaluationException(new EvaluationAttempt(this, target, context), e);
}
}
@@ -65,8 +64,7 @@ class BeanWrapperExpression implements SettableExpression {
try {
Assert.notNull(target, "The target object to evaluate is required");
new BeanWrapperImpl(target).setPropertyValue(expression, value);
}
catch (BeansException e) {
} catch (BeansException e) {
throw new EvaluationException(new SetValueAttempt(this, target, value, context), e);
}
}

View File

@@ -25,7 +25,7 @@ import org.springframework.binding.expression.SettableExpression;
* @author Keith Donald
*/
public class BeanWrapperExpressionParser extends AbstractExpressionParser {
protected Expression doParseExpression(String expressionString) throws ParserException {
return doParseSettableExpression(expressionString);
}

View File

@@ -27,7 +27,7 @@ import org.springframework.util.Assert;
/**
* A settable expression that adds non-null values to a collection.
*
*
* @author Keith Donald
*/
public class CollectionAddingExpression implements SettableExpression {
@@ -52,13 +52,13 @@ public class CollectionAddingExpression implements SettableExpression {
public void evaluateToSet(Object target, Object value, EvaluationContext context) throws EvaluationException {
Object result = evaluate(target, context);
if (result == null) {
throw new EvaluationException(new SetValueAttempt(this, target, value, null),
new IllegalArgumentException("The collection expression evaluated to a [null] reference"));
throw new EvaluationException(new SetValueAttempt(this, target, value, null), new IllegalArgumentException(
"The collection expression evaluated to a [null] reference"));
}
Assert.isInstanceOf(Collection.class, result, "Not a collection: ");
if (value != null) {
// add the value to the collection
((Collection)result).add(value);
((Collection) result).add(value);
}
}

View File

@@ -34,8 +34,8 @@ public class CompositeStringExpression implements Expression {
/**
* Creates a new composite string expression.
* @param expressions the ordered set of expressions that when evaluated
* will have their results stringed together to build the composite string
* @param expressions the ordered set of expressions that when evaluated will have their results stringed together
* to build the composite string
*/
public CompositeStringExpression(Expression[] expressions) {
this.expressions = expressions;

View File

@@ -21,8 +21,7 @@ import org.springframework.binding.expression.Expression;
import org.springframework.util.ObjectUtils;
/**
* A simple expression evaluator that just returns a fixed result on each
* evaluation.
* A simple expression evaluator that just returns a fixed result on each evaluation.
*
* @author Keith Donald
*/
@@ -44,8 +43,7 @@ public class StaticExpression implements Expression {
public int hashCode() {
if (value == null) {
return 0;
}
else {
} else {
return value.hashCode();
}
}
@@ -54,7 +52,7 @@ public class StaticExpression implements Expression {
if (!(o instanceof StaticExpression)) {
return false;
}
StaticExpression other = (StaticExpression)o;
StaticExpression other = (StaticExpression) o;
return ObjectUtils.nullSafeEquals(value, other.value);
}

View File

@@ -16,8 +16,7 @@
package org.springframework.binding.format;
/**
* A lightweight interface for formatting a value and parsing a value from its
* formatted form.
* A lightweight interface for formatting a value and parsing a value from its formatted form.
*
* @author Keith Donald
*/
@@ -32,8 +31,7 @@ public interface Formatter {
public String formatValue(Object value) throws IllegalArgumentException;
/**
* Parse the formatted string representation of a value, restoring the
* value.
* Parse the formatted string representation of a value, restoring the value.
* @param formattedString the formatted string representation
* @param targetClass the target class to convert the formatted value to
* @return the parsed value

View File

@@ -18,9 +18,8 @@ package org.springframework.binding.format;
/**
* Source for shared and commonly used <code>Formatters</code>.
* <p>
* Formatters are typically not thread safe as <code>Format</code> objects
* aren't thread safe: so implementations of this service should take care to
* synchronize them as neccessary.
* Formatters are typically not thread safe as <code>Format</code> objects aren't thread safe: so implementations of
* this service should take care to synchronize them as neccessary.
*
* @see java.text.Format
*

View File

@@ -44,7 +44,8 @@ public class InvalidFormatException extends NestedRuntimeException {
* @param cause the underlying cause of this exception
*/
public InvalidFormatException(String invalidValue, String expectedFormat, Throwable cause) {
super("Invalid format for value '" + invalidValue + "'; the expected format was '" + expectedFormat + "'", cause);
super("Invalid format for value '" + invalidValue + "'; the expected format was '" + expectedFormat + "'",
cause);
this.invalidValue = invalidValue;
this.expectedFormat = expectedFormat;
}

View File

@@ -62,18 +62,16 @@ public abstract class AbstractFormatter implements Formatter {
Assert.isTrue(!isEmpty(value), "Object to format cannot be empty");
return doFormatValue(value);
}
/**
* Template method subclasses should override to encapsulate formatting
* logic.
* Template method subclasses should override to encapsulate formatting logic.
* @param value the value to format
* @return the formatted string representation
*/
protected abstract String doFormatValue(Object value);
/**
* Returns the formatted form of an empty value. Default implementation
* just returns the empty string.
* Returns the formatted form of an empty value. Default implementation just returns the empty string.
*/
protected String getEmptyFormattedValue() {
return "";
@@ -85,8 +83,7 @@ public abstract class AbstractFormatter implements Formatter {
return getEmptyValue();
}
return doParseValue(formattedString, targetClass);
}
catch (ParseException ex) {
} catch (ParseException ex) {
throw new InvalidFormatException(formattedString, getExpectedFormat(targetClass), ex);
}
}
@@ -102,16 +99,15 @@ public abstract class AbstractFormatter implements Formatter {
ParseException;
/**
* Returns the empty value (resulting from parsing an empty input string).
* This default implementation just returns null.
* Returns the empty value (resulting from parsing an empty input string). This default implementation just returns
* null.
*/
protected Object getEmptyValue() {
return null;
}
/**
* Returns the expected string format for the given target class.
* The default implementation just returns null.
* Returns the expected string format for the given target class. The default implementation just returns null.
*/
protected String getExpectedFormat(Class targetClass) {
return null;
@@ -123,11 +119,9 @@ public abstract class AbstractFormatter implements Formatter {
protected boolean isEmpty(Object o) {
if (o == null) {
return true;
}
else if (o instanceof String) {
return !StringUtils.hasText((String)o);
}
else {
} else if (o instanceof String) {
return !StringUtils.hasText((String) o);
} else {
return false;
}
}

View File

@@ -24,8 +24,8 @@ import org.springframework.context.i18n.LocaleContext;
import org.springframework.context.i18n.SimpleLocaleContext;
/**
* Base class for formatter factories. Manages the locale used by the produced
* formatters using Spring's {@link org.springframework.context.i18n.LocaleContext} system.
* Base class for formatter factories. Manages the locale used by the produced formatters using Spring's
* {@link org.springframework.context.i18n.LocaleContext} system.
*
* @author Keith Donald
*/
@@ -38,8 +38,7 @@ public abstract class AbstractFormatterFactory implements FormatterFactory {
private Style defaultTimeStyle = Style.MEDIUM;
/**
* Sets the locale context used. Defaults to a {@link SimpleLocaleContext} holding
* the system default locale.
* Sets the locale context used. Defaults to a {@link SimpleLocaleContext} holding the system default locale.
*/
public void setLocaleContext(LocaleContext localeContext) {
this.localeContext = localeContext;

View File

@@ -31,8 +31,7 @@ public class DateFormatter extends AbstractFormatter {
private DateFormat dateFormat;
/**
* Constructs a date formatter that will delegate to the specified date
* format.
* Constructs a date formatter that will delegate to the specified date format.
* @param dateFormat the date format to use
*/
public DateFormatter(DateFormat dateFormat) {
@@ -40,8 +39,7 @@ public class DateFormatter extends AbstractFormatter {
}
/**
* Constructs a date formatter that will delegate to the specified date
* format.
* Constructs a date formatter that will delegate to the specified date format.
* @param dateFormat the date format to use
* @param allowEmpty should this formatter allow empty input arguments?
*/
@@ -52,7 +50,7 @@ public class DateFormatter extends AbstractFormatter {
// convert from date to string
protected String doFormatValue(Object date) {
return dateFormat.format((Date)date);
return dateFormat.format((Date) date);
}
// convert back from string to date
@@ -64,6 +62,6 @@ public class DateFormatter extends AbstractFormatter {
* Convenience method to parse a date.
*/
public Date parseDate(String formattedString) throws InvalidFormatException {
return (Date)parseValue(formattedString, Date.class);
return (Date) parseValue(formattedString, Date.class);
}
}

View File

@@ -53,7 +53,7 @@ public class LabeledEnumFormatter extends AbstractFormatter {
}
protected String doFormatValue(Object value) {
LabeledEnum labeledEnum = (LabeledEnum)value;
LabeledEnum labeledEnum = (LabeledEnum) value;
return labeledEnum.getLabel();
}
@@ -71,6 +71,6 @@ public class LabeledEnumFormatter extends AbstractFormatter {
* Convenience method to parse a LabeledEnum.
*/
public LabeledEnum parseLabeledEnum(String formattedString, Class enumClass) throws InvalidFormatException {
return (LabeledEnum)parseValue(formattedString, enumClass);
return (LabeledEnum) parseValue(formattedString, enumClass);
}
}

View File

@@ -23,18 +23,17 @@ import org.springframework.binding.format.InvalidFormatException;
import org.springframework.util.NumberUtils;
/**
* Converts from various <code>Number</code> specializations to
* <code>String</code> and back.
* Converts from various <code>Number</code> specializations to <code>String</code> and back.
*
* @author Keith Donald
*/
public class NumberFormatter extends AbstractFormatter {
private NumberFormat numberFormat;
/**
* Default constructor. The formatter will use "toString" when formatting
* a value and "valueOf" when parsing a value.
* Default constructor. The formatter will use "toString" when formatting a value and "valueOf" when parsing a
* value.
*/
public NumberFormatter() {
}
@@ -61,8 +60,7 @@ public class NumberFormatter extends AbstractFormatter {
if (this.numberFormat != null) {
// use NumberFormat for rendering value
return this.numberFormat.format(number);
}
else {
} else {
// use toString method for rendering value
return number.toString();
}
@@ -78,38 +76,38 @@ public class NumberFormatter extends AbstractFormatter {
return NumberUtils.parseNumber(text, targetClass);
}
}
// convenience methods
public Byte parseByte(String formattedString) throws InvalidFormatException {
return (Byte)parseValue(formattedString, Byte.class);
return (Byte) parseValue(formattedString, Byte.class);
}
public Short parseShort(String formattedString) throws InvalidFormatException {
return (Short)parseValue(formattedString, Short.class);
return (Short) parseValue(formattedString, Short.class);
}
public Integer parseInteger(String formattedString) throws InvalidFormatException {
return (Integer)parseValue(formattedString, Integer.class);
return (Integer) parseValue(formattedString, Integer.class);
}
public Long parseLong(String formattedString) throws InvalidFormatException {
return (Long)parseValue(formattedString, Long.class);
return (Long) parseValue(formattedString, Long.class);
}
public Float parseFloat(String formattedString) throws InvalidFormatException {
return (Float)parseValue(formattedString, Float.class);
return (Float) parseValue(formattedString, Float.class);
}
public Double parseDouble(String formattedString) throws InvalidFormatException {
return (Double)parseValue(formattedString, Double.class);
return (Double) parseValue(formattedString, Double.class);
}
public BigInteger parseBigInteger(String formattedString) throws InvalidFormatException {
return (BigInteger)parseValue(formattedString, BigInteger.class);
return (BigInteger) parseValue(formattedString, BigInteger.class);
}
public BigDecimal parseBigDecimal(String formattedString) throws InvalidFormatException {
return (BigDecimal)parseValue(formattedString, BigDecimal.class);
return (BigDecimal) parseValue(formattedString, BigDecimal.class);
}
}

View File

@@ -18,9 +18,8 @@ package org.springframework.binding.mapping;
/**
* A lightweight service interface for mapping between two attribute sources.
* <p>
* Implementations of this interface are expected to encapsulate the mapping
* configuration information as well as the logic to act on it to perform
* mapping between a given source and target attribute source.
* Implementations of this interface are expected to encapsulate the mapping configuration information as well as the
* logic to act on it to perform mapping between a given source and target attribute source.
*
* @author Keith Donald
*/

View File

@@ -23,8 +23,7 @@ import java.util.List;
import org.springframework.core.style.ToStringCreator;
/**
* Generic attributes mapper implementation that allows mappings to be
* configured programatically.
* Generic attributes mapper implementation that allows mappings to be configured programatically.
*
* @author Erwin Vervaet
* @author Keith Donald
@@ -49,7 +48,7 @@ public class DefaultAttributeMapper implements AttributeMapper {
/**
* Add a set of mappings.
* @param mappings the mappings
* @param mappings the mappings
*/
public void addMappings(AttributeMapper[] mappings) {
if (mappings == null) {
@@ -63,14 +62,14 @@ public class DefaultAttributeMapper implements AttributeMapper {
* @return the list of mappings
*/
public AttributeMapper[] getMappings() {
return (AttributeMapper[])mappings.toArray(new AttributeMapper[mappings.size()]);
return (AttributeMapper[]) mappings.toArray(new AttributeMapper[mappings.size()]);
}
public void map(Object source, Object target, MappingContext context) {
if (mappings != null) {
Iterator it = mappings.iterator();
while (it.hasNext()) {
AttributeMapper mapping = (AttributeMapper)it.next();
AttributeMapper mapping = (AttributeMapper) it.next();
mapping.map(source, target, context);
}
}

View File

@@ -24,10 +24,8 @@ import org.springframework.core.style.ToStringCreator;
import org.springframework.util.Assert;
/**
* A single mapping definition, encapulating the information neccessary to map
* the result of evaluating an expression on a source object to a property on a
* target object, optionally applying a type conversion during the mapping
* process.
* A single mapping definition, encapulating the information neccessary to map the result of evaluating an expression on
* a source object to a property on a target object, optionally applying a type conversion during the mapping process.
*
* @author Keith Donald
*/
@@ -51,8 +49,7 @@ public class Mapping implements AttributeMapper {
private final ConversionExecutor typeConverter;
/**
* Whether or not this is a required mapping; if true, the source expression
* must return a non-null value.
* Whether or not this is a required mapping; if true, the source expression must return a non-null value.
*/
private boolean required;
@@ -62,8 +59,7 @@ public class Mapping implements AttributeMapper {
* @param targetExpression the target expression
* @param typeConverter a type converter
*/
public Mapping(Expression sourceExpression, SettableExpression targetExpression,
ConversionExecutor typeConverter) {
public Mapping(Expression sourceExpression, SettableExpression targetExpression, ConversionExecutor typeConverter) {
this(sourceExpression, targetExpression, typeConverter, false);
}
@@ -85,9 +81,8 @@ public class Mapping implements AttributeMapper {
}
/**
* Map the <code>sourceAttribute</code> in to the
* <code>targetAttribute</code> target map, performing type conversion if
* necessary.
* Map the <code>sourceAttribute</code> in to the <code>targetAttribute</code> target map, performing type
* conversion if necessary.
* @param source The source data structure
* @param target The target data structure
*/
@@ -99,8 +94,7 @@ public class Mapping implements AttributeMapper {
throw new RequiredMappingException("This mapping is required; evaluation of expression '"
+ sourceExpression + "' against source of type [" + source.getClass()
+ "] must return a non-null value");
}
else {
} else {
// source expression returned no value, simply abort mapping
return;
}
@@ -121,9 +115,8 @@ public class Mapping implements AttributeMapper {
if (!(o instanceof Mapping)) {
return false;
}
Mapping other = (Mapping)o;
return sourceExpression.equals(other.sourceExpression)
&& targetExpression.equals(other.targetExpression);
Mapping other = (Mapping) o;
return sourceExpression.equals(other.sourceExpression) && targetExpression.equals(other.targetExpression);
}
public int hashCode() {

View File

@@ -25,8 +25,8 @@ import org.springframework.binding.expression.support.CollectionAddingExpression
import org.springframework.util.Assert;
/**
* A stateful builder that builds {@link Mapping} objects. Designed for
* convenience to build mappings in a clear, readable manner.
* A stateful builder that builds {@link Mapping} objects. Designed for convenience to build mappings in a clear,
* readable manner.
* <p>
* Example usage:
*
@@ -35,8 +35,8 @@ import org.springframework.util.Assert;
* Mapping result = mapping.source(&quot;foo&quot;).target(&quot;bar&quot;).from(String.class).to(Long.class).value();
* </pre>
*
* Calling the {@link #value()} result method clears out this builder's state so
* it can be reused to build another mapping.
* Calling the {@link #value()} result method clears out this builder's state so it can be reused to build another
* mapping.
*
* @author Keith Donald
* @author Erwin Vervaet
@@ -77,10 +77,9 @@ public class MappingBuilder {
* Whether or not the built mapping is a required mapping.
*/
private boolean required;
/**
* Creates a mapping builder that uses the expression parser to parse
* attribute mapping expressions.
* Creates a mapping builder that uses the expression parser to parse attribute mapping expressions.
* @param expressionParser the expression parser
*/
public MappingBuilder(ExpressionParser expressionParser) {
@@ -89,9 +88,8 @@ public class MappingBuilder {
}
/**
* Sets the conversion service that will convert the object returned by
* evaluating the source expression to the {@link #to(Class)} type if
* necessary.
* Sets the conversion service that will convert the object returned by evaluating the source expression to the
* {@link #to(Class)} type if necessary.
* @param conversionService the conversion service
*/
public void setConversionService(ConversionService conversionService) {
@@ -114,7 +112,7 @@ public class MappingBuilder {
* @return this, to support call-chaining
*/
public MappingBuilder target(String expressionString) {
targetExpression = (SettableExpression)expressionParser.parseExpression(expressionString);
targetExpression = (SettableExpression) expressionParser.parseExpression(expressionString);
return this;
}
@@ -124,15 +122,13 @@ public class MappingBuilder {
* @return this, to support call-chaining
*/
public MappingBuilder targetCollection(String expressionString) {
targetExpression = new CollectionAddingExpression(
expressionParser.parseSettableExpression(expressionString));
targetExpression = new CollectionAddingExpression(expressionParser.parseSettableExpression(expressionString));
return this;
}
/**
* Sets the expected type of the object returned by evaluating the source
* expression. Used in conjunction with {@link #to(Class)} to perform a type
* conversion during the mapping process.
* Sets the expected type of the object returned by evaluating the source expression. Used in conjunction with
* {@link #to(Class)} to perform a type conversion during the mapping process.
* @param sourceType the source type
* @return this, to support call-chaining
*/
@@ -159,17 +155,16 @@ public class MappingBuilder {
this.required = true;
return this;
}
/**
* The logical GoF builder getResult method, returning a fully constructed
* Mapping from the configured pieces. Once called, the state of this
* builder is nulled out to support building a new mapping object again.
* The logical GoF builder getResult method, returning a fully constructed Mapping from the configured pieces. Once
* called, the state of this builder is nulled out to support building a new mapping object again.
* @return the mapping result
*/
public Mapping value() {
Assert.notNull(sourceExpression, "The source expression must be set at a minimum");
if (targetExpression == null) {
targetExpression = (SettableExpression)sourceExpression;
targetExpression = (SettableExpression) sourceExpression;
}
ConversionExecutor typeConverter = null;
if (sourceType != null) {
@@ -179,14 +174,13 @@ public class MappingBuilder {
Mapping result;
if (required) {
result = new RequiredMapping(sourceExpression, targetExpression, typeConverter);
}
else {
} else {
result = new Mapping(sourceExpression, targetExpression, typeConverter);
}
reset();
return result;
}
/**
* Reset this mapping builder.
*/

View File

@@ -18,13 +18,10 @@ package org.springframework.binding.mapping;
/**
* A context object with two main responsibities:
* <ol>
* <li>Exposing information to a mapper to influence
* a mapping attempt.
* <li>Providing operations for recording progress or
* errors during the mapping process.
* <li>Exposing information to a mapper to influence a mapping attempt.
* <li>Providing operations for recording progress or errors during the mapping process.
* </ol>
* Empty for now; subclasses may define their own custom context behavior
* accessible by a mapper with a downcast.
* Empty for now; subclasses may define their own custom context behavior accessible by a mapper with a downcast.
*
* @author Keith Donald
*/

View File

@@ -25,7 +25,7 @@ import org.springframework.binding.expression.SettableExpression;
* @author Keith Donald
*/
public class RequiredMapping extends Mapping {
/**
* Creates a required mapping.
* @param sourceExpression the source mapping expression

View File

@@ -21,7 +21,7 @@ package org.springframework.binding.mapping;
* @author Keith Donald
*/
public class RequiredMappingException extends IllegalStateException {
/**
* Create a new required mapping exception.
* @param message a descriptive message

View File

@@ -18,8 +18,7 @@ package org.springframework.binding.method;
import org.springframework.core.NestedRuntimeException;
/**
* Thrown when a method key could not be resolved to an invokable java Method on
* a Class.
* Thrown when a method key could not be resolved to an invokable java Method on a Class.
*
* @author Keith Donald
*/
@@ -29,7 +28,7 @@ public class InvalidMethodKeyException extends NestedRuntimeException {
* The method key that could not be resolved.
*/
private MethodKey methodKey;
/**
* Creates an exception signaling an invalid method signature.
* @param methodKey the class method key

View File

@@ -28,20 +28,17 @@ import org.springframework.core.style.StylerUtils;
public class MethodInvocationException extends NestedRuntimeException {
/**
* The method signature.
* Transient because a MethodSignature is not Serializable.
* The method signature. Transient because a MethodSignature is not Serializable.
*/
private transient MethodSignature methodSignature;
/**
* The method invocation argument values.
* Transient because we cannot guarantee that the arguments are Serializable.
* The method invocation argument values. Transient because we cannot guarantee that the arguments are Serializable.
*/
private transient Object[] arguments;
/**
* Signals that the method with the specified signature could not be invoked
* with the provided arguments.
* Signals that the method with the specified signature could not be invoked with the provided arguments.
* @param methodSignature the method signature
* @param arguments the arguments
* @param cause the root cause
@@ -73,7 +70,7 @@ public class MethodInvocationException extends NestedRuntimeException {
public Throwable getTargetException() {
Throwable targetException = getCause();
while (targetException instanceof InvocationTargetException) {
targetException = ((InvocationTargetException)targetException).getTargetException();
targetException = ((InvocationTargetException) targetException).getTargetException();
}
return targetException;
}

View File

@@ -26,9 +26,8 @@ import org.springframework.core.style.StylerUtils;
import org.springframework.util.CachingMapDecorator;
/**
* A helper for invoking typed methods on abritrary objects, with support for
* argument value type conversion from values retrieved from a argument
* attribute source.
* A helper for invoking typed methods on abritrary objects, with support for argument value type conversion from values
* retrieved from a argument attribute source.
*
* @author Keith Donald
*/
@@ -37,8 +36,7 @@ public class MethodInvoker {
private static final Log logger = LogFactory.getLog(MethodInvoker.class);
/**
* Conversion service for converting arguments to the neccessary type if
* required.
* Conversion service for converting arguments to the neccessary type if required.
*/
private ConversionService conversionService = new DefaultConversionService();
@@ -59,10 +57,8 @@ public class MethodInvoker {
}
/**
* Invoke the method on the bean provided. Argument values are pulled from
* the provided argument source.
* @param signature the definition of the method to invoke, including the
* method name and the method argument types
* Invoke the method on the bean provided. Argument values are pulled from the provided argument source.
* @param signature the definition of the method to invoke, including the method name and the method argument types
* @param bean the bean to invoke
* @param argumentSource the source for method arguments
* @return the invoked method's return value
@@ -99,11 +95,9 @@ public class MethodInvoker {
logger.debug("Invoked method with signature [" + key + "] returned value [" + returnValue + "]");
}
return returnValue;
}
catch (InvocationTargetException e) {
} catch (InvocationTargetException e) {
throw new MethodInvocationException(signature, arguments, e.getTargetException());
}
catch (Exception e) {
} catch (Exception e) {
throw new MethodInvocationException(signature, arguments, e);
}
}

View File

@@ -42,9 +42,8 @@ public class MethodKey implements Serializable {
private String methodName;
/**
* The method's actual parameter types. Could contain null values
* if the user did not specify a parameter type for the corresponding
* parameter
* The method's actual parameter types. Could contain null values if the user did not specify a parameter type for
* the corresponding parameter
*/
private Class[] parameterTypes;
@@ -57,8 +56,7 @@ public class MethodKey implements Serializable {
* Create a new method key.
* @param declaredType the class the method is a member of
* @param methodName the method name
* @param parameterTypes the method's parameter types, or <code>null</code>
* if the method has no parameters
* @param parameterTypes the method's parameter types, or <code>null</code> if the method has no parameters
*/
public MethodKey(Class declaredType, String methodName, Class[] parameterTypes) {
Assert.notNull(declaredType, "The method's declared type is required");
@@ -83,8 +81,8 @@ public class MethodKey implements Serializable {
}
/**
* Returns the method parameter types. Could contain null values
* if no type was specified for the corresponding parameter.
* Returns the method parameter types. Could contain null values if no type was specified for the corresponding
* parameter.
*/
public Class[] getParameterTypes() {
return parameterTypes;
@@ -108,13 +106,11 @@ public class MethodKey implements Serializable {
protected Method resolveMethod() throws InvalidMethodKeyException {
try {
return declaredType.getMethod(methodName, parameterTypes);
}
catch (NoSuchMethodException e) {
} catch (NoSuchMethodException e) {
Method method = findMethodConsiderAssignableParameterTypes();
if (method != null) {
return method;
}
else {
} else {
throw new InvalidMethodKeyException(this, e);
}
}
@@ -140,8 +136,7 @@ public class MethodKey implements Serializable {
if (isAssignable(candidateType, parameterType)) {
numberOfCorrectArguments++;
}
}
else {
} else {
// just match on a null param type (effectively 'any')
numberOfCorrectArguments++;
}
@@ -202,16 +197,14 @@ public class MethodKey implements Serializable {
}
/**
* Convenience method that returns the parameter types describing the
* signature of the method as a string.
* Convenience method that returns the parameter types describing the signature of the method as a string.
*/
private String parameterTypesString() {
StringBuffer parameterTypesString = new StringBuffer();
for (int i = 0; i < parameterTypes.length; i++) {
if (parameterTypes[i] == null) {
parameterTypesString.append("<any>");
}
else {
} else {
parameterTypesString.append(ClassUtils.getShortName(parameterTypes[i]));
}
if (i < parameterTypes.length - 1) {
@@ -224,13 +217,12 @@ public class MethodKey implements Serializable {
// internal helpers
/**
* Determine if the given target type is assignable from the given value
* type, assuming setting by reflection. Considers primitive wrapper classes
* as assignable to the corresponding primitive types. <p> NOTE: Pulled from
* ClassUtils in Spring 2.0 for 1.2.8 compatability.
* Determine if the given target type is assignable from the given value type, assuming setting by reflection.
* Considers primitive wrapper classes as assignable to the corresponding primitive types.
* <p>
* NOTE: Pulled from ClassUtils in Spring 2.0 for 1.2.8 compatability.
* @param targetType the target type
* @param valueType the value type that should be assigned to the target
* type
* @param valueType the value type that should be assigned to the target type
* @return if the target type is assignable from the value type
*/
private static boolean isAssignable(Class targetType, Class valueType) {
@@ -238,8 +230,8 @@ public class MethodKey implements Serializable {
}
/**
* Map with primitive wrapper type as key and corresponding primitive type
* as value, for example: Integer.class -> int.class.
* Map with primitive wrapper type as key and corresponding primitive type as value, for example: Integer.class ->
* int.class.
*/
private static final Map primitiveWrapperTypeMap = new HashMap(8);

View File

@@ -19,9 +19,8 @@ import org.springframework.core.style.ToStringCreator;
import org.springframework.util.Assert;
/**
* A specification for a method consisting of the methodName and an optional set
* of named arguments. This class provides the ability to resolve a method with
* parameters and evaluate its argument values as part of a
* A specification for a method consisting of the methodName and an optional set of named arguments. This class provides
* the ability to resolve a method with parameters and evaluate its argument values as part of a
* {@link MethodInvoker method invoker attempt}.
*
* @author Keith Donald

View File

@@ -22,8 +22,7 @@ import org.springframework.util.Assert;
import org.springframework.util.ObjectUtils;
/**
* A named method parameter. Each parameter has an identifying name and is of a
* specified type (class).
* A named method parameter. Each parameter has an identifying name and is of a specified type (class).
*
* @author Keith Donald
*/
@@ -35,14 +34,13 @@ public class Parameter {
private Class type;
/**
* The name of the parameter as an evaluatable expression, e.g
* "accountNumber".
* The name of the parameter as an evaluatable expression, e.g "accountNumber".
*/
private Expression name;
/**
* Create a new named parameter definition. Named parameters are capable of resolving
* parameter values (arguments) from argument sources.
* Create a new named parameter definition. Named parameters are capable of resolving parameter values (arguments)
* from argument sources.
* @param type the parameter type, may be null
* @param name the name the method argument expression (required)
*/
@@ -53,8 +51,7 @@ public class Parameter {
}
/**
* Returns the parameter type. Could be null if no parameter type
* was specified.
* Returns the parameter type. Could be null if no parameter type was specified.
*/
public Class getType() {
return type;
@@ -68,8 +65,7 @@ public class Parameter {
}
/**
* Evaluate this method parameter against the provided argument source,
* returning a single method argument value.
* Evaluate this method parameter against the provided argument source, returning a single method argument value.
* @param argumentSource the meyhod argument source
* @param context the evaluation context
* @return the method argument value

View File

@@ -95,16 +95,15 @@ public class Parameters {
}
/**
* Get an array containing each parameter type. The resulting array
* could contain null values if the corresponding parameters did
* not specify a parameter type.
* Get an array containing each parameter type. The resulting array could contain null values if the corresponding
* parameters did not specify a parameter type.
* @return the types
*/
public Class[] getTypesArray() {
int i = 0;
Class[] types = new Class[parameters.size()];
for (Iterator it = parameters.iterator(); it.hasNext();) {
Parameter param = (Parameter)it.next();
Parameter param = (Parameter) it.next();
types[i] = param.getType();
i++;
}
@@ -126,14 +125,14 @@ public class Parameters {
* @throws IndexOutOfBoundsException if the provided index is out of bounds
*/
public Parameter getParameter(int index) throws IndexOutOfBoundsException {
return (Parameter)parameters.get(index);
return (Parameter) parameters.get(index);
}
public boolean equals(Object obj) {
if (!(obj instanceof Parameters)) {
return false;
}
Parameters other = (Parameters)obj;
Parameters other = (Parameters) obj;
return parameters.equals(other.parameters);
}

View File

@@ -25,20 +25,17 @@ import org.springframework.binding.convert.support.ConversionServiceAwareConvert
import org.springframework.binding.expression.Expression;
/**
* Converter that takes an encoded string representation and produces a
* corresponding <code>MethodSignature</code> object.
* Converter that takes an encoded string representation and produces a corresponding <code>MethodSignature</code>
* object.
* <p>
* This converter supports the following encoded forms:
* <ul>
* <li> "methodName" - the name of the method to invoke, where the method is
* expected to have no arguments. </li>
* <li> "methodName(param1Type param1Name, paramNType paramNName)" - the name of
* the method to invoke, where the method is expected to have parameters
* delimited by a comma. In this example, the method has two parameters. The
* type is either the fully-qualified class of the argument OR a known type
* alias OR left out althogether. The name is the logical name of the argument,
* which is used during data binding to retrieve the argument value
* (typically an expression). </li>
* <li> "methodName" - the name of the method to invoke, where the method is expected to have no arguments. </li>
* <li> "methodName(param1Type param1Name, paramNType paramNName)" - the name of the method to invoke, where the method
* is expected to have parameters delimited by a comma. In this example, the method has two parameters. The type is
* either the fully-qualified class of the argument OR a known type alias OR left out althogether. The name is the
* logical name of the argument, which is used during data binding to retrieve the argument value (typically an
* expression). </li>
* </ul>
*
* @see MethodSignature
@@ -71,14 +68,13 @@ public class TextToMethodSignature extends ConversionServiceAwareConverter {
}
protected Object doConvert(Object source, Class targetClass, ConversionContext context) throws Exception {
String encodedMethodSignature = (String)source;
String encodedMethodSignature = (String) source;
encodedMethodSignature = encodedMethodSignature.trim();
int openParan = encodedMethodSignature.indexOf('(');
if (openParan == -1) {
// form "foo"
return new MethodSignature(encodedMethodSignature);
}
else {
} else {
// form "foo(...)"
String methodName = encodedMethodSignature.substring(0, openParan);
int closeParan = encodedMethodSignature.lastIndexOf(')');
@@ -94,13 +90,12 @@ public class TextToMethodSignature extends ConversionServiceAwareConverter {
String param = paramArray[i].trim();
int space = param.indexOf(' ');
int expr = param.indexOf('{');
if (space == -1 || (expr != -1 && space > expr)) {
if (space == -1 || (expr != -1 && space > expr)) {
// "name" or "${name}"
params.add(new Parameter(null, parseExpression(param)));
}
else {
} else {
// "type name" or "type ${name}"
Class type = (Class)fromStringTo(Class.class).execute(param.substring(0, space).trim());
Class type = (Class) fromStringTo(Class.class).execute(param.substring(0, space).trim());
Expression name = parseExpression(param.substring(space + 1).trim());
params.add(new Parameter(type, name));
}
@@ -108,31 +103,31 @@ public class TextToMethodSignature extends ConversionServiceAwareConverter {
return new MethodSignature(methodName, params);
}
}
/**
* Split given parameter string into individual parameter definitions.
*/
private String[] splitParameters(String encodedMethodSignature, String parameters) {
List res = new LinkedList();
int paramStart = 0;
int blockNestingCount = 0;
for (int i = 0; i < parameters.length(); i++) {
switch (parameters.charAt(i)) {
case '{':
blockNestingCount++;
break;
case '}':
blockNestingCount--;
break;
case ',':
if (blockNestingCount == 0) {
// only take comma delimiter into account when not inside
// a block
res.add(parameters.substring(paramStart, i));
paramStart = i + 1;
}
break;
case '{':
blockNestingCount++;
break;
case '}':
blockNestingCount--;
break;
case ',':
if (blockNestingCount == 0) {
// only take comma delimiter into account when not inside
// a block
res.add(parameters.substring(paramStart, i));
paramStart = i + 1;
}
break;
}
}
if (blockNestingCount != 0) {
@@ -142,7 +137,7 @@ public class TextToMethodSignature extends ConversionServiceAwareConverter {
if (paramStart < parameters.length()) {
res.add(parameters.substring(paramStart));
}
return (String[])res.toArray(new String[res.size()]);
return (String[]) res.toArray(new String[res.size()]);
}
}