binding refactoring - in progress
This commit is contained in:
@@ -42,11 +42,4 @@ public interface ConversionExecutor {
|
||||
*/
|
||||
public Object execute(Object source) throws ConversionExecutionException;
|
||||
|
||||
/**
|
||||
* 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
|
||||
*/
|
||||
public Object execute(Object source, Object context) throws ConversionExecutionException;
|
||||
|
||||
}
|
||||
@@ -27,7 +27,7 @@ package org.springframework.binding.convert;
|
||||
public interface ConversionService {
|
||||
|
||||
/**
|
||||
* Return a conversion executor command object capable of converting source objects of the specified
|
||||
* Return the default conversion executor 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.
|
||||
@@ -39,4 +39,18 @@ public interface ConversionService {
|
||||
public ConversionExecutor getConversionExecutor(Class sourceClass, Class targetClass)
|
||||
throws ConversionExecutorNotFoundException;
|
||||
|
||||
/**
|
||||
* Return a custom conversion executor 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.
|
||||
* @param id the id of the custom conversion executor (should be unique among custom converters)
|
||||
* @param sourceClass the source class to convert from
|
||||
* @param targetClass the target class to convert to
|
||||
* @return the executor that can execute instance type conversion, never null
|
||||
* @throws ConversionExecutorNotFoundException when no suitable conversion executor could be found
|
||||
*/
|
||||
public ConversionExecutor getConversionExecutor(String id, Class sourceClass, Class targetClass)
|
||||
throws ConversionExecutorNotFoundException;
|
||||
|
||||
}
|
||||
@@ -1,57 +0,0 @@
|
||||
/*
|
||||
* Copyright 2004-2008 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.binding.convert;
|
||||
|
||||
import org.springframework.binding.format.Formatter;
|
||||
|
||||
/**
|
||||
* Converts objects from one type to another. May support conversion of multiple source types to multiple target types.
|
||||
* <p>
|
||||
* Implementations of this interface are thread-safe and can be shared.
|
||||
* </p>
|
||||
* <p>
|
||||
* A converter is more generic than a formatter. A formatter only handles converting from String and back, while
|
||||
* converters convert from an arbitrary Object type to another.
|
||||
* </p>
|
||||
* @see Formatter
|
||||
* @author Keith Donald
|
||||
*/
|
||||
public interface Converter {
|
||||
|
||||
/**
|
||||
* The source classes this converter can convert from.
|
||||
* @return the supported source classes
|
||||
*/
|
||||
public Class[] getSourceClasses();
|
||||
|
||||
/**
|
||||
* The target classes this converter can convert to.
|
||||
* @return the supported target classes
|
||||
*/
|
||||
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, it 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 Exception an exception occurred performing the conversion
|
||||
*/
|
||||
public Object convert(Object source, Class targetClass, Object context) throws Exception;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,48 @@
|
||||
package org.springframework.binding.convert.converters;
|
||||
|
||||
import java.lang.reflect.Array;
|
||||
|
||||
import org.springframework.binding.convert.ConversionExecutor;
|
||||
import org.springframework.binding.convert.ConversionService;
|
||||
|
||||
public class ArrayToArray implements Converter {
|
||||
|
||||
private ConversionService conversionService;
|
||||
|
||||
public ArrayToArray(ConversionService conversionService) {
|
||||
this.conversionService = conversionService;
|
||||
}
|
||||
|
||||
public Class getSourceClass() {
|
||||
return Object[].class;
|
||||
}
|
||||
|
||||
public Class getTargetClass() {
|
||||
return Object[].class;
|
||||
}
|
||||
|
||||
public Object convertSourceToTargetClass(Object source, Class targetClass) throws Exception {
|
||||
if (source == null) {
|
||||
return null;
|
||||
}
|
||||
Class sourceComponentType = source.getClass().getComponentType();
|
||||
if (!sourceComponentType.isPrimitive()) {
|
||||
Object[] sourceArray = (Object[]) source;
|
||||
Class targetComponentType = targetClass.getComponentType();
|
||||
ConversionExecutor executor = conversionService.getConversionExecutor(sourceComponentType,
|
||||
targetComponentType);
|
||||
Object target = Array.newInstance(targetComponentType, sourceArray.length);
|
||||
if (!targetComponentType.isPrimitive()) {
|
||||
Object[] targetArray = (Object[]) target;
|
||||
for (int i = 0; i < sourceArray.length; i++) {
|
||||
targetArray[i] = executor.execute(sourceArray[i]);
|
||||
}
|
||||
return targetArray;
|
||||
} else {
|
||||
throw new UnsupportedOperationException("Primitive arrays not yet supported");
|
||||
}
|
||||
} else {
|
||||
throw new UnsupportedOperationException("Primitive arrays not yet supported");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,100 @@
|
||||
package org.springframework.binding.convert.converters;
|
||||
|
||||
import java.lang.reflect.Array;
|
||||
import java.lang.reflect.Constructor;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Iterator;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.SortedSet;
|
||||
import java.util.TreeSet;
|
||||
|
||||
import org.springframework.binding.convert.ConversionExecutor;
|
||||
import org.springframework.binding.convert.ConversionService;
|
||||
import org.springframework.core.GenericCollectionTypeResolver;
|
||||
import org.springframework.core.JdkVersion;
|
||||
|
||||
public class ArrayToCollection implements TwoWayConverter {
|
||||
|
||||
private ConversionService conversionService;
|
||||
|
||||
public ArrayToCollection(ConversionService conversionService) {
|
||||
this.conversionService = conversionService;
|
||||
}
|
||||
|
||||
public Class getSourceClass() {
|
||||
return Object[].class;
|
||||
}
|
||||
|
||||
public Class getTargetClass() {
|
||||
return Collection.class;
|
||||
}
|
||||
|
||||
public Object convertSourceToTargetClass(Object source, Class targetClass) throws Exception {
|
||||
if (source == null) {
|
||||
return null;
|
||||
}
|
||||
Class collectionImplClass;
|
||||
if (targetClass.isInterface()) {
|
||||
if (List.class.equals(targetClass)) {
|
||||
collectionImplClass = ArrayList.class;
|
||||
} else if (Set.class.equals(targetClass)) {
|
||||
collectionImplClass = LinkedHashSet.class;
|
||||
} else if (SortedSet.class.equals(targetClass)) {
|
||||
collectionImplClass = TreeSet.class;
|
||||
} else {
|
||||
throw new IllegalArgumentException("Unsupported collection interface [" + targetClass.getName() + "]");
|
||||
}
|
||||
} else {
|
||||
collectionImplClass = targetClass;
|
||||
}
|
||||
Constructor constructor = collectionImplClass.getConstructor(null);
|
||||
ConversionExecutor converter;
|
||||
if (JdkVersion.isAtLeastJava15()) {
|
||||
Class elementType = GenericCollectionTypeResolver.getCollectionType(targetClass);
|
||||
if (elementType != null) {
|
||||
Class componentType = source.getClass().getComponentType();
|
||||
converter = conversionService.getConversionExecutor(componentType, elementType);
|
||||
} else {
|
||||
converter = null;
|
||||
}
|
||||
} else {
|
||||
converter = null;
|
||||
}
|
||||
Collection collection = (Collection) constructor.newInstance(null);
|
||||
Method add = collectionImplClass.getMethod("add", new Class[] { Object.class });
|
||||
int length = Array.getLength(source);
|
||||
if (converter != null) {
|
||||
for (int i = 0; i < length; i++) {
|
||||
Object value = Array.get(source, i);
|
||||
value = converter.execute(value);
|
||||
add.invoke(collection, new Object[] { value });
|
||||
}
|
||||
} else {
|
||||
for (int i = 0; i < length; i++) {
|
||||
Object value = Array.get(source, i);
|
||||
add.invoke(collection, new Object[] { value });
|
||||
}
|
||||
}
|
||||
return collection;
|
||||
}
|
||||
|
||||
public Object convertTargetToSourceClass(Object target, Class sourceClass) throws Exception {
|
||||
if (target == null) {
|
||||
return null;
|
||||
}
|
||||
Collection collection = (Collection) target;
|
||||
Object array = Array.newInstance(sourceClass.getComponentType(), collection.size());
|
||||
int i = 0;
|
||||
for (Iterator it = collection.iterator(); it.hasNext(); i++) {
|
||||
Object value = it.next();
|
||||
ConversionExecutor converter = conversionService.getConversionExecutor(value.getClass(), sourceClass
|
||||
.getComponentType());
|
||||
Array.set(array, i, converter.execute(value));
|
||||
}
|
||||
return array;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,53 @@
|
||||
/*
|
||||
* Copyright 2004-2008 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.binding.convert.converters;
|
||||
|
||||
/**
|
||||
* A converter is capable of converting a source object of type {@link #getSourceClass()} to a target type of type
|
||||
* {@link #getTargetClass()}. If the converter is a {@link TwoWayConverter}, it can also convert from the target back
|
||||
* to the source.
|
||||
* <p>
|
||||
* Implementations of this interface are thread-safe and can be shared.
|
||||
* </p>
|
||||
* @author Keith Donald
|
||||
*/
|
||||
public interface Converter {
|
||||
|
||||
/**
|
||||
* The source class this converter can convert from. May be an interface or abstract type to allow this converter to
|
||||
* convert specific subclasses as well.
|
||||
* @return the source type
|
||||
*/
|
||||
public Class getSourceClass();
|
||||
|
||||
/**
|
||||
* The target class this converter can convert to. May be an interface or abstract type to allow this converter to
|
||||
* convert specific subclasses as well.
|
||||
* @return the target type
|
||||
*/
|
||||
public Class getTargetClass();
|
||||
|
||||
/**
|
||||
* Convert the provided source object argument to an instance of the specified target class.
|
||||
* @param source the source object to convert, which must be an instance of {@link #getSourceClass()}
|
||||
* @param targetClass the target class to convert the source to, which must be equal to or a specialization of
|
||||
* {@link #getTargetClass()}
|
||||
* @return the converted object, which must be an instance of the <code>targetClass</code>
|
||||
* @throws Exception an exception occurred performing the conversion
|
||||
*/
|
||||
public Object convertSourceToTargetClass(Object source, Class targetClass) throws Exception;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,125 @@
|
||||
/*
|
||||
* Copyright 2004-2008 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.binding.convert.converters;
|
||||
|
||||
import java.text.DecimalFormat;
|
||||
import java.text.NumberFormat;
|
||||
import java.text.ParsePosition;
|
||||
import java.util.Locale;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.springframework.binding.format.DefaultNumberFormatFactory;
|
||||
import org.springframework.binding.format.NumberFormatFactory;
|
||||
import org.springframework.util.NumberUtils;
|
||||
|
||||
/**
|
||||
* A converter for common number types such as integers and big decimals. Allows the configuration of an explicit number
|
||||
* pattern and locale.
|
||||
*
|
||||
* Works with a general purpose {@link DecimalFormat} instance returned by calling
|
||||
* {@link NumberFormat#getInstance(Locale)} by default. This instance supports parsing any number type generally and
|
||||
* will not perform special type-specific logic such as rounding or truncation. Subclasses may override.
|
||||
*
|
||||
* Will coerse parsed Numbers to the desired numberClass as necessary. If type-coersion results in an overflow
|
||||
* condition; for example, what can occur with a Long being coersed to a Short, an exception will be thrown.
|
||||
*
|
||||
* @see NumberFormat
|
||||
* @see DecimalFormat
|
||||
*
|
||||
* @author Keith Donald
|
||||
*/
|
||||
public class FormattedStringToNumber extends StringToObject {
|
||||
|
||||
private static Log logger = LogFactory.getLog(FormattedStringToNumber.class);
|
||||
|
||||
private NumberFormatFactory numberFormatFactory = new DefaultNumberFormatFactory();
|
||||
|
||||
private boolean lenient;
|
||||
|
||||
public FormattedStringToNumber(Class numberClass) {
|
||||
super(numberClass);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the factory that returns the {@link NumberFormat} instance that will format numbers handled by this
|
||||
* converter.
|
||||
* @param numberFormatFactory the number format factory
|
||||
*/
|
||||
public void setNumberFormatFactory(NumberFormatFactory numberFormatFactory) {
|
||||
this.numberFormatFactory = numberFormatFactory;
|
||||
}
|
||||
|
||||
/**
|
||||
* If this Converter is "lenient" in parsing number strings. A lenient converter does not require that all
|
||||
* characters in the String be parsed successfully. Default is false.
|
||||
* @return the lenient flag
|
||||
*/
|
||||
public boolean getLenient() {
|
||||
return lenient;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets if this Converter should parse leniently.
|
||||
* @param lenient the lenient flag
|
||||
*/
|
||||
public void setLenient(boolean lenient) {
|
||||
this.lenient = lenient;
|
||||
}
|
||||
|
||||
protected Object toObject(String string, Class targetClass) throws Exception {
|
||||
ParsePosition parsePosition = new ParsePosition(0);
|
||||
NumberFormat format = numberFormatFactory.getNumberFormat();
|
||||
Number number = format.parse(string, parsePosition);
|
||||
if (number == null) {
|
||||
// no object could be parsed
|
||||
throw new InvalidFormatException(string, getPattern(format));
|
||||
}
|
||||
if (!lenient) {
|
||||
if (string.length() != parsePosition.getIndex()) {
|
||||
// indicates a part of the string that was not parsed; e.g. ".5" in 1234.5 when parsing an Integer
|
||||
throw new InvalidFormatException(string, getPattern(format));
|
||||
}
|
||||
}
|
||||
return convertToNumberClass(number, targetClass);
|
||||
}
|
||||
|
||||
protected String toString(Object object) throws Exception {
|
||||
Number number = (Number) object;
|
||||
return numberFormatFactory.getNumberFormat().format(number);
|
||||
}
|
||||
|
||||
/**
|
||||
* Coerces the Number object returned by NumberFormat to the desired numberClass. Subclasses may override.
|
||||
* @param number the parsed number
|
||||
* @return the coersed number
|
||||
* @throws IllegalArgumentException when an overflow condition occurs during coersion
|
||||
*/
|
||||
protected Number convertToNumberClass(Number number, Class numberClass) throws IllegalArgumentException {
|
||||
return NumberUtils.convertNumberToTargetClass(number, numberClass);
|
||||
}
|
||||
|
||||
// internal helpers
|
||||
|
||||
private String getPattern(NumberFormat format) {
|
||||
if (format instanceof DecimalFormat) {
|
||||
return ((DecimalFormat) format).toPattern();
|
||||
} else {
|
||||
logger.warn("Pattern string cannot be determined because NumberFormat is not a DecimalFormat");
|
||||
return "defaultNumberFormatInstance";
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,59 +0,0 @@
|
||||
/*
|
||||
* Copyright 2004-2008 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.binding.convert.converters;
|
||||
|
||||
import org.springframework.binding.convert.Converter;
|
||||
import org.springframework.binding.format.Formatter;
|
||||
|
||||
/**
|
||||
* Adapts a Formatter to the Converter interface. Allows a Formatter to be used as a Converter. Allows for both the
|
||||
* to-string and from-string logic to be used.
|
||||
*
|
||||
* @see Formatter
|
||||
* @see Formatter#format(Object)
|
||||
* @see Formatter#parse(String)
|
||||
*
|
||||
* @author Keith Donald
|
||||
*/
|
||||
public class FormatterConverter implements Converter {
|
||||
|
||||
private Formatter formatter;
|
||||
|
||||
/**
|
||||
* Creates a new formatter converter.
|
||||
* @param formatter the formatter instance to adapt to the Converter API
|
||||
*/
|
||||
public FormatterConverter(Formatter formatter) {
|
||||
this.formatter = formatter;
|
||||
}
|
||||
|
||||
public Class[] getSourceClasses() {
|
||||
return new Class[] { formatter.getObjectType(), String.class };
|
||||
}
|
||||
|
||||
public Class[] getTargetClasses() {
|
||||
return new Class[] { String.class, formatter.getObjectType() };
|
||||
}
|
||||
|
||||
public Object convert(Object source, Class targetClass, Object context) throws Exception {
|
||||
if (targetClass.equals(String.class)) {
|
||||
return formatter.format(source);
|
||||
} else {
|
||||
return formatter.parse((String) source);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -13,7 +13,7 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.binding.format;
|
||||
package org.springframework.binding.convert.converters;
|
||||
|
||||
/**
|
||||
* Thrown when a formatted value is of the wrong form.
|
||||
@@ -0,0 +1,72 @@
|
||||
package org.springframework.binding.convert.converters;
|
||||
|
||||
import java.lang.reflect.Array;
|
||||
|
||||
import org.springframework.binding.convert.ConversionExecutor;
|
||||
import org.springframework.binding.convert.ConversionService;
|
||||
|
||||
public class ObjectToArray implements TwoWayConverter {
|
||||
|
||||
private ConversionService conversionService;
|
||||
|
||||
public ObjectToArray(ConversionService conversionService) {
|
||||
this.conversionService = conversionService;
|
||||
}
|
||||
|
||||
public Class getSourceClass() {
|
||||
return Object.class;
|
||||
}
|
||||
|
||||
public Class getTargetClass() {
|
||||
return Object[].class;
|
||||
}
|
||||
|
||||
public Object convertSourceToTargetClass(Object source, Class targetClass) throws Exception {
|
||||
if (source == null) {
|
||||
return null;
|
||||
}
|
||||
if (source instanceof String) {
|
||||
String string = (String) source;
|
||||
String[] elements = string.split(",");
|
||||
Class componentType = targetClass.getComponentType();
|
||||
Object array = Array.newInstance(componentType, elements.length);
|
||||
ConversionExecutor converter = conversionService.getConversionExecutor(String.class, componentType);
|
||||
for (int i = 0; i < elements.length; i++) {
|
||||
String element = elements[i].trim();
|
||||
Array.set(array, i, converter.execute(element));
|
||||
}
|
||||
return array;
|
||||
} else {
|
||||
Class componentType = targetClass.getComponentType();
|
||||
Object array = Array.newInstance(componentType, 1);
|
||||
ConversionExecutor converter = conversionService.getConversionExecutor(source.getClass(), componentType);
|
||||
Array.set(array, 0, converter.execute(source));
|
||||
return array;
|
||||
}
|
||||
}
|
||||
|
||||
public Object convertTargetToSourceClass(Object target, Class sourceClass) throws Exception {
|
||||
if (target == null) {
|
||||
return null;
|
||||
}
|
||||
if (String.class.equals(sourceClass)) {
|
||||
int length = Array.getLength(target);
|
||||
Class componentType = target.getClass().getComponentType();
|
||||
ConversionExecutor converter = conversionService.getConversionExecutor(componentType, String.class);
|
||||
StringBuffer buffer = new StringBuffer();
|
||||
for (int i = 0; i < length; i++) {
|
||||
Object value = Array.get(target, i);
|
||||
buffer.append(converter.execute(value));
|
||||
if (i < length) {
|
||||
buffer.append(",");
|
||||
}
|
||||
}
|
||||
} else {
|
||||
Object value = Array.get(target, 0);
|
||||
Class componentType = target.getClass().getComponentType();
|
||||
ConversionExecutor converter = conversionService.getConversionExecutor(componentType, sourceClass);
|
||||
return converter.execute(value);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
package org.springframework.binding.convert.converters;
|
||||
|
||||
public class ReverseConverter implements Converter {
|
||||
|
||||
private TwoWayConverter converter;
|
||||
|
||||
public ReverseConverter(TwoWayConverter converter) {
|
||||
this.converter = converter;
|
||||
}
|
||||
|
||||
public Class getSourceClass() {
|
||||
return converter.getTargetClass();
|
||||
}
|
||||
|
||||
public Class getTargetClass() {
|
||||
return converter.getSourceClass();
|
||||
}
|
||||
|
||||
public Object convertSourceToTargetClass(Object source, Class targetClass) throws Exception {
|
||||
return converter.convertTargetToSourceClass(source, targetClass);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -16,30 +16,25 @@
|
||||
package org.springframework.binding.convert.converters;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.math.BigInteger;
|
||||
|
||||
import org.springframework.binding.convert.Converter;
|
||||
import org.springframework.util.NumberUtils;
|
||||
|
||||
/**
|
||||
* Converts textual representations of numbers to a <code>Number</code> specialization. Delegates to a synchronized
|
||||
* formatter to parse text strings.
|
||||
* Converts a String to a BigDecimal.
|
||||
*
|
||||
* @author Keith Donald
|
||||
*/
|
||||
public class TextToNumber implements Converter {
|
||||
public class StringToBigDecimal extends StringToObject {
|
||||
|
||||
public Class[] getSourceClasses() {
|
||||
return new Class[] { String.class };
|
||||
public StringToBigDecimal() {
|
||||
super(BigDecimal.class);
|
||||
}
|
||||
|
||||
public Class[] getTargetClasses() {
|
||||
return new Class[] { Integer.class, Short.class, Long.class, Float.class, Double.class, Byte.class,
|
||||
BigInteger.class, BigDecimal.class };
|
||||
public Object toObject(String string, Class objectClass) throws Exception {
|
||||
return new BigDecimal(string);
|
||||
}
|
||||
|
||||
public Object convert(Object source, Class targetClass, Object context) throws Exception {
|
||||
return NumberUtils.parseNumber((String) source, targetClass);
|
||||
public String toString(Object object) throws Exception {
|
||||
BigDecimal number = (BigDecimal) object;
|
||||
return number.toString();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
/*
|
||||
* Copyright 2004-2008 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.binding.convert.converters;
|
||||
|
||||
import java.math.BigInteger;
|
||||
|
||||
/**
|
||||
* Converts a String to a BigInteger.
|
||||
*
|
||||
* @author Keith Donald
|
||||
*/
|
||||
public class StringToBigInteger extends StringToObject {
|
||||
|
||||
public StringToBigInteger() {
|
||||
super(BigInteger.class);
|
||||
}
|
||||
|
||||
public Object toObject(String string, Class objectClass) throws Exception {
|
||||
return new BigInteger(string);
|
||||
}
|
||||
|
||||
public String toString(Object object) throws Exception {
|
||||
BigInteger number = (BigInteger) object;
|
||||
return number.toString();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,84 @@
|
||||
/*
|
||||
* Copyright 2004-2008 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.binding.convert.converters;
|
||||
|
||||
/**
|
||||
* Converts a textual representation of a boolean object to a <code>Boolean</code> instance.
|
||||
*
|
||||
* @author Keith Donald
|
||||
*/
|
||||
public class StringToBoolean extends StringToObject {
|
||||
|
||||
private static final String VALUE_TRUE = "true";
|
||||
|
||||
private static final String VALUE_FALSE = "false";
|
||||
|
||||
private String trueString;
|
||||
|
||||
private String falseString;
|
||||
|
||||
/**
|
||||
* Create a text boolean converter that parses standard true and false strings.
|
||||
*/
|
||||
public StringToBoolean() {
|
||||
super(Boolean.class);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a text to boolean converter that takes specific string representations of true and false into account.
|
||||
* @param trueString special true string to use
|
||||
* @param falseString special false string to use
|
||||
*/
|
||||
public StringToBoolean(String trueString, String falseString) {
|
||||
super(Boolean.class);
|
||||
this.trueString = trueString;
|
||||
this.falseString = falseString;
|
||||
}
|
||||
|
||||
protected Object toObject(String string, Class targetClass) throws Exception {
|
||||
if (trueString != null && string.equals(trueString)) {
|
||||
return Boolean.TRUE;
|
||||
} else if (falseString != null && string.equals(falseString)) {
|
||||
return Boolean.FALSE;
|
||||
} else if (trueString == null && string.equals(VALUE_TRUE)) {
|
||||
return Boolean.TRUE;
|
||||
} else if (falseString == null && string.equals(VALUE_FALSE)) {
|
||||
return Boolean.FALSE;
|
||||
} else {
|
||||
throw new IllegalArgumentException("Invalid boolean value [" + string + "]");
|
||||
}
|
||||
}
|
||||
|
||||
protected String toString(Object object) throws Exception {
|
||||
Boolean value = (Boolean) object;
|
||||
if (Boolean.TRUE.equals(value)) {
|
||||
if (trueString != null) {
|
||||
return trueString;
|
||||
} else {
|
||||
return VALUE_TRUE;
|
||||
}
|
||||
} else if (Boolean.FALSE.equals(value)) {
|
||||
if (falseString != null) {
|
||||
return falseString;
|
||||
} else {
|
||||
return VALUE_FALSE;
|
||||
}
|
||||
} else {
|
||||
throw new IllegalArgumentException("Invalid boolean value [" + value + "]");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
/*
|
||||
* Copyright 2004-2008 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.binding.convert.converters;
|
||||
|
||||
/**
|
||||
* Converts a String to a BigInteger.
|
||||
*
|
||||
* @author Keith Donald
|
||||
*/
|
||||
public class StringToByte extends StringToObject {
|
||||
|
||||
public StringToByte() {
|
||||
super(Byte.class);
|
||||
}
|
||||
|
||||
public Object toObject(String string, Class objectClass) throws Exception {
|
||||
return Byte.valueOf(string);
|
||||
}
|
||||
|
||||
public String toString(Object object) throws Exception {
|
||||
Byte number = (Byte) object;
|
||||
return number.toString();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
package org.springframework.binding.convert.converters;
|
||||
|
||||
public class StringToCharacter extends StringToObject {
|
||||
|
||||
public StringToCharacter() {
|
||||
super(Character.class);
|
||||
}
|
||||
|
||||
protected Object toObject(String string, Class targetClass) throws Exception {
|
||||
return new Character(string.charAt(0));
|
||||
}
|
||||
|
||||
protected String toString(Object object) throws Exception {
|
||||
Character character = (Character) object;
|
||||
return character.toString();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
/*
|
||||
* Copyright 2004-2008 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.binding.convert.converters;
|
||||
|
||||
import org.springframework.util.ClassUtils;
|
||||
|
||||
/**
|
||||
* Converts a textual representation of a class object to a <code>Class</code> instance.
|
||||
*
|
||||
* @author Keith Donald
|
||||
*/
|
||||
public class StringToClass extends StringToObject {
|
||||
|
||||
public StringToClass() {
|
||||
super(Class.class);
|
||||
}
|
||||
|
||||
public Object toObject(String string, Class objectClass) throws Exception {
|
||||
return ClassUtils.forName(string);
|
||||
}
|
||||
|
||||
public String toString(Object object) throws Exception {
|
||||
Class clazz = (Class) object;
|
||||
return clazz.getName();
|
||||
}
|
||||
}
|
||||
@@ -13,7 +13,7 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.binding.format.formatters;
|
||||
package org.springframework.binding.convert.converters;
|
||||
|
||||
import java.text.DateFormat;
|
||||
import java.text.ParseException;
|
||||
@@ -23,10 +23,7 @@ import java.util.Locale;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.springframework.binding.format.Formatter;
|
||||
import org.springframework.binding.format.InvalidFormatException;
|
||||
import org.springframework.context.i18n.LocaleContextHolder;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
/**
|
||||
@@ -34,9 +31,9 @@ import org.springframework.util.StringUtils;
|
||||
* @see SimpleDateFormat
|
||||
* @author Keith Donald
|
||||
*/
|
||||
public class DateFormatter implements Formatter {
|
||||
public class StringToDate extends StringToObject {
|
||||
|
||||
private static Log logger = LogFactory.getLog(DateFormatter.class);
|
||||
private static Log logger = LogFactory.getLog(StringToDate.class);
|
||||
|
||||
/**
|
||||
* The default date pattern.
|
||||
@@ -47,6 +44,10 @@ public class DateFormatter implements Formatter {
|
||||
|
||||
private Locale locale;
|
||||
|
||||
public StringToDate() {
|
||||
super(Date.class);
|
||||
}
|
||||
|
||||
/**
|
||||
* The pattern to use to format date values. If not specified, the default pattern 'yyyy-MM-dd' is used.
|
||||
* @return the date formatting pattern
|
||||
@@ -80,32 +81,26 @@ public class DateFormatter implements Formatter {
|
||||
this.locale = locale;
|
||||
}
|
||||
|
||||
// implementing Formatter
|
||||
|
||||
public Class getObjectType() {
|
||||
return Date.class;
|
||||
}
|
||||
|
||||
public String format(Object date) {
|
||||
if (date == null) {
|
||||
return "";
|
||||
}
|
||||
Assert.isInstanceOf(Date.class, date, "Object is not a [java.util.Date]");
|
||||
return getDateFormat().format((Date) date);
|
||||
}
|
||||
|
||||
public Object parse(String formattedString) throws InvalidFormatException {
|
||||
if (!StringUtils.hasText(formattedString)) {
|
||||
public Object toObject(String string, Class targetClass) throws Exception {
|
||||
if (!StringUtils.hasText(string)) {
|
||||
return null;
|
||||
}
|
||||
DateFormat dateFormat = getDateFormat();
|
||||
try {
|
||||
return dateFormat.parse(formattedString);
|
||||
return dateFormat.parse(string);
|
||||
} catch (ParseException e) {
|
||||
throw new InvalidFormatException(formattedString, getPattern(dateFormat), e);
|
||||
throw new InvalidFormatException(string, getPattern(dateFormat), e);
|
||||
}
|
||||
}
|
||||
|
||||
public String toString(Object target) throws Exception {
|
||||
Date date = (Date) target;
|
||||
if (date == null) {
|
||||
return "";
|
||||
}
|
||||
return getDateFormat().format(date);
|
||||
}
|
||||
|
||||
// subclassing hookings
|
||||
|
||||
protected DateFormat getDateFormat() {
|
||||
@@ -0,0 +1,38 @@
|
||||
/*
|
||||
* Copyright 2004-2008 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.binding.convert.converters;
|
||||
|
||||
/**
|
||||
* Converts a String to an Short using {@link Short#valueOf(String)}.
|
||||
*
|
||||
* @author Keith Donald
|
||||
*/
|
||||
public class StringToDouble extends StringToObject {
|
||||
|
||||
public StringToDouble() {
|
||||
super(Double.class);
|
||||
}
|
||||
|
||||
public Object toObject(String string, Class objectClass) throws Exception {
|
||||
return Double.valueOf(string);
|
||||
}
|
||||
|
||||
public String toString(Object object) throws Exception {
|
||||
Double number = (Double) object;
|
||||
return number.toString();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
/*
|
||||
* Copyright 2004-2008 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.binding.convert.converters;
|
||||
|
||||
/**
|
||||
* Converts a String to an Short using {@link Short#valueOf(String)}.
|
||||
*
|
||||
* @author Keith Donald
|
||||
*/
|
||||
public class StringToFloat extends StringToObject {
|
||||
|
||||
public StringToFloat() {
|
||||
super(Float.class);
|
||||
}
|
||||
|
||||
public Object toObject(String string, Class objectClass) throws Exception {
|
||||
return Float.valueOf(string);
|
||||
}
|
||||
|
||||
public String toString(Object object) throws Exception {
|
||||
Float number = (Float) object;
|
||||
return number.toString();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
/*
|
||||
* Copyright 2004-2008 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.binding.convert.converters;
|
||||
|
||||
/**
|
||||
* Converts a String to an Integer using {@link Integer#valueOf(String)}.
|
||||
*
|
||||
* @author Keith Donald
|
||||
*/
|
||||
public class StringToInteger extends StringToObject {
|
||||
|
||||
public StringToInteger() {
|
||||
super(Integer.class);
|
||||
}
|
||||
|
||||
public Object toObject(String string, Class objectClass) throws Exception {
|
||||
return Integer.valueOf(string);
|
||||
}
|
||||
|
||||
public String toString(Object object) throws Exception {
|
||||
Integer number = (Integer) object;
|
||||
return number.toString();
|
||||
}
|
||||
}
|
||||
@@ -15,7 +15,6 @@
|
||||
*/
|
||||
package org.springframework.binding.convert.converters;
|
||||
|
||||
import org.springframework.binding.convert.Converter;
|
||||
import org.springframework.core.enums.LabeledEnum;
|
||||
import org.springframework.core.enums.LabeledEnumResolver;
|
||||
import org.springframework.core.enums.StaticLabeledEnumResolver;
|
||||
@@ -25,20 +24,21 @@ import org.springframework.core.enums.StaticLabeledEnumResolver;
|
||||
*
|
||||
* @author Keith Donald
|
||||
*/
|
||||
public class TextToLabeledEnum implements Converter {
|
||||
public class StringToLabeledEnum extends StringToObject {
|
||||
|
||||
private LabeledEnumResolver labeledEnumResolver = StaticLabeledEnumResolver.instance();
|
||||
|
||||
public Class[] getSourceClasses() {
|
||||
return new Class[] { String.class };
|
||||
public StringToLabeledEnum() {
|
||||
super(LabeledEnum.class);
|
||||
}
|
||||
|
||||
public Class[] getTargetClasses() {
|
||||
return new Class[] { LabeledEnum.class };
|
||||
protected Object toObject(String string, Class targetClass) throws Exception {
|
||||
return labeledEnumResolver.getLabeledEnumByLabel(targetClass, string);
|
||||
}
|
||||
|
||||
public Object convert(Object source, Class targetClass, Object context) throws Exception {
|
||||
String label = (String) source;
|
||||
return labeledEnumResolver.getLabeledEnumByLabel(targetClass, label);
|
||||
protected String toString(Object object) throws Exception {
|
||||
LabeledEnum labeledEnum = (LabeledEnum) object;
|
||||
return labeledEnum.getLabel();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
/*
|
||||
* Copyright 2004-2008 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.binding.convert.converters;
|
||||
|
||||
/**
|
||||
* Converts a String to an Long using {@link Long#valueOf(String)}.
|
||||
*
|
||||
* @author Keith Donald
|
||||
*/
|
||||
public class StringToLong extends StringToObject {
|
||||
|
||||
public StringToLong() {
|
||||
super(Long.class);
|
||||
}
|
||||
|
||||
public Object toObject(String string, Class objectClass) throws Exception {
|
||||
return Long.valueOf(string);
|
||||
}
|
||||
|
||||
public String toString(Object object) throws Exception {
|
||||
Long number = (Long) object;
|
||||
return number.toString();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
package org.springframework.binding.convert.converters;
|
||||
|
||||
public abstract class StringToObject implements TwoWayConverter {
|
||||
|
||||
private Class objectClass;
|
||||
|
||||
public StringToObject(Class objectClass) {
|
||||
this.objectClass = objectClass;
|
||||
}
|
||||
|
||||
public final Class getSourceClass() {
|
||||
return String.class;
|
||||
}
|
||||
|
||||
public final Class getTargetClass() {
|
||||
return objectClass;
|
||||
}
|
||||
|
||||
public final Object convertSourceToTargetClass(Object source, Class targetClass) throws Exception {
|
||||
String string = (String) source;
|
||||
if (string != null && string.length() > 0) {
|
||||
return toObject(string, targetClass);
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public final Object convertTargetToSourceClass(Object target, Class sourceClass) throws Exception {
|
||||
if (target != null) {
|
||||
return toString(target);
|
||||
} else {
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
protected abstract Object toObject(String string, Class targetClass) throws Exception;
|
||||
|
||||
protected abstract String toString(Object object) throws Exception;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
/*
|
||||
* Copyright 2004-2008 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.binding.convert.converters;
|
||||
|
||||
/**
|
||||
* Converts a String to an Short using {@link Short#valueOf(String)}.
|
||||
*
|
||||
* @author Keith Donald
|
||||
*/
|
||||
public class StringToShort extends StringToObject {
|
||||
|
||||
public StringToShort() {
|
||||
super(Short.class);
|
||||
}
|
||||
|
||||
public Object toObject(String string, Class objectClass) throws Exception {
|
||||
return Short.valueOf(string);
|
||||
}
|
||||
|
||||
public String toString(Object object) throws Exception {
|
||||
Short number = (Short) object;
|
||||
return number.toString();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,94 +0,0 @@
|
||||
/*
|
||||
* Copyright 2004-2008 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.binding.convert.converters;
|
||||
|
||||
import org.springframework.binding.convert.Converter;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
/**
|
||||
* Converts a textual representation of a boolean object to a <code>Boolean</code> instance.
|
||||
*
|
||||
* @author Keith Donald
|
||||
*/
|
||||
public class TextToBoolean implements Converter {
|
||||
|
||||
private static final String VALUE_TRUE = "true";
|
||||
|
||||
private static final String VALUE_FALSE = "false";
|
||||
|
||||
private static final String VALUE_ON = "on";
|
||||
|
||||
private static final String VALUE_OFF = "off";
|
||||
|
||||
private static final String VALUE_YES = "yes";
|
||||
|
||||
private static final String VALUE_NO = "no";
|
||||
|
||||
private static final String VALUE_1 = "1";
|
||||
|
||||
private static final String VALUE_0 = "0";
|
||||
|
||||
private String trueString;
|
||||
|
||||
private String falseString;
|
||||
|
||||
/**
|
||||
* Default constructor. No special true or false strings are considered.
|
||||
*/
|
||||
public TextToBoolean() {
|
||||
this(null, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* 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
|
||||
*/
|
||||
public TextToBoolean(String trueString, String falseString) {
|
||||
this.trueString = trueString;
|
||||
this.falseString = falseString;
|
||||
}
|
||||
|
||||
public Class[] getSourceClasses() {
|
||||
return new Class[] { String.class };
|
||||
}
|
||||
|
||||
public Class[] getTargetClasses() {
|
||||
return new Class[] { Boolean.class };
|
||||
}
|
||||
|
||||
public Object convert(Object source, Class targetClass, Object context) throws Exception {
|
||||
String text = (String) source;
|
||||
if (!StringUtils.hasText(text)) {
|
||||
return null;
|
||||
} else if (this.trueString != null && text.equalsIgnoreCase(this.trueString)) {
|
||||
return Boolean.TRUE;
|
||||
} else if (this.falseString != null && text.equalsIgnoreCase(this.falseString)) {
|
||||
return Boolean.FALSE;
|
||||
} 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
|
||||
&& (text.equalsIgnoreCase(VALUE_FALSE) || text.equalsIgnoreCase(VALUE_OFF)
|
||||
|| text.equalsIgnoreCase(VALUE_NO) || text.equals(VALUE_0))) {
|
||||
return Boolean.FALSE;
|
||||
} else {
|
||||
throw new IllegalArgumentException("Invalid boolean value [" + text + "]");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,85 +0,0 @@
|
||||
/*
|
||||
* Copyright 2004-2008 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.binding.convert.converters;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.math.BigInteger;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import org.springframework.binding.convert.Converter;
|
||||
import org.springframework.core.enums.LabeledEnum;
|
||||
import org.springframework.util.ClassUtils;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
/**
|
||||
* Converts a textual representation of a class object to a <code>Class</code> instance.
|
||||
*
|
||||
* @author Keith Donald
|
||||
*/
|
||||
public class TextToClass implements Converter {
|
||||
|
||||
private Map aliasMap = new HashMap();
|
||||
|
||||
public TextToClass() {
|
||||
addDefaultAliases();
|
||||
}
|
||||
|
||||
/**
|
||||
* Add an alias for given target type.
|
||||
*/
|
||||
public void addAlias(String alias, Class targetType) {
|
||||
aliasMap.put(alias, targetType);
|
||||
}
|
||||
|
||||
public Class[] getSourceClasses() {
|
||||
return new Class[] { String.class };
|
||||
}
|
||||
|
||||
public Class[] getTargetClasses() {
|
||||
return new Class[] { Class.class };
|
||||
}
|
||||
|
||||
public Object convert(Object source, Class targetClass, Object context) throws Exception {
|
||||
String text = (String) source;
|
||||
if (StringUtils.hasText(text)) {
|
||||
text = text.trim();
|
||||
if (aliasMap.containsKey(text)) {
|
||||
return aliasMap.get(text);
|
||||
} else {
|
||||
return ClassUtils.forName(text);
|
||||
}
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
protected void addDefaultAliases() {
|
||||
addAlias("string", String.class);
|
||||
addAlias("short", Short.class);
|
||||
addAlias("integer", Integer.class);
|
||||
addAlias("int", Integer.class);
|
||||
addAlias("byte", Byte.class);
|
||||
addAlias("long", Long.class);
|
||||
addAlias("float", Float.class);
|
||||
addAlias("double", Double.class);
|
||||
addAlias("bigInteger", BigInteger.class);
|
||||
addAlias("bigDecimal", BigDecimal.class);
|
||||
addAlias("boolean", Boolean.class);
|
||||
addAlias("class", Class.class);
|
||||
addAlias("labeledEnum", LabeledEnum.class);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
/*
|
||||
* Copyright 2004-2008 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.binding.convert.converters;
|
||||
|
||||
/**
|
||||
* A converter that can also convert from the target back to the source.
|
||||
*
|
||||
* @author Keith Donald
|
||||
*/
|
||||
public interface TwoWayConverter extends Converter {
|
||||
|
||||
/**
|
||||
* Convert the provided target object argument to an instance of the specified source class.
|
||||
* @param target the target object to convert, which must be an instance of {@link #getTargetClass()}
|
||||
* @param sourceClass the source class to convert the target to, which must be equal to or a specialization of
|
||||
* {@link #getSourceClass()}
|
||||
* @return the converted object, which must be an instance of the <code>sourceClass</code>
|
||||
* @throws Exception an exception occurred performing the conversion
|
||||
*/
|
||||
public Object convertTargetToSourceClass(Object target, Class sourceClass) throws Exception;
|
||||
|
||||
}
|
||||
@@ -16,10 +16,19 @@
|
||||
package org.springframework.binding.convert.service;
|
||||
|
||||
import org.springframework.binding.convert.ConversionService;
|
||||
import org.springframework.binding.convert.converters.TextToBoolean;
|
||||
import org.springframework.binding.convert.converters.TextToClass;
|
||||
import org.springframework.binding.convert.converters.TextToLabeledEnum;
|
||||
import org.springframework.binding.convert.converters.TextToNumber;
|
||||
import org.springframework.binding.convert.converters.StringToBigDecimal;
|
||||
import org.springframework.binding.convert.converters.StringToBigInteger;
|
||||
import org.springframework.binding.convert.converters.StringToBoolean;
|
||||
import org.springframework.binding.convert.converters.StringToByte;
|
||||
import org.springframework.binding.convert.converters.StringToCharacter;
|
||||
import org.springframework.binding.convert.converters.StringToClass;
|
||||
import org.springframework.binding.convert.converters.StringToDate;
|
||||
import org.springframework.binding.convert.converters.StringToDouble;
|
||||
import org.springframework.binding.convert.converters.StringToFloat;
|
||||
import org.springframework.binding.convert.converters.StringToInteger;
|
||||
import org.springframework.binding.convert.converters.StringToLabeledEnum;
|
||||
import org.springframework.binding.convert.converters.StringToLong;
|
||||
import org.springframework.binding.convert.converters.StringToShort;
|
||||
|
||||
/**
|
||||
* Default, local implementation of a conversion service. Will automatically register <i>from string</i> converters for
|
||||
@@ -45,10 +54,19 @@ public class DefaultConversionService extends GenericConversionService {
|
||||
* Add all default converters to the conversion service.
|
||||
*/
|
||||
protected void addDefaultConverters() {
|
||||
addConverter(new TextToClass());
|
||||
addConverter(new TextToBoolean());
|
||||
addConverter(new TextToLabeledEnum());
|
||||
addConverter(new TextToNumber());
|
||||
addConverter(new StringToByte());
|
||||
addConverter(new StringToBoolean());
|
||||
addConverter(new StringToCharacter());
|
||||
addConverter(new StringToShort());
|
||||
addConverter(new StringToInteger());
|
||||
addConverter(new StringToLong());
|
||||
addConverter(new StringToFloat());
|
||||
addConverter(new StringToDouble());
|
||||
addConverter(new StringToBigInteger());
|
||||
addConverter(new StringToBigDecimal());
|
||||
addConverter(new StringToClass());
|
||||
addConverter(new StringToLabeledEnum());
|
||||
addConverter(new StringToDate());
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -15,6 +15,8 @@
|
||||
*/
|
||||
package org.springframework.binding.convert.service;
|
||||
|
||||
import java.lang.reflect.Modifier;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.LinkedList;
|
||||
@@ -23,7 +25,12 @@ import java.util.Map;
|
||||
import org.springframework.binding.convert.ConversionExecutor;
|
||||
import org.springframework.binding.convert.ConversionExecutorNotFoundException;
|
||||
import org.springframework.binding.convert.ConversionService;
|
||||
import org.springframework.binding.convert.Converter;
|
||||
import org.springframework.binding.convert.converters.ArrayToArray;
|
||||
import org.springframework.binding.convert.converters.ArrayToCollection;
|
||||
import org.springframework.binding.convert.converters.Converter;
|
||||
import org.springframework.binding.convert.converters.ObjectToArray;
|
||||
import org.springframework.binding.convert.converters.ReverseConverter;
|
||||
import org.springframework.binding.convert.converters.TwoWayConverter;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
/**
|
||||
@@ -35,8 +42,8 @@ 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.
|
||||
* is a map of target classes that can be converted to, ultimately mapping to a specific converter that can perform
|
||||
* the source->target conversion.
|
||||
*/
|
||||
private Map sourceClassConverters = new HashMap();
|
||||
|
||||
@@ -64,36 +71,65 @@ public class GenericConversionService implements ConversionService {
|
||||
* @param converter the converter
|
||||
*/
|
||||
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);
|
||||
if (sourceMap == null) {
|
||||
sourceMap = new HashMap();
|
||||
sourceClassConverters.put(sourceClass, sourceMap);
|
||||
}
|
||||
for (int j = 0; j < targetClasses.length; j++) {
|
||||
Class targetClass = targetClasses[j];
|
||||
if (!targetClass.equals(sourceClass)) {
|
||||
sourceMap.put(targetClass, converter);
|
||||
}
|
||||
}
|
||||
Class sourceClass = converter.getSourceClass();
|
||||
Class targetClass = converter.getTargetClass();
|
||||
if (sourceClass.isPrimitive()) {
|
||||
throw new IllegalArgumentException("Invalid Converter " + converter
|
||||
+ "; A primitive type is not allowed for the [sourceClass] argument");
|
||||
}
|
||||
if (targetClass.isPrimitive()) {
|
||||
throw new IllegalArgumentException("Invalid Converter " + converter
|
||||
+ "; A primitive type is not allowed for the [targetClass] argument");
|
||||
}
|
||||
Map sourceMap = getSourceMap(sourceClass);
|
||||
sourceMap.put(targetClass, converter);
|
||||
if (converter instanceof TwoWayConverter) {
|
||||
sourceMap = getSourceMap(targetClass);
|
||||
sourceMap.put(sourceClass, new ReverseConverter((TwoWayConverter) converter));
|
||||
}
|
||||
}
|
||||
|
||||
private Map getSourceMap(Class sourceClass) {
|
||||
Map sourceMap = (Map) sourceClassConverters.get(sourceClass);
|
||||
if (sourceMap == null) {
|
||||
sourceMap = new HashMap();
|
||||
sourceClassConverters.put(sourceClass, sourceMap);
|
||||
}
|
||||
return sourceMap;
|
||||
}
|
||||
|
||||
public ConversionExecutor getConversionExecutor(Class sourceClass, Class targetClass)
|
||||
throws ConversionExecutorNotFoundException {
|
||||
Assert.notNull(sourceClass, "The source class to convert from is required");
|
||||
Assert.notNull(targetClass, "The target class to convert to is required");
|
||||
if (sourceClassConverters == null || sourceClassConverters.isEmpty()) {
|
||||
throw new IllegalStateException("No converters have been added to this service's registry");
|
||||
}
|
||||
sourceClass = convertToWrapperClassIfNecessary(sourceClass);
|
||||
targetClass = convertToWrapperClassIfNecessary(targetClass);
|
||||
if (targetClass.isAssignableFrom(sourceClass)) {
|
||||
return new StaticConversionExecutor(sourceClass, targetClass, new NoOpConverter(sourceClass, targetClass));
|
||||
}
|
||||
if (sourceClass.isArray()) {
|
||||
if (targetClass.isArray()) {
|
||||
return new StaticConversionExecutor(sourceClass, targetClass, new ArrayToArray(this));
|
||||
} else if (Collection.class.isAssignableFrom(targetClass)) {
|
||||
if (!targetClass.isInterface() && Modifier.isAbstract(targetClass.getModifiers())) {
|
||||
throw new IllegalArgumentException("Conversion target class [" + targetClass.getName()
|
||||
+ "] is invalid; cannot convert to abstract collection types--"
|
||||
+ "request an interface or concrete implementation instead");
|
||||
}
|
||||
return new StaticConversionExecutor(sourceClass, targetClass, new ArrayToCollection(this));
|
||||
} else {
|
||||
Converter arrayToObject = new ReverseConverter(new ObjectToArray(this));
|
||||
return new StaticConversionExecutor(sourceClass, targetClass, arrayToObject);
|
||||
}
|
||||
}
|
||||
if (targetClass.isArray()) {
|
||||
if (Collection.class.isAssignableFrom(sourceClass)) {
|
||||
Converter collectionToArray = new ReverseConverter(new ArrayToCollection(this));
|
||||
return new StaticConversionExecutor(sourceClass, targetClass, collectionToArray);
|
||||
} else {
|
||||
return new StaticConversionExecutor(sourceClass, targetClass, new ObjectToArray(this));
|
||||
}
|
||||
}
|
||||
Map sourceTargetConverters = findConvertersForSource(sourceClass);
|
||||
Converter converter = findTargetConverter(sourceTargetConverters, targetClass);
|
||||
if (converter != null) {
|
||||
@@ -111,6 +147,11 @@ public class GenericConversionService implements ConversionService {
|
||||
}
|
||||
}
|
||||
|
||||
public ConversionExecutor getConversionExecutor(String id, Class sourceClass, Class targetClass)
|
||||
throws ConversionExecutorNotFoundException {
|
||||
throw new UnsupportedOperationException("Not yet implemented");
|
||||
}
|
||||
|
||||
// subclassing support
|
||||
|
||||
/**
|
||||
@@ -143,7 +184,7 @@ public class GenericConversionService implements ConversionService {
|
||||
if (sourceTargetConverters != null && !sourceTargetConverters.isEmpty()) {
|
||||
return sourceTargetConverters;
|
||||
}
|
||||
if (!sourceClass.isInterface() && (sourceClass.getSuperclass() != null)) {
|
||||
if (!sourceClass.isInterface() && sourceClass.getSuperclass() != null) {
|
||||
classQueue.addFirst(sourceClass.getSuperclass());
|
||||
}
|
||||
// queue up source class's implemented interfaces.
|
||||
@@ -164,7 +205,7 @@ public class GenericConversionService implements ConversionService {
|
||||
if (converter != null) {
|
||||
return converter;
|
||||
}
|
||||
if (!targetClass.isInterface() && (targetClass.getSuperclass() != null)) {
|
||||
if (!targetClass.isInterface() && targetClass.getSuperclass() != null) {
|
||||
classQueue.addFirst(targetClass.getSuperclass());
|
||||
}
|
||||
// queue up target class's implemented interfaces.
|
||||
@@ -201,4 +242,5 @@ public class GenericConversionService implements ConversionService {
|
||||
return targetType;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -15,7 +15,7 @@
|
||||
*/
|
||||
package org.springframework.binding.convert.service;
|
||||
|
||||
import org.springframework.binding.convert.Converter;
|
||||
import org.springframework.binding.convert.converters.Converter;
|
||||
|
||||
/**
|
||||
* Package private converter that is a "no op".
|
||||
@@ -36,15 +36,24 @@ class NoOpConverter implements Converter {
|
||||
this.targetClass = targetClass;
|
||||
}
|
||||
|
||||
public Object convert(Object source, Class targetClass, Object context) throws Exception {
|
||||
public Class getSourceClass() {
|
||||
return sourceClass;
|
||||
}
|
||||
|
||||
public Class getTargetClass() {
|
||||
return targetClass;
|
||||
}
|
||||
|
||||
public Object convertSourceToTargetClass(Object source, Class targetClass) throws Exception {
|
||||
return source;
|
||||
}
|
||||
|
||||
public Class[] getSourceClasses() {
|
||||
return new Class[] { sourceClass };
|
||||
public boolean isTwoWay() {
|
||||
return true;
|
||||
}
|
||||
|
||||
public Class[] getTargetClasses() {
|
||||
return new Class[] { targetClass };
|
||||
public Object convertTargetToSourceClass(Object target, Class sourceClass) throws Exception,
|
||||
UnsupportedOperationException {
|
||||
return target;
|
||||
}
|
||||
}
|
||||
@@ -17,7 +17,7 @@ package org.springframework.binding.convert.service;
|
||||
|
||||
import org.springframework.binding.convert.ConversionExecutionException;
|
||||
import org.springframework.binding.convert.ConversionExecutor;
|
||||
import org.springframework.binding.convert.Converter;
|
||||
import org.springframework.binding.convert.converters.Converter;
|
||||
import org.springframework.core.style.ToStringCreator;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
@@ -87,10 +87,6 @@ public class StaticConversionExecutor implements ConversionExecutor {
|
||||
}
|
||||
|
||||
public Object execute(Object source) throws ConversionExecutionException {
|
||||
return execute(source, null);
|
||||
}
|
||||
|
||||
public Object execute(Object source, Object context) throws ConversionExecutionException {
|
||||
if (targetClass.isInstance(source)) {
|
||||
// source is already assignment compatible with target class
|
||||
return source;
|
||||
@@ -100,7 +96,7 @@ public class StaticConversionExecutor implements ConversionExecutor {
|
||||
+ source + " is expected to be an instance of " + getSourceClass());
|
||||
}
|
||||
try {
|
||||
return converter.convert(source, targetClass, context);
|
||||
return converter.convertSourceToTargetClass(source, targetClass);
|
||||
} catch (Exception e) {
|
||||
throw new ConversionExecutionException(source, getSourceClass(), getTargetClass(), e);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,66 @@
|
||||
/*
|
||||
* Copyright 2004-2008 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.binding.format;
|
||||
|
||||
import java.text.NumberFormat;
|
||||
import java.util.Locale;
|
||||
|
||||
import org.springframework.context.i18n.LocaleContextHolder;
|
||||
|
||||
/**
|
||||
* Base class suitable for subclassing by most {@link NumberFormatFactory} implementations.
|
||||
*
|
||||
* @author Keith Donald
|
||||
*/
|
||||
public abstract class AbstractNumberFormatFactory implements NumberFormatFactory {
|
||||
|
||||
private Locale locale;
|
||||
|
||||
/**
|
||||
* The locale to use in formatting number values. If null, the locale associated with the current thread is used.
|
||||
* @see LocaleContextHolder#getLocale()
|
||||
* @return the locale
|
||||
*/
|
||||
public Locale getLocale() {
|
||||
return locale;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the locale to use in formatting number values.
|
||||
* @param locale the locale
|
||||
*/
|
||||
public void setLocale(Locale locale) {
|
||||
this.locale = locale;
|
||||
}
|
||||
|
||||
public final NumberFormat getNumberFormat() {
|
||||
Locale locale = determineLocale(this.locale);
|
||||
return getNumberFormat(locale);
|
||||
}
|
||||
|
||||
/**
|
||||
* Subclasses should override to create the new NumberFormat instance.
|
||||
* @param locale the locale to use
|
||||
* @return the number format
|
||||
*/
|
||||
protected abstract NumberFormat getNumberFormat(Locale locale);
|
||||
|
||||
// internal helpers
|
||||
|
||||
private Locale determineLocale(Locale locale) {
|
||||
return locale != null ? locale : LocaleContextHolder.getLocale();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
/*
|
||||
* Copyright 2004-2008 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.binding.format;
|
||||
|
||||
import java.text.NumberFormat;
|
||||
import java.util.Locale;
|
||||
|
||||
/**
|
||||
* Produces NumberFormat instances that format currency values.
|
||||
*
|
||||
* @see NumberFormat
|
||||
* @author Keith Donald
|
||||
*/
|
||||
public class CurrencyNumberFormatFactory extends AbstractNumberFormatFactory {
|
||||
protected NumberFormat getNumberFormat(Locale locale) {
|
||||
return NumberFormat.getCurrencyInstance(locale);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,71 @@
|
||||
/*
|
||||
* Copyright 2004-2008 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.binding.format;
|
||||
|
||||
import java.text.DecimalFormat;
|
||||
import java.text.NumberFormat;
|
||||
import java.util.Locale;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
|
||||
/**
|
||||
* Works with a general purpose {@link DecimalFormat} instance returned by calling
|
||||
* {@link NumberFormat#getInstance(Locale)} by default. This instance supports parsing any number type generally and
|
||||
* will not perform special type-specific logic such as rounding or truncation.
|
||||
*
|
||||
* @see NumberFormat
|
||||
* @see DecimalFormat
|
||||
*
|
||||
* @author Keith Donald
|
||||
*/
|
||||
public class DefaultNumberFormatFactory extends AbstractNumberFormatFactory {
|
||||
|
||||
private static Log logger = LogFactory.getLog(DefaultNumberFormatFactory.class);
|
||||
|
||||
private String pattern;
|
||||
|
||||
/**
|
||||
* The pattern to use to format number values. If not specified, the default DecimalFormat pattern is used.
|
||||
* @return the date formatting pattern
|
||||
*/
|
||||
public String getPattern() {
|
||||
return pattern;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the pattern for formatting numbers.
|
||||
* @param pattern the format pattern
|
||||
* @see DecimalFormat
|
||||
*/
|
||||
public void setPattern(String pattern) {
|
||||
this.pattern = pattern;
|
||||
}
|
||||
|
||||
protected NumberFormat getNumberFormat(Locale locale) {
|
||||
NumberFormat format = NumberFormat.getInstance(locale);
|
||||
if (pattern != null) {
|
||||
if (format instanceof DecimalFormat) {
|
||||
((DecimalFormat) format).applyPattern(pattern);
|
||||
} else {
|
||||
logger.warn("Unable to apply format pattern '" + pattern
|
||||
+ "'; Returned NumberFormat is not a DecimalFormat");
|
||||
}
|
||||
}
|
||||
return format;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,48 +0,0 @@
|
||||
/*
|
||||
* Copyright 2004-2008 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.binding.format;
|
||||
|
||||
/**
|
||||
* Formats objects of a certain class for display.
|
||||
*
|
||||
* @author Keith Donald
|
||||
*/
|
||||
public interface Formatter {
|
||||
|
||||
/**
|
||||
* Returns the type of object this Formatter formats. Successful {@link #parse(String) parse calls} will return
|
||||
* instances of this type. {@link #format(Object)} callers must provide an instance of this type.
|
||||
* @return the type of object being formatted
|
||||
*/
|
||||
public Class getObjectType();
|
||||
|
||||
/**
|
||||
* Format the object for display.
|
||||
* @param object the object to format
|
||||
* @return the formatted string, fit for display in a UI
|
||||
* @throws IllegalArgumentException if the object is of the wrong type
|
||||
*/
|
||||
public String format(Object object) throws IllegalArgumentException;
|
||||
|
||||
/**
|
||||
* Parse the formatted string representation of an object and return the object.
|
||||
* @param formattedString the formatted string representation
|
||||
* @return the parsed object
|
||||
* @throws InvalidFormatException the formatted string was in an invalid form, often due to user input error
|
||||
*/
|
||||
public Object parse(String formattedString) throws InvalidFormatException;
|
||||
|
||||
}
|
||||
@@ -1,41 +0,0 @@
|
||||
/*
|
||||
* Copyright 2004-2008 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.binding.format;
|
||||
|
||||
/**
|
||||
* A Source for shared and commonly used <code>Formatters</code>.
|
||||
*
|
||||
* @author Keith Donald
|
||||
*/
|
||||
public interface FormatterRegistry {
|
||||
|
||||
/**
|
||||
* Returns the default formatter installed for the given class of object.
|
||||
* @param clazz the type of object that will be formatted
|
||||
* @return the formatter
|
||||
*/
|
||||
public Formatter getFormatter(Class clazz);
|
||||
|
||||
/**
|
||||
* Returns the formatter for the given class of object with the given id. Use this method to query a custom
|
||||
* formatter instance for a given class of object.
|
||||
* @param clazz the type of object that will be formatted
|
||||
* @param id the id of the custom formatter instance; typically descriptive like "localDate"
|
||||
* @return the formatter
|
||||
*/
|
||||
public Formatter getFormatter(Class clazz, String id);
|
||||
|
||||
}
|
||||
@@ -1,36 +1,29 @@
|
||||
/*
|
||||
* Copyright 2004-2008 the original author or authors.
|
||||
*
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.binding.format.formatters;
|
||||
package org.springframework.binding.format;
|
||||
|
||||
import java.text.NumberFormat;
|
||||
import java.util.Locale;
|
||||
|
||||
/**
|
||||
* The default formatter for integer instances that are whole numbers and do not have fractions, such as Integers,
|
||||
* Longs, and Shorts. Simply delegates to {@link NumberFormat#getIntegerInstance(Locale)}.
|
||||
*
|
||||
* @see NumberFormat
|
||||
* @author Keith Donald
|
||||
*/
|
||||
public class IntegerFormatter extends NumberFormatter {
|
||||
|
||||
public IntegerFormatter(Class numberClass) {
|
||||
super(numberClass);
|
||||
}
|
||||
|
||||
protected NumberFormat createNumberFormat(Locale locale) {
|
||||
public class IntegerNumberFormatFactory extends AbstractNumberFormatFactory {
|
||||
protected NumberFormat getNumberFormat(Locale locale) {
|
||||
return NumberFormat.getIntegerInstance(locale);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
package org.springframework.binding.format;
|
||||
|
||||
import java.text.NumberFormat;
|
||||
|
||||
/**
|
||||
* A factory for {@link NumberFormat} objects. Conceals the complexity associated with configuring, constructing, and/or
|
||||
* caching number format instances.
|
||||
*
|
||||
* @author Keith Donald
|
||||
*/
|
||||
public interface NumberFormatFactory {
|
||||
|
||||
/**
|
||||
* Factory method that returns a fully-configured {@link NumberFormat} instance to use to format an object for
|
||||
* display.
|
||||
* @return returns the number for a
|
||||
*/
|
||||
public NumberFormat getNumberFormat();
|
||||
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
/*
|
||||
* Copyright 2004-2008 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.binding.format;
|
||||
|
||||
import java.text.NumberFormat;
|
||||
import java.util.Locale;
|
||||
|
||||
/**
|
||||
* Produces NumberFormat instances that format percent values.
|
||||
*
|
||||
* @see NumberFormat
|
||||
* @author Keith Donald
|
||||
*/
|
||||
public class PercentNumberFormatFactory extends AbstractNumberFormatFactory {
|
||||
protected NumberFormat getNumberFormat(Locale locale) {
|
||||
return NumberFormat.getPercentInstance(locale);
|
||||
}
|
||||
}
|
||||
@@ -1,58 +0,0 @@
|
||||
/*
|
||||
* Copyright 2004-2008 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.binding.format.formatters;
|
||||
|
||||
import org.springframework.binding.format.Formatter;
|
||||
import org.springframework.binding.format.InvalidFormatException;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
/**
|
||||
* A formatter for boolean values. Formats {@link Boolean#TRUE} as "true" and {@link Boolean#FALSE} as "false".
|
||||
*
|
||||
* @author Keith Donald
|
||||
*/
|
||||
public class BooleanFormatter implements Formatter {
|
||||
|
||||
public Class getObjectType() {
|
||||
return Boolean.class;
|
||||
}
|
||||
|
||||
public String format(Object value) throws IllegalArgumentException {
|
||||
if (value == null) {
|
||||
return "";
|
||||
}
|
||||
Assert.isInstanceOf(Boolean.class, value, "Object is not a [java.lang.Boolean]");
|
||||
if (Boolean.TRUE.equals(value)) {
|
||||
return "true";
|
||||
} else {
|
||||
return "false";
|
||||
}
|
||||
}
|
||||
|
||||
public Object parse(String formattedString) throws InvalidFormatException {
|
||||
if (!StringUtils.hasText(formattedString)) {
|
||||
return null;
|
||||
}
|
||||
if (formattedString.equals("true")) {
|
||||
return Boolean.TRUE;
|
||||
} else if (formattedString.equals("false")) {
|
||||
return Boolean.FALSE;
|
||||
} else {
|
||||
throw new InvalidFormatException(formattedString, "true | false");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,213 +0,0 @@
|
||||
/*
|
||||
* Copyright 2004-2008 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.binding.format.formatters;
|
||||
|
||||
import java.text.DecimalFormat;
|
||||
import java.text.NumberFormat;
|
||||
import java.text.ParsePosition;
|
||||
import java.util.Locale;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.springframework.binding.format.Formatter;
|
||||
import org.springframework.binding.format.InvalidFormatException;
|
||||
import org.springframework.context.i18n.LocaleContextHolder;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.NumberUtils;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
/**
|
||||
* A general formatter for common number types such as integers and big decimals. Allows the configuration of an
|
||||
* explicit number pattern and locale.
|
||||
*
|
||||
* Works with a general purpose {@link DecimalFormat} instance returned by calling
|
||||
* {@link NumberFormat#getInstance(Locale)} by default. This instance supports parsing any number type generally and
|
||||
* will not perform special type-specific logic such as rounding or truncation. Subclasses may override.
|
||||
*
|
||||
* Will coerse parsed Numbers to the desired numberClass as necessary. If type-coersion results in an overflow
|
||||
* condition; for example, what can occur with a Long being coersed to a Short, an exception will be thrown.
|
||||
*
|
||||
* @see NumberFormat
|
||||
* @see DecimalFormat
|
||||
*
|
||||
* @author Keith Donald
|
||||
*/
|
||||
public class NumberFormatter implements Formatter {
|
||||
|
||||
private static Log logger = LogFactory.getLog(NumberFormatter.class);
|
||||
|
||||
private String pattern;
|
||||
|
||||
private Class numberClass;
|
||||
|
||||
private Locale locale;
|
||||
|
||||
private boolean lenient;
|
||||
|
||||
/**
|
||||
* Creates a number formatter for the specified number type.
|
||||
* @param numberClass the number type, a class extending from {@link Number}.
|
||||
*/
|
||||
public NumberFormatter(Class numberClass) {
|
||||
Assert.notNull(numberClass, "The number class is required");
|
||||
Assert.isTrue(Number.class.isAssignableFrom(numberClass), "The class must extend from Number");
|
||||
this.numberClass = numberClass;
|
||||
}
|
||||
|
||||
/**
|
||||
* The pattern to use to format number values. If not specified, the default DecimalFormat pattern is used.
|
||||
* @return the date formatting pattern
|
||||
*/
|
||||
public String getPattern() {
|
||||
return pattern;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the pattern for formatting numbers.
|
||||
* @param pattern the format pattern
|
||||
* @see DecimalFormat
|
||||
*/
|
||||
public void setPattern(String pattern) {
|
||||
this.pattern = pattern;
|
||||
}
|
||||
|
||||
/**
|
||||
* The locale to use in formatting number values. If null, the locale associated with the current thread is used.
|
||||
* @see LocaleContextHolder#getLocale()
|
||||
* @return the locale
|
||||
*/
|
||||
public Locale getLocale() {
|
||||
return locale;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the locale to use in formatting number values.
|
||||
* @param locale the locale
|
||||
*/
|
||||
public void setLocale(Locale locale) {
|
||||
this.locale = locale;
|
||||
}
|
||||
|
||||
/**
|
||||
* If this Formatter is "lenient" in parsing number strings. A lenient formatter does not require that all
|
||||
* characters in the String be parsed successfully. Default is false.
|
||||
* @return the lenient flag
|
||||
*/
|
||||
public boolean getLenient() {
|
||||
return lenient;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets if this Formatter should parse leniently.
|
||||
* @param lenient the lenient flag
|
||||
*/
|
||||
public void setLenient(boolean lenient) {
|
||||
this.lenient = lenient;
|
||||
}
|
||||
|
||||
// implementing Formatter
|
||||
|
||||
public Class getObjectType() {
|
||||
return numberClass;
|
||||
}
|
||||
|
||||
public String format(Object number) {
|
||||
if (number == null) {
|
||||
return "";
|
||||
}
|
||||
if (!numberClass.isInstance(number)) {
|
||||
throw new IllegalArgumentException("Object is not a [" + numberClass.getName() + "]; it is a ["
|
||||
+ number.getClass().getName() + "]");
|
||||
}
|
||||
return getNumberFormat().format(number);
|
||||
}
|
||||
|
||||
public Object parse(String formattedString) throws InvalidFormatException {
|
||||
if (!StringUtils.hasText(formattedString)) {
|
||||
return null;
|
||||
}
|
||||
ParsePosition parsePosition = new ParsePosition(0);
|
||||
NumberFormat format = getNumberFormat();
|
||||
Number number = format.parse(formattedString, parsePosition);
|
||||
if (number == null) {
|
||||
// no object could be parsed
|
||||
throw new InvalidFormatException(formattedString, getPattern(format));
|
||||
}
|
||||
if (!lenient) {
|
||||
if (formattedString.length() != parsePosition.getIndex()) {
|
||||
// indicates a part of the string that was not parsed; e.g. ".5" in 1234.5 when parsing an Integer
|
||||
throw new InvalidFormatException(formattedString, getPattern(format));
|
||||
}
|
||||
}
|
||||
return convertToNumberClass(number);
|
||||
}
|
||||
|
||||
// subclassing hookings
|
||||
|
||||
/**
|
||||
* Factory method that returns a fully-configured {@link NumberFormat} instance to use to format an object for
|
||||
* display. Applies the locale and pattern properties if configured. Subclasses may override.
|
||||
*/
|
||||
protected NumberFormat getNumberFormat() {
|
||||
Locale locale = determineLocale(this.locale);
|
||||
NumberFormat format = createNumberFormat(locale);
|
||||
if (pattern != null) {
|
||||
if (format instanceof DecimalFormat) {
|
||||
((DecimalFormat) format).applyPattern(pattern);
|
||||
} else {
|
||||
logger.warn("Unable to apply format pattern '" + pattern
|
||||
+ "'; Returned NumberFormat is not a DecimalFormat");
|
||||
}
|
||||
}
|
||||
return format;
|
||||
}
|
||||
|
||||
/**
|
||||
* Delegates to the {@link NumberFormat java.text.NumberFormat API} to construct the new NumberFormat instance.
|
||||
* Called by {@link #getNumberFormat()} after calculating the Locale. Subclasses may override to control how the
|
||||
* Format instance is constructed.
|
||||
* @param locale the calculated Locale
|
||||
* @return the new NumberFormat instance
|
||||
*/
|
||||
protected NumberFormat createNumberFormat(Locale locale) {
|
||||
return NumberFormat.getInstance(locale);
|
||||
}
|
||||
|
||||
/**
|
||||
* Coerces the Number object returned by NumberFormat to the desired numberClass. Subclasses may override.
|
||||
* @param number the parsed number
|
||||
* @return the coersed number
|
||||
* @throws IllegalArgumentException when an overflow condition occurs during coersion
|
||||
*/
|
||||
protected Number convertToNumberClass(Number number) throws IllegalArgumentException {
|
||||
return NumberUtils.convertNumberToTargetClass(number, numberClass);
|
||||
}
|
||||
|
||||
// internal helpers
|
||||
|
||||
private Locale determineLocale(Locale locale) {
|
||||
return locale != null ? locale : LocaleContextHolder.getLocale();
|
||||
}
|
||||
|
||||
private String getPattern(NumberFormat format) {
|
||||
if (format instanceof DecimalFormat) {
|
||||
return ((DecimalFormat) format).toPattern();
|
||||
} else {
|
||||
logger.warn("Pattern string cannot be determined because NumberFormat is not a DecimalFormat");
|
||||
return "defaultNumberFormatInstance";
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,77 +0,0 @@
|
||||
/*
|
||||
* Copyright 2004-2008 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.binding.format.formatters;
|
||||
|
||||
import java.beans.PropertyEditor;
|
||||
|
||||
import org.springframework.binding.format.Formatter;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
/**
|
||||
* Adapts a {@link PropertyEditor} to the formatter interface. Useful for re-using pre-existing PropertyEditors as
|
||||
* Formatters.
|
||||
*
|
||||
* Note: this class synchronizes calls into the configured PropertyEditor instance to ensure thread safety.
|
||||
*
|
||||
* @author Keith Donald
|
||||
*/
|
||||
public class PropertyEditorFormatter implements Formatter {
|
||||
|
||||
private Class objectType;
|
||||
|
||||
private PropertyEditor propertyEditor;
|
||||
|
||||
/**
|
||||
* Wrap the given property editor in a formatter.
|
||||
*/
|
||||
public PropertyEditorFormatter(PropertyEditor propertyEditor, Class objectType) {
|
||||
Assert.notNull(propertyEditor, "The PropertyEditor is required");
|
||||
Assert.notNull(objectType, "The object type is required");
|
||||
this.propertyEditor = propertyEditor;
|
||||
this.objectType = objectType;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the wrapped property editor.
|
||||
*/
|
||||
public PropertyEditor getPropertyEditor() {
|
||||
return propertyEditor;
|
||||
}
|
||||
|
||||
// implementing Formatter
|
||||
|
||||
public Class getObjectType() {
|
||||
return objectType;
|
||||
}
|
||||
|
||||
public String format(Object value) {
|
||||
synchronized (propertyEditor) {
|
||||
propertyEditor.setValue(value);
|
||||
String text = propertyEditor.getAsText();
|
||||
propertyEditor.setValue(null);
|
||||
return text;
|
||||
}
|
||||
}
|
||||
|
||||
public Object parse(String formattedValue) {
|
||||
synchronized (propertyEditor) {
|
||||
propertyEditor.setAsText(formattedValue);
|
||||
Object value = propertyEditor.getValue();
|
||||
propertyEditor.setValue(null);
|
||||
return value;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,7 +0,0 @@
|
||||
<html>
|
||||
<body>
|
||||
<p>
|
||||
Common Formatter implementations.
|
||||
</p>
|
||||
</body>
|
||||
</html>
|
||||
@@ -123,7 +123,7 @@ public class DefaultMapping implements Mapping {
|
||||
if (sourceValue != null) {
|
||||
if (typeConverter != null) {
|
||||
try {
|
||||
targetValue = typeConverter.execute(sourceValue, context);
|
||||
targetValue = typeConverter.execute(sourceValue);
|
||||
} catch (ConversionExecutionException e) {
|
||||
context.setTypeConversionErrorResult(e);
|
||||
return;
|
||||
@@ -142,7 +142,7 @@ public class DefaultMapping implements Mapping {
|
||||
ConversionExecutor typeConverter = conversionService.getConversionExecutor(sourceValue
|
||||
.getClass(), targetType);
|
||||
try {
|
||||
targetValue = typeConverter.execute(sourceValue, context);
|
||||
targetValue = typeConverter.execute(sourceValue);
|
||||
} catch (ConversionExecutionException e) {
|
||||
context.setTypeConversionErrorResult(e);
|
||||
return;
|
||||
|
||||
Reference in New Issue
Block a user