diff --git a/spring-binding/src/main/java/org/springframework/binding/convert/ConversionException.java b/spring-binding/src/main/java/org/springframework/binding/convert/ConversionException.java
index 77f1cf67..205c1590 100644
--- a/spring-binding/src/main/java/org/springframework/binding/convert/ConversionException.java
+++ b/spring-binding/src/main/java/org/springframework/binding/convert/ConversionException.java
@@ -16,85 +16,26 @@
package org.springframework.binding.convert;
/**
- * Base class for exceptions thrown by the type conversion system.
+ * Base class for exceptions thrown by the convert system.
*
* @author Keith Donald
*/
-public class ConversionException extends RuntimeException {
-
- /**
- * The source type we tried to convert from
- */
- private Class sourceClass;
-
- /**
- * The target type we tried to convert to.
- */
- private Class targetClass;
-
- /**
- * The value we tried to convert. Transient because we cannot guarantee that the value is Serializable.
- */
- private transient Object value;
+public abstract class ConversionException extends RuntimeException {
/**
* Creates a new conversion exception.
- * @param value the value we tried to convert
- * @param targetClass the target type
- * @param cause underlying cause of this exception
+ * @param message the exception message
+ * @param cause the cause
*/
- public ConversionException(Object value, Class targetClass, Throwable cause) {
- super("Unable to convert value '" + value + "' of type '" + (value != null ? value.getClass().getName() : null)
- + "' to class '" + targetClass.getName() + "'", cause);
- this.value = value;
- this.targetClass = targetClass;
- }
-
- /**
- * Creates a new conversion exception.
- * @param sourceClass the source type
- * @param value the value we tried to convert
- * @param targetClass the target type
- * @param message a descriptive message
- */
- public ConversionException(Class sourceClass, Object value, Class targetClass, String message, Throwable cause) {
+ public ConversionException(String message, Throwable cause) {
super(message, cause);
- this.sourceClass = sourceClass;
- this.value = value;
- this.targetClass = targetClass;
}
/**
* Creates a new conversion exception.
- * @param sourceClass the source type
- * @param targetClass the target type
- * @param message a descriptive message
+ * @param message the exception message
*/
- public ConversionException(Class sourceClass, Class targetClass, String message) {
+ public ConversionException(String message) {
super(message);
- this.sourceClass = sourceClass;
- this.targetClass = targetClass;
}
-
- /**
- * Returns the source type.
- */
- public Class getSourceClass() {
- return sourceClass;
- }
-
- /**
- * Returns the target type.
- */
- public Class getTargetClass() {
- return targetClass;
- }
-
- /**
- * Returns the value we tried to convert.
- */
- public Object getValue() {
- return value;
- }
-
-}
\ No newline at end of file
+}
diff --git a/spring-binding/src/main/java/org/springframework/binding/convert/ConversionExecutionException.java b/spring-binding/src/main/java/org/springframework/binding/convert/ConversionExecutionException.java
new file mode 100644
index 00000000..49ba8880
--- /dev/null
+++ b/spring-binding/src/main/java/org/springframework/binding/convert/ConversionExecutionException.java
@@ -0,0 +1,94 @@
+/*
+ * 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;
+
+/**
+ * Thrown when an attempt to execute a type conversion fails.
+ *
+ * @author Keith Donald
+ */
+public class ConversionExecutionException extends ConversionException {
+
+ /**
+ * The value we tried to convert. Transient because we cannot guarantee that the value is Serializable.
+ */
+ private transient Object value;
+
+ /**
+ * The source type we tried to convert the value from.
+ */
+ private Class sourceClass;
+
+ /**
+ * The target type we tried to convert the value to.
+ */
+ private Class targetClass;
+
+ /**
+ * Creates a new conversion exception.
+ * @param value the value we tried to convert
+ * @param sourceClass the value's original type
+ * @param targetClass the value's target type
+ * @param cause the cause of the conversion failure
+ */
+ public ConversionExecutionException(Object value, Class sourceClass, Class targetClass, Throwable cause) {
+ super(defaultMessage(value, sourceClass, targetClass, cause), cause);
+ this.value = value;
+ this.sourceClass = sourceClass;
+ this.targetClass = targetClass;
+ }
+
+ /**
+ * Creates a new conversion exception.
+ * @param value the value we tried to convert
+ * @param sourceClass the value's original type
+ * @param targetClass the value's target type
+ * @param message a descriptive message of what went wrong.
+ */
+ public ConversionExecutionException(Object value, Class sourceClass, Class targetClass, String message) {
+ super(message);
+ this.value = value;
+ this.sourceClass = sourceClass;
+ this.targetClass = targetClass;
+ }
+
+ /**
+ * Returns the actual value we tried to convert, an instance of {@link #getSourceClass()}.
+ */
+ public Object getValue() {
+ return value;
+ }
+
+ /**
+ * Returns the source type we tried to convert the value from.
+ */
+ public Class getSourceClass() {
+ return sourceClass;
+ }
+
+ /**
+ * Returns the target type we tried to convert the value to.
+ */
+ public Class getTargetClass() {
+ return targetClass;
+ }
+
+ private static String defaultMessage(Object value, Class sourceClass, Class targetClass, Throwable cause) {
+ return "Unable to convert value " + value + " from type '" + sourceClass.getName() + "' to type '"
+ + targetClass.getName() + "; reason = '" + cause.getMessage() + "'";
+ }
+
+}
\ No newline at end of file
diff --git a/spring-binding/src/main/java/org/springframework/binding/convert/ConversionExecutor.java b/spring-binding/src/main/java/org/springframework/binding/convert/ConversionExecutor.java
index df94c8a2..06ffa756 100644
--- a/spring-binding/src/main/java/org/springframework/binding/convert/ConversionExecutor.java
+++ b/spring-binding/src/main/java/org/springframework/binding/convert/ConversionExecutor.java
@@ -40,13 +40,13 @@ public interface ConversionExecutor {
* Execute the conversion for the provided source object.
* @param source the source object to convert
*/
- public Object execute(Object source) throws ConversionException;
+ 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 ConversionException;
+ public Object execute(Object source, Object context) throws ConversionExecutionException;
}
\ No newline at end of file
diff --git a/spring-binding/src/main/java/org/springframework/binding/convert/ConversionExecutorNotFoundException.java b/spring-binding/src/main/java/org/springframework/binding/convert/ConversionExecutorNotFoundException.java
new file mode 100644
index 00000000..55ca51f8
--- /dev/null
+++ b/spring-binding/src/main/java/org/springframework/binding/convert/ConversionExecutorNotFoundException.java
@@ -0,0 +1,55 @@
+/*
+ * 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;
+
+/**
+ * Thrown when a conversion executor could not be found in a conversion service.
+ *
+ * @see ConversionService#getConversionExecutor(Class, Class)
+ * @author Keith Donald
+ */
+public class ConversionExecutorNotFoundException extends ConversionException {
+
+ private Class sourceClass;
+
+ private Class targetClass;
+
+ /**
+ * Creates a new conversion executor not found exception.
+ * @param sourceClass the source type requested to convert from
+ * @param targetClass the target type requested to convert to
+ * @param message a descriptive message
+ */
+ public ConversionExecutorNotFoundException(Class sourceClass, Class targetClass, String message) {
+ super(message);
+ this.sourceClass = sourceClass;
+ this.targetClass = targetClass;
+ }
+
+ /**
+ * Returns the source type requested to convert from.
+ */
+ public Class getSourceClass() {
+ return sourceClass;
+ }
+
+ /**
+ * Returns the target type requested to convert to.
+ */
+ public Class getTargetClass() {
+ return targetClass;
+ }
+}
diff --git a/spring-binding/src/main/java/org/springframework/binding/convert/ConversionService.java b/spring-binding/src/main/java/org/springframework/binding/convert/ConversionService.java
index d416c2b9..a450e2c2 100644
--- a/spring-binding/src/main/java/org/springframework/binding/convert/ConversionService.java
+++ b/spring-binding/src/main/java/org/springframework/binding/convert/ConversionService.java
@@ -33,9 +33,10 @@ public interface ConversionService {
* The returned ConversionExecutor is thread-safe and may safely be cached for use in client code.
* @param sourceClass the source class to convert from
* @param targetClass the target class to convert to
- * @return the executor that can execute instance conversion, never null
- * @throws ConversionException an exception occurred retrieving a converter for the source-to-target pair
+ * @return the executor that can execute instance type conversion, never null
+ * @throws ConversionExecutorNotFoundException when no suitable conversion executor could be found
*/
- public ConversionExecutor getConversionExecutor(Class sourceClass, Class targetClass) throws ConversionException;
+ public ConversionExecutor getConversionExecutor(Class sourceClass, Class targetClass)
+ throws ConversionExecutorNotFoundException;
}
\ No newline at end of file
diff --git a/spring-binding/src/main/java/org/springframework/binding/convert/Converter.java b/spring-binding/src/main/java/org/springframework/binding/convert/Converter.java
index 4a47ce63..0c2b2894 100644
--- a/spring-binding/src/main/java/org/springframework/binding/convert/Converter.java
+++ b/spring-binding/src/main/java/org/springframework/binding/convert/Converter.java
@@ -50,8 +50,8 @@ public interface Converter {
* targetClasses
* @param context an optional conversion context that may be used to influence the conversion process
* @return the converted object, an instance of the target type
- * @throws ConversionException an exception occurred during the type conversion
+ * @throws Exception an exception occurred performing the conversion
*/
- public Object convert(Object source, Class targetClass, Object context) throws ConversionException;
+ public Object convert(Object source, Class targetClass, Object context) throws Exception;
}
\ No newline at end of file
diff --git a/spring-binding/src/main/java/org/springframework/binding/convert/converters/AbstractConverter.java b/spring-binding/src/main/java/org/springframework/binding/convert/converters/AbstractConverter.java
deleted file mode 100644
index 4e89ebd7..00000000
--- a/spring-binding/src/main/java/org/springframework/binding/convert/converters/AbstractConverter.java
+++ /dev/null
@@ -1,88 +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.ConversionException;
-import org.springframework.binding.convert.Converter;
-
-/**
- * Base class for converters provided as a convenience to implementors.
- *
- * @author Keith Donald
- */
-public abstract class AbstractConverter implements Converter {
-
- /**
- * Convenience convert method that converts the provided source to the first target object supported by this
- * converter. Useful when a converter only supports conversion to a single target.
- * @param source the source to convert
- * @return the converted object
- * @throws ConversionException an exception occured converting the source value
- */
- public Object convert(Object source) throws ConversionException {
- return convert(source, getTargetClasses()[0], null);
- }
-
- /**
- * Convenience convert method that converts the provided source to the target class specified with an empty
- * conversion context.
- * @param source the source to convert
- * @param targetClass the target class to convert the source to, must be one of the supported
- * targetClasses
- * @return the converted object
- * @throws ConversionException an exception occured converting the source value
- */
- public Object convert(Object source, Class targetClass) throws ConversionException {
- return convert(source, targetClass, null);
- }
-
- /**
- * Convenience convert method that converts the provided source to the first target object supported by this
- * converter. Useful when a converter only supports conversion to a single target.
- * @param source the source to convert
- * @param context the conversion context, useful for influencing the behavior of the converter
- * @return the converted object
- * @throws ConversionException an exception occured converting the source value
- */
- public Object convert(Object source, Object context) throws ConversionException {
- return convert(source, getTargetClasses()[0], context);
- }
-
- public Object convert(Object source, Class targetClass, Object context) throws ConversionException {
- try {
- return doConvert(source, targetClass, context);
- } catch (ConversionException e) {
- throw e;
- } catch (Throwable e) {
- // wrap in a ConversionException
- if (targetClass == null) {
- targetClass = getTargetClasses()[0];
- }
- throw new ConversionException(source, targetClass, e);
- }
- }
-
- /**
- * Template method subclasses should override to actually perform the type conversion.
- * @param source the source to convert from
- * @param targetClass the target type to convert to
- * @param context an optional conversion context that may be used to influence the conversion process, could be null
- * @return the converted source value
- * @throws Exception an exception occurred, will be wrapped in a conversion exception if necessary
- */
- protected abstract Object doConvert(Object source, Class targetClass, Object context) throws Exception;
-
-}
\ No newline at end of file
diff --git a/spring-binding/src/main/java/org/springframework/binding/convert/converters/TextToBoolean.java b/spring-binding/src/main/java/org/springframework/binding/convert/converters/TextToBoolean.java
index 8cab3115..17730175 100644
--- a/spring-binding/src/main/java/org/springframework/binding/convert/converters/TextToBoolean.java
+++ b/spring-binding/src/main/java/org/springframework/binding/convert/converters/TextToBoolean.java
@@ -15,6 +15,7 @@
*/
package org.springframework.binding.convert.converters;
+import org.springframework.binding.convert.Converter;
import org.springframework.util.StringUtils;
/**
@@ -22,7 +23,7 @@ import org.springframework.util.StringUtils;
*
* @author Keith Donald
*/
-public class TextToBoolean extends AbstractConverter {
+public class TextToBoolean implements Converter {
private static final String VALUE_TRUE = "true";
@@ -70,7 +71,7 @@ public class TextToBoolean extends AbstractConverter {
return new Class[] { Boolean.class };
}
- protected Object doConvert(Object source, Class targetClass, Object context) throws Exception {
+ public Object convert(Object source, Class targetClass, Object context) throws Exception {
String text = (String) source;
if (!StringUtils.hasText(text)) {
return null;
diff --git a/spring-binding/src/main/java/org/springframework/binding/convert/converters/TextToClass.java b/spring-binding/src/main/java/org/springframework/binding/convert/converters/TextToClass.java
index 929213d2..d2179029 100644
--- a/spring-binding/src/main/java/org/springframework/binding/convert/converters/TextToClass.java
+++ b/spring-binding/src/main/java/org/springframework/binding/convert/converters/TextToClass.java
@@ -20,6 +20,7 @@ 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;
@@ -29,7 +30,7 @@ import org.springframework.util.StringUtils;
*
* @author Keith Donald
*/
-public class TextToClass extends AbstractConverter {
+public class TextToClass implements Converter {
private Map aliasMap = new HashMap();
@@ -52,7 +53,7 @@ public class TextToClass extends AbstractConverter {
return new Class[] { Class.class };
}
- protected Object doConvert(Object source, Class targetClass, Object context) throws Exception {
+ public Object convert(Object source, Class targetClass, Object context) throws Exception {
String text = (String) source;
if (StringUtils.hasText(text)) {
text = text.trim();
diff --git a/spring-binding/src/main/java/org/springframework/binding/convert/converters/TextToLabeledEnum.java b/spring-binding/src/main/java/org/springframework/binding/convert/converters/TextToLabeledEnum.java
index 6bc448ef..35595243 100644
--- a/spring-binding/src/main/java/org/springframework/binding/convert/converters/TextToLabeledEnum.java
+++ b/spring-binding/src/main/java/org/springframework/binding/convert/converters/TextToLabeledEnum.java
@@ -15,6 +15,7 @@
*/
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;
@@ -24,7 +25,7 @@ import org.springframework.core.enums.StaticLabeledEnumResolver;
*
* @author Keith Donald
*/
-public class TextToLabeledEnum extends AbstractConverter {
+public class TextToLabeledEnum implements Converter {
private LabeledEnumResolver labeledEnumResolver = StaticLabeledEnumResolver.instance();
@@ -36,7 +37,7 @@ public class TextToLabeledEnum extends AbstractConverter {
return new Class[] { LabeledEnum.class };
}
- protected Object doConvert(Object source, Class targetClass, Object context) throws Exception {
+ public Object convert(Object source, Class targetClass, Object context) throws Exception {
String label = (String) source;
return labeledEnumResolver.getLabeledEnumByLabel(targetClass, label);
}
diff --git a/spring-binding/src/main/java/org/springframework/binding/convert/converters/TextToNumber.java b/spring-binding/src/main/java/org/springframework/binding/convert/converters/TextToNumber.java
index 92ea7b21..e453a56f 100644
--- a/spring-binding/src/main/java/org/springframework/binding/convert/converters/TextToNumber.java
+++ b/spring-binding/src/main/java/org/springframework/binding/convert/converters/TextToNumber.java
@@ -18,6 +18,7 @@ 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;
/**
@@ -26,7 +27,7 @@ import org.springframework.util.NumberUtils;
*
* @author Keith Donald
*/
-public class TextToNumber extends AbstractConverter {
+public class TextToNumber implements Converter {
public Class[] getSourceClasses() {
return new Class[] { String.class };
@@ -37,7 +38,7 @@ public class TextToNumber extends AbstractConverter {
BigInteger.class, BigDecimal.class };
}
- protected Object doConvert(Object source, Class targetClass, Object context) throws Exception {
+ public Object convert(Object source, Class targetClass, Object context) throws Exception {
return NumberUtils.parseNumber((String) source, targetClass);
}
diff --git a/spring-binding/src/main/java/org/springframework/binding/convert/service/GenericConversionService.java b/spring-binding/src/main/java/org/springframework/binding/convert/service/GenericConversionService.java
index 11cfb280..40f01aba 100644
--- a/spring-binding/src/main/java/org/springframework/binding/convert/service/GenericConversionService.java
+++ b/spring-binding/src/main/java/org/springframework/binding/convert/service/GenericConversionService.java
@@ -20,8 +20,8 @@ import java.util.HashMap;
import java.util.LinkedList;
import java.util.Map;
-import org.springframework.binding.convert.ConversionException;
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.util.Assert;
@@ -80,10 +80,11 @@ public class GenericConversionService implements ConversionService {
}
}
- public ConversionExecutor getConversionExecutor(Class sourceClass, Class targetClass) throws ConversionException {
+ 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 (this.sourceClassConverters == null || this.sourceClassConverters.isEmpty()) {
+ if (sourceClassConverters == null || sourceClassConverters.isEmpty()) {
throw new IllegalStateException("No converters have been added to this service's registry");
}
sourceClass = convertToWrapperClassIfNecessary(sourceClass);
@@ -101,9 +102,9 @@ public class GenericConversionService implements ConversionService {
// try the parent
return parent.getConversionExecutor(sourceClass, targetClass);
} else {
- throw new ConversionException(sourceClass, targetClass,
- "No converter registered to convert from sourceClass '" + sourceClass + "' to target class '"
- + targetClass + "'");
+ throw new ConversionExecutorNotFoundException(sourceClass, targetClass,
+ "No ConversionExecutor found for converting from sourceClass '" + sourceClass.getName()
+ + "' to target class '" + targetClass.getName() + "'");
}
}
}
diff --git a/spring-binding/src/main/java/org/springframework/binding/convert/service/NoOpConverter.java b/spring-binding/src/main/java/org/springframework/binding/convert/service/NoOpConverter.java
index 0d3084e8..582747d6 100644
--- a/spring-binding/src/main/java/org/springframework/binding/convert/service/NoOpConverter.java
+++ b/spring-binding/src/main/java/org/springframework/binding/convert/service/NoOpConverter.java
@@ -15,15 +15,14 @@
*/
package org.springframework.binding.convert.service;
-import org.springframework.binding.convert.converters.AbstractConverter;
-
+import org.springframework.binding.convert.Converter;
/**
* Package private converter that is a "no op".
*
* @author Keith Donald
*/
-class NoOpConverter extends AbstractConverter {
+class NoOpConverter implements Converter {
private Class sourceClass;
@@ -37,7 +36,7 @@ class NoOpConverter extends AbstractConverter {
this.targetClass = targetClass;
}
- protected Object doConvert(Object source, Class targetClass, Object context) throws Exception {
+ public Object convert(Object source, Class targetClass, Object context) throws Exception {
return source;
}
diff --git a/spring-binding/src/main/java/org/springframework/binding/convert/service/RuntimeBindingConversionExecutor.java b/spring-binding/src/main/java/org/springframework/binding/convert/service/RuntimeBindingConversionExecutor.java
index 87f93752..4caf8768 100644
--- a/spring-binding/src/main/java/org/springframework/binding/convert/service/RuntimeBindingConversionExecutor.java
+++ b/spring-binding/src/main/java/org/springframework/binding/convert/service/RuntimeBindingConversionExecutor.java
@@ -15,7 +15,7 @@
*/
package org.springframework.binding.convert.service;
-import org.springframework.binding.convert.ConversionException;
+import org.springframework.binding.convert.ConversionExecutionException;
import org.springframework.binding.convert.ConversionExecutor;
import org.springframework.binding.convert.ConversionService;
import org.springframework.util.Assert;
@@ -62,11 +62,11 @@ public class RuntimeBindingConversionExecutor implements ConversionExecutor {
return targetClass.hashCode();
}
- public Object execute(Object source) throws ConversionException {
+ public Object execute(Object source) throws ConversionExecutionException {
return execute(source, null);
}
- public Object execute(Object source, Object context) throws ConversionException {
+ public Object execute(Object source, Object context) throws ConversionExecutionException {
return conversionService.getConversionExecutor(source.getClass(), targetClass).execute(source);
}
diff --git a/spring-binding/src/main/java/org/springframework/binding/convert/service/StaticConversionExecutor.java b/spring-binding/src/main/java/org/springframework/binding/convert/service/StaticConversionExecutor.java
index 4c3597e5..9e7e2334 100644
--- a/spring-binding/src/main/java/org/springframework/binding/convert/service/StaticConversionExecutor.java
+++ b/spring-binding/src/main/java/org/springframework/binding/convert/service/StaticConversionExecutor.java
@@ -15,7 +15,7 @@
*/
package org.springframework.binding.convert.service;
-import org.springframework.binding.convert.ConversionException;
+import org.springframework.binding.convert.ConversionExecutionException;
import org.springframework.binding.convert.ConversionExecutor;
import org.springframework.binding.convert.Converter;
import org.springframework.core.style.ToStringCreator;
@@ -30,7 +30,7 @@ import org.springframework.util.Assert;
*
* @author Keith Donald
*/
-class StaticConversionExecutor implements ConversionExecutor {
+public class StaticConversionExecutor implements ConversionExecutor {
/**
* The source value type this executor will attempt to convert from.
@@ -86,20 +86,24 @@ class StaticConversionExecutor implements ConversionExecutor {
return converter;
}
- public Object execute(Object source) throws ConversionException {
+ public Object execute(Object source) throws ConversionExecutionException {
return execute(source, null);
}
- public Object execute(Object source, Object context) throws ConversionException {
+ public Object execute(Object source, Object context) throws ConversionExecutionException {
if (targetClass.isInstance(source)) {
// source is already assignment compatible with target class
return source;
}
if (source != null && !sourceClass.isInstance(source)) {
- throw new ConversionException(getSourceClass(), source, getTargetClass(), "Source object '" + source
- + "' is expected to be an instance of " + getSourceClass(), null);
+ throw new ConversionExecutionException(source, getSourceClass(), getTargetClass(), "Source object "
+ + source + " is expected to be an instance of " + getSourceClass());
+ }
+ try {
+ return converter.convert(source, targetClass, context);
+ } catch (Exception e) {
+ throw new ConversionExecutionException(source, getSourceClass(), getTargetClass(), e);
}
- return converter.convert(source, targetClass, context);
}
public boolean equals(Object o) {
diff --git a/spring-binding/src/main/java/org/springframework/binding/expression/EvaluationException.java b/spring-binding/src/main/java/org/springframework/binding/expression/EvaluationException.java
index 18131f24..4c4fb358 100644
--- a/spring-binding/src/main/java/org/springframework/binding/expression/EvaluationException.java
+++ b/spring-binding/src/main/java/org/springframework/binding/expression/EvaluationException.java
@@ -33,8 +33,7 @@ public class EvaluationException extends RuntimeException {
* @param cause the underlying cause of this exception
*/
public EvaluationException(EvaluationAttempt evaluationAttempt, Throwable cause) {
- this(evaluationAttempt, evaluationAttempt
- + " failed - make sure the expression is evaluatable in the context provided", cause);
+ this(evaluationAttempt, defaultMessage(evaluationAttempt, cause), cause);
}
/**
@@ -53,4 +52,13 @@ public class EvaluationException extends RuntimeException {
public EvaluationAttempt getEvaluationAttempt() {
return evaluationAttempt;
}
+
+ private static String defaultMessage(EvaluationAttempt evaluationAttempt, Throwable cause) {
+ if (cause != null) {
+ return evaluationAttempt + " failed - " + cause.getMessage();
+ } else {
+ return evaluationAttempt + " failed - make sure the expression is evaluatable in the context provided";
+ }
+ }
+
}
\ No newline at end of file
diff --git a/spring-binding/src/main/java/org/springframework/binding/format/formatters/BooleanFormatter.java b/spring-binding/src/main/java/org/springframework/binding/format/formatters/BooleanFormatter.java
index c7354da6..799ab973 100644
--- a/spring-binding/src/main/java/org/springframework/binding/format/formatters/BooleanFormatter.java
+++ b/spring-binding/src/main/java/org/springframework/binding/format/formatters/BooleanFormatter.java
@@ -19,6 +19,11 @@ import org.springframework.binding.format.Formatter;
import org.springframework.binding.format.InvalidFormatException;
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 String format(Object value) throws IllegalArgumentException {
@@ -30,12 +35,11 @@ public class BooleanFormatter implements Formatter {
} else if (Boolean.FALSE.equals(value)) {
return "false";
} else {
- throw new IllegalArgumentException("Must be a Boolean " + value);
+ throw new IllegalArgumentException("Not a Boolean: " + value);
}
}
public Object parse(String formattedString) throws InvalidFormatException {
- formattedString = (formattedString != null ? formattedString.trim() : null);
if (!StringUtils.hasText(formattedString)) {
return null;
}
diff --git a/spring-binding/src/main/java/org/springframework/binding/format/formatters/DateFormatter.java b/spring-binding/src/main/java/org/springframework/binding/format/formatters/DateFormatter.java
index 62aba8ec..e4931c30 100644
--- a/spring-binding/src/main/java/org/springframework/binding/format/formatters/DateFormatter.java
+++ b/spring-binding/src/main/java/org/springframework/binding/format/formatters/DateFormatter.java
@@ -25,26 +25,50 @@ import org.springframework.binding.format.Formatter;
import org.springframework.binding.format.InvalidFormatException;
import org.springframework.util.StringUtils;
+/**
+ * A formatter for {@link Date} types. Allows the configuration of an explicit date pattern and locale.
+ * @see SimpleDateFormat
+ * @author Keith Donald
+ */
public class DateFormatter implements Formatter {
- public static final String DEFAULT_PATTERN = "yyyy-MM-dd";
+ /**
+ * The default date pattern.
+ */
+ private static final String DEFAULT_PATTERN = "yyyy-MM-dd";
private String pattern;
private Locale locale;
+ /**
+ * The pattern to use to format date values.
+ * @return the date formatting pattern
+ */
public String getPattern() {
return pattern;
}
+ /**
+ * Sets the pattern to use to format date values.
+ * @param pattern the date formatting pattern
+ */
public void setPattern(String pattern) {
this.pattern = pattern;
}
+ /**
+ * The locale to use in formatting date values. If null, the default locale is used.
+ * @return the locale
+ */
public Locale getLocale() {
return locale;
}
+ /**
+ * Sets the locale to use in formatting date values.
+ * @param locale the locale
+ */
public void setLocale(Locale locale) {
this.locale = locale;
}
@@ -64,20 +88,26 @@ public class DateFormatter implements Formatter {
try {
return dateFormat.parse(formattedString);
} catch (ParseException e) {
- throw new InvalidFormatException(formattedString, dateFormat.toString());
+ throw new InvalidFormatException(formattedString, determinePattern(pattern), e);
}
}
+ // subclassing hookings
+
protected DateFormat getDateFormat() {
- String pattern = this.pattern;
- if (pattern == null) {
- pattern = DEFAULT_PATTERN;
- }
- Locale locale = this.locale;
- if (locale == null) {
- locale = Locale.getDefault();
- }
+ String pattern = determinePattern(this.pattern);
+ Locale locale = determineLocale(this.locale);
return new SimpleDateFormat(pattern, locale);
}
+ // internal helpers
+
+ private String determinePattern(String pattern) {
+ return pattern != null ? pattern : DEFAULT_PATTERN;
+ }
+
+ private Locale determineLocale(Locale locale) {
+ return locale != null ? locale : Locale.getDefault();
+ }
+
}
\ No newline at end of file
diff --git a/spring-binding/src/main/java/org/springframework/binding/format/formatters/NumberFormatter.java b/spring-binding/src/main/java/org/springframework/binding/format/formatters/NumberFormatter.java
index 0dac00bc..3ba3a8a0 100644
--- a/spring-binding/src/main/java/org/springframework/binding/format/formatters/NumberFormatter.java
+++ b/spring-binding/src/main/java/org/springframework/binding/format/formatters/NumberFormatter.java
@@ -25,8 +25,9 @@ import org.springframework.util.NumberUtils;
import org.springframework.util.StringUtils;
/**
- * A formatter for the common number types such as integers, and big decimals.
- *
+ * A formatter for common number types such as integers and big decimals. Supports basic decoding of number values from
+ * text, as well as applying custom number format patterns.
+ * @see DecimalFormat
* @author Keith Donald
*/
public class NumberFormatter implements Formatter {
@@ -78,7 +79,7 @@ public class NumberFormatter implements Formatter {
try {
return NumberUtils.parseNumber(formattedString, numberClass);
} catch (NumberFormatException e) {
- throw new InvalidFormatException(formattedString, "A " + numberClass.getName(), e);
+ throw new InvalidFormatException(formattedString, "A valid " + numberClass.getName() + " string", e);
}
}
}
diff --git a/spring-binding/src/main/java/org/springframework/binding/format/formatters/PropertyEditorFormatter.java b/spring-binding/src/main/java/org/springframework/binding/format/formatters/PropertyEditorFormatter.java
index 02b6ae63..8e3745ee 100644
--- a/spring-binding/src/main/java/org/springframework/binding/format/formatters/PropertyEditorFormatter.java
+++ b/spring-binding/src/main/java/org/springframework/binding/format/formatters/PropertyEditorFormatter.java
@@ -21,7 +21,8 @@ import org.springframework.binding.format.Formatter;
import org.springframework.util.Assert;
/**
- * Adapts a property editor to the formatter interface.
+ * Adapts a {@link PropertyEditor} to the formatter interface.
+ *
* @author Keith Donald
*/
public class PropertyEditorFormatter implements Formatter {
@@ -32,7 +33,7 @@ public class PropertyEditorFormatter implements Formatter {
* Wrap the given property editor in a formatter.
*/
public PropertyEditorFormatter(PropertyEditor propertyEditor) {
- Assert.notNull(propertyEditor, "Property editor is required");
+ Assert.notNull(propertyEditor, "The PropertyEditor is required");
this.propertyEditor = propertyEditor;
}
diff --git a/spring-binding/src/main/java/org/springframework/binding/mapping/impl/DefaultMapper.java b/spring-binding/src/main/java/org/springframework/binding/mapping/impl/DefaultMapper.java
index 25f4fab0..75095e4e 100644
--- a/spring-binding/src/main/java/org/springframework/binding/mapping/impl/DefaultMapper.java
+++ b/spring-binding/src/main/java/org/springframework/binding/mapping/impl/DefaultMapper.java
@@ -15,8 +15,8 @@
*/
package org.springframework.binding.mapping.impl;
+import java.util.ArrayList;
import java.util.Iterator;
-import java.util.LinkedList;
import java.util.List;
import org.apache.commons.logging.Log;
@@ -29,13 +29,16 @@ import org.springframework.core.style.ToStringCreator;
/**
* Generic mapper implementation that allows mappings to be configured programatically.
+ *
+ * @see #addMapping(DefaultMapping)
+ * @see #setConversionService(ConversionService)
* @author Keith Donald
*/
public class DefaultMapper implements Mapper {
private static final Log logger = LogFactory.getLog(DefaultMapper.class);
- private List mappings = new LinkedList();
+ private List mappings = new ArrayList();
private ConversionService conversionService;
@@ -56,7 +59,7 @@ public class DefaultMapper implements Mapper {
/**
* Add a mapping to this mapper.
- * @param mapping the mapping to add
+ * @param mapping the mapping to add (required)
* @return this, to support convenient call chaining
*/
public DefaultMapper addMapping(DefaultMapping mapping) {
@@ -73,15 +76,21 @@ public class DefaultMapper implements Mapper {
}
public MappingResults map(Object source, Object target) {
+ if (logger.isDebugEnabled()) {
+ logger.debug("Beginning mapping between source [" + source.getClass().getName() + "] and target ["
+ + target.getClass().getName() + "]");
+ }
DefaultMappingContext context = new DefaultMappingContext(source, target, conversionService);
Iterator it = mappings.iterator();
while (it.hasNext()) {
DefaultMapping mapping = (DefaultMapping) it.next();
mapping.map(context);
}
- MappingResults results = context.toResult();
+ MappingResults results = context.getMappingResults();
if (logger.isDebugEnabled()) {
- logger.debug("Mapper completed; results = " + results);
+ logger.debug("Completing mapping between source [" + source.getClass().getName() + "] and target ["
+ + target.getClass().getName() + "]; total mappings = " + results.getAllResults().size()
+ + "; total errors = " + results.getErrorResults().size() + "; " + results);
}
return results;
}
diff --git a/spring-binding/src/main/java/org/springframework/binding/mapping/impl/DefaultMapping.java b/spring-binding/src/main/java/org/springframework/binding/mapping/impl/DefaultMapping.java
index f7c2f1a8..573f5e83 100644
--- a/spring-binding/src/main/java/org/springframework/binding/mapping/impl/DefaultMapping.java
+++ b/spring-binding/src/main/java/org/springframework/binding/mapping/impl/DefaultMapping.java
@@ -15,7 +15,7 @@
*/
package org.springframework.binding.mapping.impl;
-import org.springframework.binding.convert.ConversionException;
+import org.springframework.binding.convert.ConversionExecutionException;
import org.springframework.binding.convert.ConversionExecutor;
import org.springframework.binding.convert.ConversionService;
import org.springframework.binding.expression.EvaluationException;
@@ -123,9 +123,9 @@ public class DefaultMapping implements Mapping {
if (sourceValue != null) {
if (typeConverter != null) {
try {
- targetValue = typeConverter.execute(targetValue, context);
- } catch (ConversionException e) {
- context.setTypeConversionErrorResult(sourceValue, e.getTargetClass());
+ targetValue = typeConverter.execute(sourceValue, context);
+ } catch (ConversionExecutionException e) {
+ context.setTypeConversionErrorResult(e);
return;
}
} else {
@@ -139,12 +139,12 @@ public class DefaultMapping implements Mapping {
return;
}
if (targetType != null && !targetType.isInstance(targetValue)) {
+ ConversionExecutor typeConverter = conversionService.getConversionExecutor(sourceValue
+ .getClass(), targetType);
try {
- ConversionExecutor typeConverter = conversionService.getConversionExecutor(sourceValue
- .getClass(), targetType);
targetValue = typeConverter.execute(sourceValue, context);
- } catch (ConversionException e) {
- context.setTypeConversionErrorResult(sourceValue, e.getTargetClass());
+ } catch (ConversionExecutionException e) {
+ context.setTypeConversionErrorResult(e);
return;
}
}
diff --git a/spring-binding/src/main/java/org/springframework/binding/mapping/impl/DefaultMappingContext.java b/spring-binding/src/main/java/org/springframework/binding/mapping/impl/DefaultMappingContext.java
index 8b1e4867..a39ff302 100644
--- a/spring-binding/src/main/java/org/springframework/binding/mapping/impl/DefaultMappingContext.java
+++ b/spring-binding/src/main/java/org/springframework/binding/mapping/impl/DefaultMappingContext.java
@@ -20,6 +20,7 @@ import java.util.List;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
+import org.springframework.binding.convert.ConversionExecutionException;
import org.springframework.binding.convert.ConversionService;
import org.springframework.binding.expression.EvaluationException;
import org.springframework.binding.mapping.Mapping;
@@ -92,10 +93,10 @@ public class DefaultMappingContext {
* @param mapping the mapping to make the current mapping
*/
public void setCurrentMapping(Mapping mapping) {
- if (this.currentMapping != null) {
+ if (currentMapping != null) {
throw new IllegalStateException("The current mapping has not finished yet");
}
- this.currentMapping = mapping;
+ currentMapping = mapping;
}
/**
@@ -120,11 +121,12 @@ public class DefaultMappingContext {
/**
* Indicates the current mapping ended with a 'type conversion' error. This means the value obtained from the source
* could not be converted to a type that could be assigned to the target expression.
- * @param originalValue the original source value that could not be converted during the mapping attempt
- * @param targetType the desired target type to which conversion could not be performed
+ * @param exception the conversion exception that occurred, containing the original source value that could not be
+ * converted during the mapping attempt, as well as the desired target type to which conversion could not be
+ * performed
*/
- public void setTypeConversionErrorResult(Object originalValue, Class targetType) {
- add(new MappingResult(currentMapping, new TypeConversionError(originalValue, targetType)));
+ public void setTypeConversionErrorResult(ConversionExecutionException exception) {
+ add(new MappingResult(currentMapping, new TypeConversionError(exception)));
}
/**
@@ -143,7 +145,11 @@ public class DefaultMappingContext {
add(new MappingResult(currentMapping, new TargetAccessError(originalValue, error)));
}
- public MappingResults toResult() {
+ /**
+ * Returns the mapping results recorded in this context.
+ * @return the mapping results
+ */
+ public MappingResults getMappingResults() {
return new DefaultMappingResults(source, target, mappingResults);
}
@@ -153,8 +159,8 @@ public class DefaultMappingContext {
if (logger.isDebugEnabled()) {
logger.debug("Adding " + result);
}
- this.mappingResults.add(result);
- this.currentMapping = null;
+ mappingResults.add(result);
+ currentMapping = null;
}
}
diff --git a/spring-binding/src/main/java/org/springframework/binding/mapping/impl/DefaultMappingResults.java b/spring-binding/src/main/java/org/springframework/binding/mapping/impl/DefaultMappingResults.java
index 5971911e..67f273fd 100644
--- a/spring-binding/src/main/java/org/springframework/binding/mapping/impl/DefaultMappingResults.java
+++ b/spring-binding/src/main/java/org/springframework/binding/mapping/impl/DefaultMappingResults.java
@@ -23,9 +23,6 @@ import java.util.List;
import org.springframework.binding.mapping.MappingResult;
import org.springframework.binding.mapping.MappingResults;
import org.springframework.binding.mapping.MappingResultsCriteria;
-import org.springframework.core.style.ToStringCreator;
-import org.springframework.util.ClassUtils;
-import org.springframework.util.ObjectUtils;
/**
* Default mapping results implementation.
@@ -99,11 +96,6 @@ public class DefaultMappingResults implements MappingResults {
}
public String toString() {
- String sourceString = ClassUtils.getShortName(source.getClass()) + "@"
- + ObjectUtils.getIdentityHexString(source);
- String targetString = ClassUtils.getShortName(target.getClass()) + "@"
- + ObjectUtils.getIdentityHexString(target);
- return new ToStringCreator(this).append("source", sourceString).append("target", targetString).append(
- "results", mappingResults).toString();
+ return "Mapping Results = " + mappingResults.toString();
}
}
diff --git a/spring-binding/src/main/java/org/springframework/binding/mapping/results/TypeConversionError.java b/spring-binding/src/main/java/org/springframework/binding/mapping/results/TypeConversionError.java
index d8649d4e..30100999 100644
--- a/spring-binding/src/main/java/org/springframework/binding/mapping/results/TypeConversionError.java
+++ b/spring-binding/src/main/java/org/springframework/binding/mapping/results/TypeConversionError.java
@@ -15,6 +15,7 @@
*/
package org.springframework.binding.mapping.results;
+import org.springframework.binding.convert.ConversionExecutionException;
import org.springframework.binding.mapping.Result;
import org.springframework.core.style.ToStringCreator;
@@ -29,18 +30,18 @@ public class TypeConversionError extends Result {
private Class targetType;
+ private ConversionExecutionException exception;
+
/**
* Creates a new type conversion error.
- * @param originalValue the value that could not be converted
- * @param targetType the target type of the conversion
+ * @param exception the underlying type conversion exception
*/
- public TypeConversionError(Object originalValue, Class targetType) {
- this.originalValue = originalValue;
- this.targetType = targetType;
+ public TypeConversionError(ConversionExecutionException exception) {
+ this.exception = exception;
}
public Object getOriginalValue() {
- return originalValue;
+ return exception.getValue();
}
public Object getMappedValue() {
@@ -60,12 +61,19 @@ public class TypeConversionError extends Result {
/**
* Returns the target type of the conversion attempt.
*/
- public Class getTargetType() {
- return targetType;
+ public Class getTargetClass() {
+ return exception.getTargetClass();
+ }
+
+ /**
+ * Returns the backing type conversion exception that occurred.
+ */
+ public ConversionExecutionException getException() {
+ return exception;
}
public String toString() {
return new ToStringCreator(this).append("originalValue", originalValue).append("targetType", targetType)
- .toString();
+ .append("details", exception.getMessage()).toString();
}
}
diff --git a/spring-binding/src/test/java/org/springframework/binding/convert/service/DefaultConversionServiceTests.java b/spring-binding/src/test/java/org/springframework/binding/convert/service/DefaultConversionServiceTests.java
index ce3f4427..e4da6b19 100644
--- a/spring-binding/src/test/java/org/springframework/binding/convert/service/DefaultConversionServiceTests.java
+++ b/spring-binding/src/test/java/org/springframework/binding/convert/service/DefaultConversionServiceTests.java
@@ -21,12 +21,11 @@ import java.util.List;
import junit.framework.TestCase;
-import org.springframework.binding.convert.ConversionException;
+import org.springframework.binding.convert.ConversionExecutionException;
import org.springframework.binding.convert.ConversionExecutor;
+import org.springframework.binding.convert.ConversionExecutorNotFoundException;
import org.springframework.binding.convert.Converter;
import org.springframework.binding.convert.converters.TextToBoolean;
-import org.springframework.binding.convert.service.DefaultConversionService;
-import org.springframework.binding.convert.service.StaticConversionExecutor;
/**
* Test case for the default conversion service.
@@ -44,7 +43,7 @@ public class DefaultConversionServiceTests extends TestCase {
try {
service.getConversionExecutor(List.class, ArrayList.class);
fail();
- } catch (ConversionException e) {
+ } catch (ConversionExecutorNotFoundException e) {
// expected
}
}
@@ -60,7 +59,7 @@ public class DefaultConversionServiceTests extends TestCase {
try {
executor.execute("ja");
fail();
- } catch (ConversionException e) {
+ } catch (ConversionExecutionException e) {
// expected
}
@@ -76,7 +75,7 @@ public class DefaultConversionServiceTests extends TestCase {
try {
service.getConversionExecutor(String.class, HashMap.class);
fail("Should have thrown an exception");
- } catch (ConversionException e) {
+ } catch (ConversionExecutorNotFoundException e) {
}
}
diff --git a/spring-binding/src/test/java/org/springframework/binding/convert/service/StaticConversionExecutorImplTests.java b/spring-binding/src/test/java/org/springframework/binding/convert/service/StaticConversionExecutorImplTests.java
index 7b664000..5508204c 100644
--- a/spring-binding/src/test/java/org/springframework/binding/convert/service/StaticConversionExecutorImplTests.java
+++ b/spring-binding/src/test/java/org/springframework/binding/convert/service/StaticConversionExecutorImplTests.java
@@ -19,8 +19,8 @@ import java.util.Date;
import junit.framework.TestCase;
-import org.springframework.binding.convert.ConversionException;
-import org.springframework.binding.convert.converters.AbstractConverter;
+import org.springframework.binding.convert.ConversionExecutionException;
+import org.springframework.binding.convert.Converter;
public class StaticConversionExecutorImplTests extends TestCase {
@@ -47,12 +47,12 @@ public class StaticConversionExecutorImplTests extends TestCase {
try {
conversionExecutor.execute(new StringBuffer());
fail();
- } catch (ConversionException e) {
+ } catch (ConversionExecutionException e) {
// expected
}
}
- private class TestTextToDate extends AbstractConverter {
+ private class TestTextToDate implements Converter {
public Class[] getSourceClasses() {
return new Class[] { String.class };
@@ -62,7 +62,7 @@ public class StaticConversionExecutorImplTests extends TestCase {
return new Class[] { Date.class };
}
- protected Object doConvert(Object source, Class targetClass, Object context) throws Exception {
+ public Object convert(Object source, Class targetClass, Object context) throws Exception {
return source == null ? null : new Date();
}
}
diff --git a/spring-binding/src/test/java/org/springframework/binding/format/formatters/BooleanFormatterTests.java b/spring-binding/src/test/java/org/springframework/binding/format/formatters/BooleanFormatterTests.java
new file mode 100644
index 00000000..680d4f56
--- /dev/null
+++ b/spring-binding/src/test/java/org/springframework/binding/format/formatters/BooleanFormatterTests.java
@@ -0,0 +1,47 @@
+package org.springframework.binding.format.formatters;
+
+import junit.framework.TestCase;
+
+import org.springframework.binding.format.InvalidFormatException;
+
+public class BooleanFormatterTests extends TestCase {
+
+ private BooleanFormatter formatter = new BooleanFormatter();
+
+ public void testFormatTrue() {
+ assertEquals("true", formatter.format(Boolean.TRUE));
+ }
+
+ public void testFormatFalse() {
+ assertEquals("false", formatter.format(Boolean.FALSE));
+ }
+
+ public void testFormatNull() {
+ assertEquals("", formatter.format(null));
+ }
+
+ public void testParseTrue() {
+ assertEquals(Boolean.TRUE, formatter.parse("true"));
+ }
+
+ public void testParseFalse() {
+ assertEquals(Boolean.FALSE, formatter.parse("false"));
+ }
+
+ public void testParseInvalid() {
+ try {
+ formatter.parse("bogus");
+ fail("Should have failed");
+ } catch (InvalidFormatException e) {
+ }
+ }
+
+ public void testParseNull() {
+ assertNull(formatter.parse(null));
+ }
+
+ public void testParseEmptyString() {
+ assertNull(formatter.parse(""));
+ }
+
+}
diff --git a/spring-binding/src/test/java/org/springframework/binding/format/formatters/DateFormatterTests.java b/spring-binding/src/test/java/org/springframework/binding/format/formatters/DateFormatterTests.java
index 3c4b53a8..58ebf8a8 100644
--- a/spring-binding/src/test/java/org/springframework/binding/format/formatters/DateFormatterTests.java
+++ b/spring-binding/src/test/java/org/springframework/binding/format/formatters/DateFormatterTests.java
@@ -6,6 +6,8 @@ import java.util.GregorianCalendar;
import junit.framework.TestCase;
+import org.springframework.binding.format.InvalidFormatException;
+
public class DateFormatterTests extends TestCase {
public void testFormatDefaultPattern() {
@@ -14,6 +16,18 @@ public class DateFormatterTests extends TestCase {
assertEquals("2008-04-01", dateFormatter.format(calendar.getTime()));
}
+ public void testFormatCustomPattern() {
+ DateFormatter dateFormatter = new DateFormatter();
+ dateFormatter.setPattern("MM-dd-yyyy");
+ Calendar calendar = new GregorianCalendar(2008, 3, 1);
+ assertEquals("04-01-2008", dateFormatter.format(calendar.getTime()));
+ }
+
+ public void testFormatNull() {
+ DateFormatter dateFormatter = new DateFormatter();
+ assertEquals("", dateFormatter.format(null));
+ }
+
public void testParseDefaultPattern() {
DateFormatter dateFormatter = new DateFormatter();
Calendar calendar = new GregorianCalendar();
@@ -23,4 +37,24 @@ public class DateFormatterTests extends TestCase {
assertEquals(1, calendar.get(Calendar.DAY_OF_MONTH));
}
+ public void testParseInvalidFormat() {
+ DateFormatter dateFormatter = new DateFormatter();
+ try {
+ dateFormatter.parse("01/04/08");
+ fail("Should have failed");
+ } catch (InvalidFormatException e) {
+
+ }
+ }
+
+ public void testParseNull() {
+ DateFormatter dateFormatter = new DateFormatter();
+ assertNull(dateFormatter.parse(null));
+ }
+
+ public void testParseEmptyString() {
+ DateFormatter dateFormatter = new DateFormatter();
+ assertNull(dateFormatter.parse(""));
+ }
+
}
diff --git a/spring-binding/src/test/java/org/springframework/binding/format/formatters/NumberFormatterTests.java b/spring-binding/src/test/java/org/springframework/binding/format/formatters/NumberFormatterTests.java
new file mode 100644
index 00000000..9ec1960a
--- /dev/null
+++ b/spring-binding/src/test/java/org/springframework/binding/format/formatters/NumberFormatterTests.java
@@ -0,0 +1,73 @@
+package org.springframework.binding.format.formatters;
+
+import java.math.BigDecimal;
+
+import junit.framework.TestCase;
+
+import org.springframework.binding.format.InvalidFormatException;
+
+public class NumberFormatterTests extends TestCase {
+
+ private NumberFormatter formatter;
+
+ public void testFormatIntegerDefaultPattern() {
+ formatter = new NumberFormatter(Integer.class);
+ String value = formatter.format(new Integer(12345));
+ assertEquals("12345", value);
+ }
+
+ public void testFormatBigDecimalCustomPattern() {
+ formatter = new NumberFormatter(BigDecimal.class);
+ formatter.setPattern("000.00");
+ BigDecimal dec = new BigDecimal("123.45");
+ String value = formatter.format(dec);
+ assertEquals("123.45", value);
+ }
+
+ public void testFormatNull() {
+ formatter = new NumberFormatter(Integer.class);
+ assertEquals("", formatter.format(null));
+ }
+
+ public void testParseIntegerDefaultPattern() {
+ formatter = new NumberFormatter(Integer.class);
+ Integer integer = (Integer) formatter.parse("12345");
+ assertEquals(Integer.valueOf(12345), integer);
+ }
+
+ public void testParseBigDecimalCustomPattern() {
+ formatter = new NumberFormatter(BigDecimal.class);
+ formatter.setPattern("000.00");
+ BigDecimal dec = (BigDecimal) formatter.parse("123.45");
+ assertEquals(new BigDecimal("123.45"), dec);
+ }
+
+ public void testParseInvalidFormatNoPattern() {
+ try {
+ formatter = new NumberFormatter(Integer.class);
+ formatter.parse("12345b");
+ fail("Should have failed");
+ } catch (InvalidFormatException e) {
+ }
+ }
+
+ public void testParseInvalidFormatPattern() {
+ try {
+ formatter = new NumberFormatter(BigDecimal.class);
+ formatter.setPattern("000.00");
+ formatter.parse("bogus");
+ } catch (InvalidFormatException e) {
+ }
+ }
+
+ public void testParseNull() {
+ formatter = new NumberFormatter(Integer.class);
+ assertNull(formatter.parse(null));
+ }
+
+ public void testParseEmptyString() {
+ formatter = new NumberFormatter(Integer.class);
+ assertNull(formatter.parse(""));
+ }
+
+}
diff --git a/spring-binding/src/test/java/org/springframework/binding/format/impl/FormatterRegistryImplTests.java b/spring-binding/src/test/java/org/springframework/binding/format/impl/GenericFormatterRegistryTests.java
similarity index 98%
rename from spring-binding/src/test/java/org/springframework/binding/format/impl/FormatterRegistryImplTests.java
rename to spring-binding/src/test/java/org/springframework/binding/format/impl/GenericFormatterRegistryTests.java
index 629913cf..7ca7f03d 100644
--- a/spring-binding/src/test/java/org/springframework/binding/format/impl/FormatterRegistryImplTests.java
+++ b/spring-binding/src/test/java/org/springframework/binding/format/impl/GenericFormatterRegistryTests.java
@@ -9,7 +9,7 @@ import org.springframework.binding.format.InvalidFormatException;
import org.springframework.binding.format.formatters.NumberFormatter;
import org.springframework.binding.format.registry.GenericFormatterRegistry;
-public class FormatterRegistryImplTests extends TestCase {
+public class GenericFormatterRegistryTests extends TestCase {
GenericFormatterRegistry registry = new GenericFormatterRegistry();
diff --git a/spring-binding/src/test/java/org/springframework/binding/mapping/DefaultMapperTests.java b/spring-binding/src/test/java/org/springframework/binding/mapping/DefaultMapperTests.java
new file mode 100644
index 00000000..731e678e
--- /dev/null
+++ b/spring-binding/src/test/java/org/springframework/binding/mapping/DefaultMapperTests.java
@@ -0,0 +1,148 @@
+package org.springframework.binding.mapping;
+
+import java.util.Locale;
+
+import junit.framework.TestCase;
+
+import org.springframework.binding.convert.Converter;
+import org.springframework.binding.convert.service.DefaultConversionService;
+import org.springframework.binding.expression.ExpressionParser;
+import org.springframework.binding.expression.el.DefaultExpressionFactoryUtils;
+import org.springframework.binding.expression.el.ELExpressionParser;
+import org.springframework.binding.expression.support.FluentParserContext;
+import org.springframework.binding.mapping.impl.DefaultMapper;
+import org.springframework.binding.mapping.impl.DefaultMapping;
+import org.springframework.util.StringUtils;
+
+public class DefaultMapperTests extends TestCase {
+ private DefaultMapper mapper = new DefaultMapper();
+ private ExpressionParser parser = new ELExpressionParser(DefaultExpressionFactoryUtils.createExpressionFactory());
+
+ public void testMapping() {
+ DefaultMapping mapping1 = new DefaultMapping(parser.parseExpression("foo", null), parser.parseExpression("bar",
+ null));
+ DefaultMapping mapping2 = new DefaultMapping(parser.parseExpression("foo", null), parser.parseExpression("baz",
+ null));
+ mapper.addMapping(mapping1);
+ mapper.addMapping(mapping2);
+ assertEquals(2, mapper.getMappings().length);
+ TestBean bean1 = new TestBean();
+ bean1.foo = "a";
+ TestBean2 bean2 = new TestBean2();
+ MappingResults results = mapper.map(bean1, bean2);
+ assertSame(bean1, results.getSource());
+ assertSame(bean2, results.getTarget());
+ assertEquals(2, results.getAllResults().size());
+ assertEquals(0, results.getErrorResults().size());
+ assertEquals("a", bean2.bar);
+ assertEquals("a", bean2.baz);
+ assertEquals(1, results.getResults(new MappingResultsCriteria() {
+ public boolean test(MappingResult result) {
+ if (result.getMapping().getTargetExpression().getExpressionString().equals("baz")) {
+ return true;
+ } else {
+ return false;
+ }
+ }
+ }).size());
+ }
+
+ public void testMappingWithAutomaticConversion() {
+ DefaultMapping mapping1 = new DefaultMapping(parser.parseExpression("foo", new FluentParserContext()
+ .expectResult(Integer.class)), parser.parseExpression("boop", null));
+ mapper.addMapping(mapping1);
+ TestBean bean1 = new TestBean();
+ bean1.foo = "12345";
+ TestBean2 bean2 = new TestBean2();
+ MappingResults results = mapper.map(bean1, bean2);
+ assertSame(bean1, results.getSource());
+ assertSame(bean2, results.getTarget());
+ assertEquals(1, results.getAllResults().size());
+ assertEquals(0, results.getErrorResults().size());
+ assertEquals(new Integer(12345), bean2.boop);
+ }
+
+ public void testMappingWithCustomConversionService() {
+ DefaultConversionService conversionService = new DefaultConversionService();
+ conversionService.addConverter(new Converter() {
+ public Class[] getSourceClasses() {
+ return new Class[] { String.class };
+ }
+
+ public Class[] getTargetClasses() {
+ return new Class[] { Locale.class };
+ }
+
+ public Object convert(Object source, Class targetClass, Object context) throws Exception {
+ return StringUtils.parseLocaleString((String) source);
+ }
+ });
+ mapper.setConversionService(conversionService);
+ DefaultMapping mapping1 = new DefaultMapping(parser.parseExpression("foo", null), parser.parseExpression(
+ "beep", null));
+ mapper.addMapping(mapping1);
+ TestBean bean1 = new TestBean();
+ bean1.foo = "en";
+ TestBean2 bean2 = new TestBean2();
+ MappingResults results = mapper.map(bean1, bean2);
+ assertSame(bean1, results.getSource());
+ assertSame(bean2, results.getTarget());
+ assertEquals(1, results.getAllResults().size());
+ System.out.println(results.getAllResults());
+ assertEquals(0, results.getErrorResults().size());
+ assertEquals(Locale.ENGLISH, bean2.beep);
+ }
+
+ public static class TestBean {
+ private String foo;
+
+ public String getFoo() {
+ return foo;
+ }
+
+ public void setFoo(String foo) {
+ this.foo = foo;
+ }
+
+ }
+
+ public static class TestBean2 {
+ private String bar;
+ private String baz;
+ private Integer boop;
+ private Locale beep;
+
+ public String getBar() {
+ return bar;
+ }
+
+ public String getBaz() {
+ return baz;
+ }
+
+ public void setBaz(String baz) {
+ this.baz = baz;
+ }
+
+ public void setBar(String bar) {
+ this.bar = bar;
+ }
+
+ public Integer getBoop() {
+ return boop;
+ }
+
+ public void setBoop(Integer boop) {
+ this.boop = boop;
+ }
+
+ public Locale getBeep() {
+ return beep;
+ }
+
+ public void setBeep(Locale beep) {
+ this.beep = beep;
+ }
+
+ }
+}
\ No newline at end of file
diff --git a/spring-faces/src/main/java/org/springframework/faces/model/converter/DataModelConverter.java b/spring-faces/src/main/java/org/springframework/faces/model/converter/DataModelConverter.java
index f6b03e9d..6cd98c9d 100644
--- a/spring-faces/src/main/java/org/springframework/faces/model/converter/DataModelConverter.java
+++ b/spring-faces/src/main/java/org/springframework/faces/model/converter/DataModelConverter.java
@@ -21,7 +21,7 @@ import java.util.List;
import javax.faces.model.DataModel;
import org.springframework.binding.convert.Converter;
-import org.springframework.binding.convert.converters.AbstractConverter;
+import org.springframework.faces.model.OneSelectionTrackingListDataModel;
import org.springframework.util.ClassUtils;
/**
@@ -30,14 +30,7 @@ import org.springframework.util.ClassUtils;
*
* @author Jeremy Grelle
*/
-public class DataModelConverter extends AbstractConverter {
-
- protected Object doConvert(Object source, Class targetClass, Object context) throws Exception {
- Constructor emptyConstructor = ClassUtils.getConstructorIfAvailable(targetClass, new Class[] {});
- DataModel model = (DataModel) emptyConstructor.newInstance(new Object[] {});
- model.setWrappedData(source);
- return model;
- }
+public class DataModelConverter implements Converter {
public Class[] getSourceClasses() {
return new Class[] { Object[].class, List.class, Object.class };
@@ -47,4 +40,14 @@ public class DataModelConverter extends AbstractConverter {
return new Class[] { DataModel.class };
}
+ public Object convert(Object source, Class targetClass, Object context) throws Exception {
+ if (targetClass.equals(DataModel.class)) {
+ targetClass = OneSelectionTrackingListDataModel.class;
+ }
+ Constructor emptyConstructor = ClassUtils.getConstructorIfAvailable(targetClass, new Class[] {});
+ DataModel model = (DataModel) emptyConstructor.newInstance(new Object[] {});
+ model.setWrappedData(source);
+ return model;
+ }
+
}
diff --git a/spring-faces/src/main/java/org/springframework/faces/model/converter/FacesConversionService.java b/spring-faces/src/main/java/org/springframework/faces/model/converter/FacesConversionService.java
index c607e401..ba29a70b 100644
--- a/spring-faces/src/main/java/org/springframework/faces/model/converter/FacesConversionService.java
+++ b/spring-faces/src/main/java/org/springframework/faces/model/converter/FacesConversionService.java
@@ -12,6 +12,8 @@ e.org/licenses/LICENSE-2.0
*/
package org.springframework.faces.model.converter;
+import javax.faces.model.DataModel;
+
import org.springframework.binding.convert.ConversionService;
import org.springframework.binding.convert.converters.TextToClass;
import org.springframework.binding.convert.service.DefaultConversionService;
@@ -37,6 +39,6 @@ public class FacesConversionService extends DefaultConversionService {
protected void addFacesConverters() {
addConverter(new DataModelConverter());
TextToClass classConverter = (TextToClass) getConverter(String.class, Class.class);
- classConverter.addAlias("dataModel", OneSelectionTrackingListDataModel.class);
+ classConverter.addAlias("dataModel", DataModel.class);
}
}
diff --git a/spring-faces/src/test/java/org/springframework/faces/config/FacesFlowBuilderServicesBeanDefinitionParserTests.java b/spring-faces/src/test/java/org/springframework/faces/config/FacesFlowBuilderServicesBeanDefinitionParserTests.java
index 923a03c8..2e811cdc 100644
--- a/spring-faces/src/test/java/org/springframework/faces/config/FacesFlowBuilderServicesBeanDefinitionParserTests.java
+++ b/spring-faces/src/test/java/org/springframework/faces/config/FacesFlowBuilderServicesBeanDefinitionParserTests.java
@@ -2,7 +2,7 @@ package org.springframework.faces.config;
import junit.framework.TestCase;
-import org.springframework.binding.convert.ConversionException;
+import org.springframework.binding.convert.ConversionExecutionException;
import org.springframework.binding.convert.ConversionExecutor;
import org.springframework.binding.convert.ConversionService;
import org.springframework.binding.expression.Expression;
@@ -74,21 +74,21 @@ public class FacesFlowBuilderServicesBeanDefinitionParserTests extends TestCase
public static class TestConversionService implements ConversionService {
- public Class getClassByAlias(String alias) throws ConversionException {
+ public Class getClassByAlias(String alias) throws ConversionExecutionException {
throw new UnsupportedOperationException("Auto-generated method stub");
}
public ConversionExecutor getConversionExecutor(Class sourceClass, Class targetClass)
- throws ConversionException {
+ throws ConversionExecutionException {
throw new UnsupportedOperationException("Auto-generated method stub");
}
public ConversionExecutor getConversionExecutorByTargetAlias(Class sourceClass, String targetAlias)
- throws ConversionException {
+ throws ConversionExecutionException {
throw new UnsupportedOperationException("Auto-generated method stub");
}
- public ConversionExecutor[] getConversionExecutorsForSource(Class sourceClass) throws ConversionException {
+ public ConversionExecutor[] getConversionExecutorsForSource(Class sourceClass) throws ConversionExecutionException {
throw new UnsupportedOperationException("Auto-generated method stub");
}
diff --git a/spring-faces/src/test/java/org/springframework/faces/model/converter/DataModelConverterTests.java b/spring-faces/src/test/java/org/springframework/faces/model/converter/DataModelConverterTests.java
index 5d9cb20b..35949f2d 100644
--- a/spring-faces/src/test/java/org/springframework/faces/model/converter/DataModelConverterTests.java
+++ b/spring-faces/src/test/java/org/springframework/faces/model/converter/DataModelConverterTests.java
@@ -7,16 +7,25 @@ import java.util.List;
import javax.faces.model.DataModel;
import javax.faces.model.ListDataModel;
+import junit.framework.TestCase;
+
import org.springframework.binding.convert.Converter;
import org.springframework.faces.model.SerializableListDataModel;
-import junit.framework.TestCase;
-
public class DataModelConverterTests extends TestCase {
Converter converter = new DataModelConverter();
- public void testConvertListToListDataModel() {
+ public void testConvertListToDataModel() throws Exception {
+ List sourceList = new ArrayList();
+
+ DataModel resultModel = (DataModel) converter.convert(sourceList, DataModel.class, null);
+
+ assertNotNull(resultModel);
+ assertSame(sourceList, resultModel.getWrappedData());
+ }
+
+ public void testConvertListToListDataModel() throws Exception {
List sourceList = new ArrayList();
DataModel resultModel = (DataModel) converter.convert(sourceList, ListDataModel.class, null);
@@ -25,7 +34,7 @@ public class DataModelConverterTests extends TestCase {
assertSame(sourceList, resultModel.getWrappedData());
}
- public void testConvertListToSerializableListDataModel() {
+ public void testConvertListToSerializableListDataModel() throws Exception {
List sourceList = new ArrayList();
DataModel resultModel = (DataModel) converter.convert(sourceList, SerializableListDataModel.class, null);
@@ -35,7 +44,7 @@ public class DataModelConverterTests extends TestCase {
assertTrue(resultModel instanceof Serializable);
}
- public void testConvertListToSerializableListDataModelNullSource() {
+ public void testConvertListToSerializableListDataModelNullSource() throws Exception {
List sourceList = null;
DataModel resultModel = (DataModel) converter.convert(sourceList, SerializableListDataModel.class, null);
diff --git a/spring-faces/src/test/java/org/springframework/faces/model/converter/FacesConversionServiceTests.java b/spring-faces/src/test/java/org/springframework/faces/model/converter/FacesConversionServiceTests.java
new file mode 100644
index 00000000..4b0c7f8b
--- /dev/null
+++ b/spring-faces/src/test/java/org/springframework/faces/model/converter/FacesConversionServiceTests.java
@@ -0,0 +1,26 @@
+package org.springframework.faces.model.converter;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.faces.model.DataModel;
+
+import junit.framework.TestCase;
+
+import org.springframework.binding.convert.ConversionExecutor;
+
+public class FacesConversionServiceTests extends TestCase {
+ private FacesConversionService service;
+
+ protected void setUp() throws Exception {
+ service = new FacesConversionService();
+ }
+
+ public void testGetAbstractType() {
+ ConversionExecutor executor = service.getConversionExecutor(List.class, DataModel.class);
+ ArrayList list = new ArrayList();
+ list.add("foo");
+ executor.execute(list);
+ }
+
+}
diff --git a/spring-webflow-reference/src/flow-managed-persistence.xml b/spring-webflow-reference/src/flow-managed-persistence.xml
index 36ba350c..d6a3571e 100644
--- a/spring-webflow-reference/src/flow-managed-persistence.xml
+++ b/spring-webflow-reference/src/flow-managed-persistence.xml
@@ -85,13 +85,15 @@
ConversationScoped PersistenceContext
- This pattern creates a PersistenceContext in conversationScope on flow startup,
- and uses that context for data access until the conversation ends.
+ This pattern creates a PersistenceContext in conversationScope on flow startup, and uses that context for data access until the conversation ends.
This pattern generally employs a manual flush mode; that is, the application decides when to flush changes to the database.
A convention for flow-managed flushing may be employed, such as always flushing after a transition one from one view-state to another.
This pattern provides no flow-level isolation of intermediate edits since flushing synchronizes persistent object state with the database.
With this pattern, all data access generally occurs non-transactionally.
+
+ An implementation of this flow-managed persistence pattern is not yet available in the Web Flow distribution, and will be considered for future releases.
+
ViewState PersistenceContext
@@ -104,5 +106,8 @@
This pattern is often used in conjunction with an optimistic locking strategy to protect the integrity of data modified in parallel by multiple users.
This pattern stores much less flow state, but generally increases the amount of data access since persistent entities are fetched and flushed more often.
+
+ An implementation of this flow-managed persistence pattern is not yet available in the Web Flow distribution, and will be considered for future releases.
+
\ No newline at end of file
diff --git a/spring-webflow-reference/src/spring-mvc.xml b/spring-webflow-reference/src/spring-mvc.xml
index 75e31480..1952db87 100644
--- a/spring-webflow-reference/src/spring-mvc.xml
+++ b/spring-webflow-reference/src/spring-mvc.xml
@@ -181,6 +181,32 @@ public class BookingFlowHandler extends AbstractFlowHandler {
]]>
+
+ FlowHandler Redirects
+
+ A FlowHandler handling a FlowExecutionOutcome or FlowException returns a String to indicate the resource to redirect to after handling.
+ In the previous example, the BookingFlowHandler redirects to the booking/show resource URI for bookingConfirmed outcomes,
+ and the hotels/index resource URI for all other outcomes.
+
+
+ By default, returned resource locations are relative to the current servlet mapping.
+ This allows for a flow handler to redirect to other Controllers in the application using relative paths.
+ In addition, explicit redirect prefixes are supported for cases where more control is needed.
+
+
+ The explicit redirect prefixes supported are:
+
+
+ servletRelative: - redirect to a resource relative to the current servlet
+ contextRelative: - redirect to a resource relative to the current web application context path
+ serverRelative: - redirect to a resource relative to the server root
+ http:// or https:// - redirect to a fully-qualified resource URI
+
+
+ These same redirect prefixes are also supported within a flow definition when using the externalRedirect: directive in
+ conjunction with a view-state or end-state; for example, view="externalRedirect:http://springframework.org"
+
+
Flow Controller
diff --git a/spring-webflow-reference/src/views.xml b/spring-webflow-reference/src/views.xml
index 942f1236..62221b96 100644
--- a/spring-webflow-reference/src/views.xml
+++ b/spring-webflow-reference/src/views.xml
@@ -161,11 +161,6 @@
For a flow event to be generated that can drive a view state transition, model binding must complete successfully.
If model binding fails, the view is re-rendered to allow the user to revise their edits.
-
- The exact model binding and validation semantics are a function of the view technology in use.
- See the Spring MVC and Faces section for more information on MVC and JSF semantics, respectively.
- Regardless of the view technology used, your flow should not change.
-
Suppressing binding
diff --git a/spring-webflow-samples/booking-faces/src/main/webapp/WEB-INF/config/dispatcher-servlet-config.xml b/spring-webflow-samples/booking-faces/src/main/webapp/WEB-INF/config/dispatcher-servlet-config.xml
deleted file mode 100644
index 3da3506e..00000000
--- a/spring-webflow-samples/booking-faces/src/main/webapp/WEB-INF/config/dispatcher-servlet-config.xml
+++ /dev/null
@@ -1,10 +0,0 @@
-
-
-
-
-
-
\ No newline at end of file
diff --git a/spring-webflow-samples/booking-faces/src/main/webapp/WEB-INF/web.xml b/spring-webflow-samples/booking-faces/src/main/webapp/WEB-INF/web.xml
index dd5adc1e..7b6bcd6d 100755
--- a/spring-webflow-samples/booking-faces/src/main/webapp/WEB-INF/web.xml
+++ b/spring-webflow-samples/booking-faces/src/main/webapp/WEB-INF/web.xml
@@ -65,7 +65,7 @@
org.springframework.web.servlet.DispatcherServlet
contextConfigLocation
- /WEB-INF/config/dispatcher-servlet-config.xml
+
2
diff --git a/spring-webflow-samples/booking-mvc/src/main/webapp/WEB-INF/web.xml b/spring-webflow-samples/booking-mvc/src/main/webapp/WEB-INF/web.xml
index 11157af7..412b889d 100755
--- a/spring-webflow-samples/booking-mvc/src/main/webapp/WEB-INF/web.xml
+++ b/spring-webflow-samples/booking-mvc/src/main/webapp/WEB-INF/web.xml
@@ -47,7 +47,7 @@
org.springframework.web.servlet.DispatcherServlet
contextConfigLocation
- /WEB-INF/config/dispatcher-servlet-config.xml
+
1
diff --git a/spring-webflow/src/main/java/org/springframework/webflow/core/collection/LocalParameterMap.java b/spring-webflow/src/main/java/org/springframework/webflow/core/collection/LocalParameterMap.java
index ecb92511..326682bc 100644
--- a/spring-webflow/src/main/java/org/springframework/webflow/core/collection/LocalParameterMap.java
+++ b/spring-webflow/src/main/java/org/springframework/webflow/core/collection/LocalParameterMap.java
@@ -26,7 +26,7 @@ import java.util.List;
import java.util.Map;
import org.springframework.binding.collection.MapAccessor;
-import org.springframework.binding.convert.ConversionException;
+import org.springframework.binding.convert.ConversionExecutionException;
import org.springframework.binding.convert.ConversionExecutor;
import org.springframework.binding.convert.ConversionService;
import org.springframework.binding.convert.service.DefaultConversionService;
@@ -149,16 +149,16 @@ public class LocalParameterMap implements ParameterMap, Serializable {
}
}
- public Object[] getArray(String parameterName, Class targetElementType) throws ConversionException {
+ public Object[] getArray(String parameterName, Class targetElementType) throws ConversionExecutionException {
String[] parameters = getArray(parameterName);
return parameters != null ? convert(parameters, targetElementType) : null;
}
- public Object get(String parameterName, Class targetType) throws ConversionException {
+ public Object get(String parameterName, Class targetType) throws ConversionExecutionException {
return get(parameterName, targetType, null);
}
- public Object get(String parameterName, Class targetType, Object defaultValue) throws ConversionException {
+ public Object get(String parameterName, Class targetType, Object defaultValue) throws ConversionExecutionException {
if (defaultValue != null) {
assertAssignableTo(targetType, defaultValue.getClass());
}
@@ -177,65 +177,65 @@ public class LocalParameterMap implements ParameterMap, Serializable {
}
public Object[] getRequiredArray(String parameterName, Class targetElementType) throws IllegalArgumentException,
- ConversionException {
+ ConversionExecutionException {
String[] parameters = getRequiredArray(parameterName);
return convert(parameters, targetElementType);
}
public Object getRequired(String parameterName, Class targetType) throws IllegalArgumentException,
- ConversionException {
+ ConversionExecutionException {
return convert(getRequired(parameterName), targetType);
}
- public Number getNumber(String parameterName, Class targetType) throws ConversionException {
+ public Number getNumber(String parameterName, Class targetType) throws ConversionExecutionException {
assertAssignableTo(Number.class, targetType);
return (Number) get(parameterName, targetType);
}
- public Number getNumber(String parameterName, Class targetType, Number defaultValue) throws ConversionException {
+ public Number getNumber(String parameterName, Class targetType, Number defaultValue) throws ConversionExecutionException {
assertAssignableTo(Number.class, targetType);
return (Number) get(parameterName, targetType, defaultValue);
}
public Number getRequiredNumber(String parameterName, Class targetType) throws IllegalArgumentException,
- ConversionException {
+ ConversionExecutionException {
assertAssignableTo(Number.class, targetType);
return (Number) getRequired(parameterName, targetType);
}
- public Integer getInteger(String parameterName) throws ConversionException {
+ public Integer getInteger(String parameterName) throws ConversionExecutionException {
return (Integer) get(parameterName, Integer.class);
}
- public Integer getInteger(String parameterName, Integer defaultValue) throws ConversionException {
+ public Integer getInteger(String parameterName, Integer defaultValue) throws ConversionExecutionException {
return (Integer) get(parameterName, Integer.class, defaultValue);
}
- public Integer getRequiredInteger(String parameterName) throws IllegalArgumentException, ConversionException {
+ public Integer getRequiredInteger(String parameterName) throws IllegalArgumentException, ConversionExecutionException {
return (Integer) getRequired(parameterName, Integer.class);
}
- public Long getLong(String parameterName) throws ConversionException {
+ public Long getLong(String parameterName) throws ConversionExecutionException {
return (Long) get(parameterName, Long.class);
}
- public Long getLong(String parameterName, Long defaultValue) throws ConversionException {
+ public Long getLong(String parameterName, Long defaultValue) throws ConversionExecutionException {
return (Long) get(parameterName, Long.class, defaultValue);
}
- public Long getRequiredLong(String parameterName) throws IllegalArgumentException, ConversionException {
+ public Long getRequiredLong(String parameterName) throws IllegalArgumentException, ConversionExecutionException {
return (Long) getRequired(parameterName, Long.class);
}
- public Boolean getBoolean(String parameterName) throws ConversionException {
+ public Boolean getBoolean(String parameterName) throws ConversionExecutionException {
return (Boolean) get(parameterName, Boolean.class);
}
- public Boolean getBoolean(String parameterName, Boolean defaultValue) throws ConversionException {
+ public Boolean getBoolean(String parameterName, Boolean defaultValue) throws ConversionExecutionException {
return (Boolean) get(parameterName, Boolean.class, defaultValue);
}
- public Boolean getRequiredBoolean(String parameterName) throws IllegalArgumentException, ConversionException {
+ public Boolean getRequiredBoolean(String parameterName) throws IllegalArgumentException, ConversionExecutionException {
return (Boolean) getRequired(parameterName, Boolean.class);
}
@@ -272,14 +272,14 @@ public class LocalParameterMap implements ParameterMap, Serializable {
/**
* Convert given String parameter to specified target type.
*/
- private Object convert(String parameter, Class targetType) throws ConversionException {
+ private Object convert(String parameter, Class targetType) throws ConversionExecutionException {
return conversionService.getConversionExecutor(String.class, targetType).execute(parameter);
}
/**
* Convert given array of String parameters to specified target type and return the resulting array.
*/
- private Object[] convert(String[] parameters, Class targetElementType) throws ConversionException {
+ private Object[] convert(String[] parameters, Class targetElementType) throws ConversionExecutionException {
List list = new ArrayList(parameters.length);
ConversionExecutor converter = conversionService.getConversionExecutor(String.class, targetElementType);
for (int i = 0; i < parameters.length; i++) {
diff --git a/spring-webflow/src/main/java/org/springframework/webflow/core/collection/ParameterMap.java b/spring-webflow/src/main/java/org/springframework/webflow/core/collection/ParameterMap.java
index c051cd7d..675db489 100644
--- a/spring-webflow/src/main/java/org/springframework/webflow/core/collection/ParameterMap.java
+++ b/spring-webflow/src/main/java/org/springframework/webflow/core/collection/ParameterMap.java
@@ -16,7 +16,7 @@
package org.springframework.webflow.core.collection;
import org.springframework.binding.collection.MapAdaptable;
-import org.springframework.binding.convert.ConversionException;
+import org.springframework.binding.convert.ConversionExecutionException;
import org.springframework.web.multipart.MultipartFile;
/**
@@ -78,18 +78,18 @@ public interface ParameterMap extends MapAdaptable {
* @param parameterName the parameter name
* @param targetElementType the target type of the array's elements
* @return the converterd parameter value array
- * @throws ConversionException when the value could not be converted
+ * @throws ConversionExecutionException when the value could not be converted
*/
- public Object[] getArray(String parameterName, Class targetElementType) throws ConversionException;
+ public Object[] getArray(String parameterName, Class targetElementType) throws ConversionExecutionException;
/**
* Get a parameter value, converting it from String to the target type.
* @param parameterName the name of the parameter
* @param targetType the target type of the parameter value
* @return the converted parameter value, or null if not found
- * @throws ConversionException when the value could not be converted
+ * @throws ConversionExecutionException when the value could not be converted
*/
- public Object get(String parameterName, Class targetType) throws ConversionException;
+ public Object get(String parameterName, Class targetType) throws ConversionExecutionException;
/**
* Get a parameter value, converting it from String to the target type or returning the defaultValue
@@ -98,9 +98,9 @@ public interface ParameterMap extends MapAdaptable {
* @param targetType the target type of the parameter value
* @param defaultValue the default value
* @return the converted parameter value, or the default if not found
- * @throws ConversionException when a value could not be converted
+ * @throws ConversionExecutionException when a value could not be converted
*/
- public Object get(String parameterName, Class targetType, Object defaultValue) throws ConversionException;
+ public Object get(String parameterName, Class targetType, Object defaultValue) throws ConversionExecutionException;
/**
* Get the value of a required parameter.
@@ -123,10 +123,10 @@ public interface ParameterMap extends MapAdaptable {
* @param parameterName the name of the parameter
* @return the parameter value
* @throws IllegalArgumentException when the parameter is not found
- * @throws ConversionException when a value could not be converted
+ * @throws ConversionExecutionException when a value could not be converted
*/
public Object[] getRequiredArray(String parameterName, Class targetElementType) throws IllegalArgumentException,
- ConversionException;
+ ConversionExecutionException;
/**
* Get the value of a required parameter and convert it to the target type.
@@ -134,10 +134,10 @@ public interface ParameterMap extends MapAdaptable {
* @param targetType the target type of the parameter value
* @return the converted parameter value
* @throws IllegalArgumentException when the parameter is not found
- * @throws ConversionException when the value could not be converted
+ * @throws ConversionExecutionException when the value could not be converted
*/
public Object getRequired(String parameterName, Class targetType) throws IllegalArgumentException,
- ConversionException;
+ ConversionExecutionException;
/**
* Returns a number parameter value in the map that is of the specified type, returning null if no
@@ -145,9 +145,9 @@ public interface ParameterMap extends MapAdaptable {
* @param parameterName the parameter name
* @param targetType the target number type
* @return the number parameter value
- * @throws ConversionException when the value could not be converted
+ * @throws ConversionExecutionException when the value could not be converted
*/
- public Number getNumber(String parameterName, Class targetType) throws ConversionException;
+ public Number getNumber(String parameterName, Class targetType) throws ConversionExecutionException;
/**
* Returns a number parameter value in the map of the specified type, returning the defaultValue if no value was
@@ -155,9 +155,9 @@ public interface ParameterMap extends MapAdaptable {
* @param parameterName the parameter name
* @param defaultValue the default
* @return the number parameter value
- * @throws ConversionException when the value could not be converted
+ * @throws ConversionExecutionException when the value could not be converted
*/
- public Number getNumber(String parameterName, Class targetType, Number defaultValue) throws ConversionException;
+ public Number getNumber(String parameterName, Class targetType, Number defaultValue) throws ConversionExecutionException;
/**
* Returns a number parameter value in the map, throwing an exception if the parameter is not present or could not
@@ -165,27 +165,27 @@ public interface ParameterMap extends MapAdaptable {
* @param parameterName the parameter name
* @return the number parameter value
* @throws IllegalArgumentException if the parameter is not present
- * @throws ConversionException when the value could not be converted
+ * @throws ConversionExecutionException when the value could not be converted
*/
public Number getRequiredNumber(String parameterName, Class targetType) throws IllegalArgumentException,
- ConversionException;
+ ConversionExecutionException;
/**
* Returns an integer parameter value in the map, returning null if no value was found.
* @param parameterName the parameter name
* @return the integer parameter value
- * @throws ConversionException when the value could not be converted
+ * @throws ConversionExecutionException when the value could not be converted
*/
- public Integer getInteger(String parameterName) throws ConversionException;
+ public Integer getInteger(String parameterName) throws ConversionExecutionException;
/**
* Returns an integer parameter value in the map, returning the defaultValue if no value was found.
* @param parameterName the parameter name
* @param defaultValue the default
* @return the integer parameter value
- * @throws ConversionException when the value could not be converted
+ * @throws ConversionExecutionException when the value could not be converted
*/
- public Integer getInteger(String parameterName, Integer defaultValue) throws ConversionException;
+ public Integer getInteger(String parameterName, Integer defaultValue) throws ConversionExecutionException;
/**
* Returns an integer parameter value in the map, throwing an exception if the parameter is not present or could not
@@ -193,26 +193,26 @@ public interface ParameterMap extends MapAdaptable {
* @param parameterName the parameter name
* @return the integer parameter value
* @throws IllegalArgumentException if the parameter is not present
- * @throws ConversionException when the value could not be converted
+ * @throws ConversionExecutionException when the value could not be converted
*/
- public Integer getRequiredInteger(String parameterName) throws IllegalArgumentException, ConversionException;
+ public Integer getRequiredInteger(String parameterName) throws IllegalArgumentException, ConversionExecutionException;
/**
* Returns a long parameter value in the map, returning null if no value was found.
* @param parameterName the parameter name
* @return the long parameter value
- * @throws ConversionException when the value could not be converted
+ * @throws ConversionExecutionException when the value could not be converted
*/
- public Long getLong(String parameterName) throws ConversionException;
+ public Long getLong(String parameterName) throws ConversionExecutionException;
/**
* Returns a long parameter value in the map, returning the defaultValue if no value was found.
* @param parameterName the parameter name
* @param defaultValue the default
* @return the long parameter value
- * @throws ConversionException when the value could not be converted
+ * @throws ConversionExecutionException when the value could not be converted
*/
- public Long getLong(String parameterName, Long defaultValue) throws ConversionException;
+ public Long getLong(String parameterName, Long defaultValue) throws ConversionExecutionException;
/**
* Returns a long parameter value in the map, throwing an exception if the parameter is not present or could not be
@@ -220,26 +220,26 @@ public interface ParameterMap extends MapAdaptable {
* @param parameterName the parameter name
* @return the long parameter value
* @throws IllegalArgumentException if the parameter is not present
- * @throws ConversionException when the value could not be converted
+ * @throws ConversionExecutionException when the value could not be converted
*/
- public Long getRequiredLong(String parameterName) throws IllegalArgumentException, ConversionException;
+ public Long getRequiredLong(String parameterName) throws IllegalArgumentException, ConversionExecutionException;
/**
* Returns a boolean parameter value in the map, returning null if no value was found.
* @param parameterName the parameter name
* @return the long parameter value
- * @throws ConversionException when the value could not be converted
+ * @throws ConversionExecutionException when the value could not be converted
*/
- public Boolean getBoolean(String parameterName) throws ConversionException;
+ public Boolean getBoolean(String parameterName) throws ConversionExecutionException;
/**
* Returns a boolean parameter value in the map, returning the defaultValue if no value was found.
* @param parameterName the parameter name
* @param defaultValue the default
* @return the boolean parameter value
- * @throws ConversionException when the value could not be converted
+ * @throws ConversionExecutionException when the value could not be converted
*/
- public Boolean getBoolean(String parameterName, Boolean defaultValue) throws ConversionException;
+ public Boolean getBoolean(String parameterName, Boolean defaultValue) throws ConversionExecutionException;
/**
* Returns a boolean parameter value in the map, throwing an exception if the parameter is not present or could not
@@ -247,9 +247,9 @@ public interface ParameterMap extends MapAdaptable {
* @param parameterName the parameter name
* @return the boolean parameter value
* @throws IllegalArgumentException if the parameter is not present
- * @throws ConversionException when the value could not be converted
+ * @throws ConversionExecutionException when the value could not be converted
*/
- public Boolean getRequiredBoolean(String parameterName) throws IllegalArgumentException, ConversionException;
+ public Boolean getRequiredBoolean(String parameterName) throws IllegalArgumentException, ConversionExecutionException;
/**
* Get a multi-part file parameter value, returning null if no value is found.
diff --git a/spring-webflow/src/main/java/org/springframework/webflow/engine/builder/model/FlowModelFlowBuilder.java b/spring-webflow/src/main/java/org/springframework/webflow/engine/builder/model/FlowModelFlowBuilder.java
index 46bdda8e..3e5d25d7 100644
--- a/spring-webflow/src/main/java/org/springframework/webflow/engine/builder/model/FlowModelFlowBuilder.java
+++ b/spring-webflow/src/main/java/org/springframework/webflow/engine/builder/model/FlowModelFlowBuilder.java
@@ -24,7 +24,7 @@ import java.util.List;
import org.springframework.beans.factory.config.ConfigurableBeanFactory;
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
import org.springframework.beans.factory.xml.XmlBeanDefinitionReader;
-import org.springframework.binding.convert.ConversionException;
+import org.springframework.binding.convert.ConversionExecutionException;
import org.springframework.binding.convert.ConversionExecutor;
import org.springframework.binding.convert.service.RuntimeBindingConversionExecutor;
import org.springframework.binding.expression.EvaluationException;
@@ -905,7 +905,7 @@ public class FlowModelFlowBuilder extends AbstractFlowBuilder {
}
}
- private ConversionExecutor fromStringTo(Class targetType) throws ConversionException {
+ private ConversionExecutor fromStringTo(Class targetType) throws ConversionExecutionException {
return getLocalContext().getConversionService().getConversionExecutor(String.class, targetType);
}
diff --git a/spring-webflow/src/main/java/org/springframework/webflow/engine/builder/support/FlowBuilderContextImpl.java b/spring-webflow/src/main/java/org/springframework/webflow/engine/builder/support/FlowBuilderContextImpl.java
index b9e05078..a829315f 100644
--- a/spring-webflow/src/main/java/org/springframework/webflow/engine/builder/support/FlowBuilderContextImpl.java
+++ b/spring-webflow/src/main/java/org/springframework/webflow/engine/builder/support/FlowBuilderContextImpl.java
@@ -15,7 +15,7 @@
*/
package org.springframework.webflow.engine.builder.support;
-import org.springframework.binding.convert.ConversionException;
+import org.springframework.binding.convert.ConversionExecutionException;
import org.springframework.binding.convert.ConversionExecutor;
import org.springframework.binding.convert.ConversionService;
import org.springframework.binding.convert.service.GenericConversionService;
@@ -125,7 +125,7 @@ public class FlowBuilderContextImpl implements FlowBuilderContext {
*/
private class ParentConversionServiceProxy implements ConversionService {
public ConversionExecutor getConversionExecutor(Class sourceClass, Class targetClass)
- throws ConversionException {
+ throws ConversionExecutionException {
return getFlowBuilderServices().getConversionService().getConversionExecutor(sourceClass, targetClass);
}
}
diff --git a/spring-webflow/src/main/java/org/springframework/webflow/engine/builder/support/TextToTargetStateResolver.java b/spring-webflow/src/main/java/org/springframework/webflow/engine/builder/support/TextToTargetStateResolver.java
index 8901853f..4b0a1610 100644
--- a/spring-webflow/src/main/java/org/springframework/webflow/engine/builder/support/TextToTargetStateResolver.java
+++ b/spring-webflow/src/main/java/org/springframework/webflow/engine/builder/support/TextToTargetStateResolver.java
@@ -15,7 +15,7 @@
*/
package org.springframework.webflow.engine.builder.support;
-import org.springframework.binding.convert.converters.AbstractConverter;
+import org.springframework.binding.convert.Converter;
import org.springframework.binding.expression.Expression;
import org.springframework.binding.expression.ExpressionParser;
import org.springframework.binding.expression.support.FluentParserContext;
@@ -40,7 +40,7 @@ import org.springframework.webflow.execution.RequestContext;
* @author Keith Donald
* @author Erwin Vervaet
*/
-class TextToTargetStateResolver extends AbstractConverter {
+class TextToTargetStateResolver implements Converter {
/**
* Context for flow builder services.
@@ -63,7 +63,7 @@ class TextToTargetStateResolver extends AbstractConverter {
return new Class[] { TargetStateResolver.class };
}
- protected Object doConvert(Object source, Class targetClass, Object context) throws Exception {
+ public Object convert(Object source, Class targetClass, Object context) throws Exception {
String targetStateId = (String) source;
if (!StringUtils.hasText(targetStateId)) {
return null;
diff --git a/spring-webflow/src/main/java/org/springframework/webflow/engine/builder/support/TextToTransitionCriteria.java b/spring-webflow/src/main/java/org/springframework/webflow/engine/builder/support/TextToTransitionCriteria.java
index e0743738..96b1d0f2 100644
--- a/spring-webflow/src/main/java/org/springframework/webflow/engine/builder/support/TextToTransitionCriteria.java
+++ b/spring-webflow/src/main/java/org/springframework/webflow/engine/builder/support/TextToTransitionCriteria.java
@@ -15,8 +15,8 @@
*/
package org.springframework.webflow.engine.builder.support;
-import org.springframework.binding.convert.ConversionException;
-import org.springframework.binding.convert.converters.AbstractConverter;
+import org.springframework.binding.convert.ConversionExecutionException;
+import org.springframework.binding.convert.Converter;
import org.springframework.binding.expression.Expression;
import org.springframework.binding.expression.ExpressionParser;
import org.springframework.binding.expression.ExpressionVariable;
@@ -47,7 +47,7 @@ import org.springframework.webflow.execution.RequestContext;
* @author Keith Donald
* @author Erwin Vervaet
*/
-class TextToTransitionCriteria extends AbstractConverter {
+class TextToTransitionCriteria implements Converter {
/**
* Context for flow builder services.
@@ -70,7 +70,7 @@ class TextToTransitionCriteria extends AbstractConverter {
return new Class[] { TransitionCriteria.class };
}
- protected Object doConvert(Object source, Class targetClass, Object context) throws Exception {
+ public Object convert(Object source, Class targetClass, Object context) throws Exception {
String encodedCriteria = (String) source;
ExpressionParser parser = flowBuilderContext.getExpressionParser();
if (!StringUtils.hasText(encodedCriteria)
@@ -87,10 +87,10 @@ class TextToTransitionCriteria extends AbstractConverter {
* @param encodedCriteria the encoded transition criteria expression
* @param parser the parser that should parse the expression
* @return the transition criteria object
- * @throws ConversionException when something goes wrong
+ * @throws ConversionExecutionException when something goes wrong
*/
protected TransitionCriteria createBooleanExpressionTransitionCriteria(String encodedCriteria,
- ExpressionParser parser) throws ConversionException {
+ ExpressionParser parser) throws ConversionExecutionException {
Expression expression = parser.parseExpression(encodedCriteria, new FluentParserContext().template().evaluate(
RequestContext.class).variable(new ExpressionVariable("result", "lastEvent.id")));
return new DefaultTransitionCriteria(expression);
diff --git a/spring-webflow/src/main/java/org/springframework/webflow/expression/DefaultExpressionParserFactory.java b/spring-webflow/src/main/java/org/springframework/webflow/expression/DefaultExpressionParserFactory.java
index d7b2c7d0..a66f44b4 100644
--- a/spring-webflow/src/main/java/org/springframework/webflow/expression/DefaultExpressionParserFactory.java
+++ b/spring-webflow/src/main/java/org/springframework/webflow/expression/DefaultExpressionParserFactory.java
@@ -17,6 +17,8 @@ package org.springframework.webflow.expression;
import javax.el.ExpressionFactory;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
import org.springframework.binding.expression.Expression;
import org.springframework.binding.expression.ExpressionParser;
import org.springframework.binding.expression.ParserContext;
@@ -42,6 +44,8 @@ import org.springframework.webflow.expression.el.WebFlowELExpressionParser;
*/
public final class DefaultExpressionParserFactory {
+ private static final Log logger = LogFactory.getLog(DefaultExpressionParserFactory.class);
+
/**
* The singleton instance of the default expression parser.
*/
@@ -73,6 +77,9 @@ public final class DefaultExpressionParserFactory {
private static synchronized ExpressionParser getDefaultExpressionParser() {
if (INSTANCE == null) {
INSTANCE = createDefaultExpressionParser();
+ if (logger.isDebugEnabled()) {
+ logger.debug("Initialized default Web Flow ExpressionParser " + INSTANCE);
+ }
}
return INSTANCE;
}
diff --git a/spring-webflow/src/main/java/org/springframework/webflow/mvc/view/AbstractMvcView.java b/spring-webflow/src/main/java/org/springframework/webflow/mvc/view/AbstractMvcView.java
index 9408894d..a751caeb 100644
--- a/spring-webflow/src/main/java/org/springframework/webflow/mvc/view/AbstractMvcView.java
+++ b/spring-webflow/src/main/java/org/springframework/webflow/mvc/view/AbstractMvcView.java
@@ -23,7 +23,7 @@ import java.util.List;
import java.util.Map;
import org.springframework.beans.factory.BeanFactory;
-import org.springframework.binding.convert.ConversionException;
+import org.springframework.binding.convert.ConversionExecutionException;
import org.springframework.binding.convert.ConversionExecutor;
import org.springframework.binding.expression.EvaluationException;
import org.springframework.binding.expression.Expression;
@@ -356,11 +356,11 @@ public abstract class AbstractMvcView implements View {
this.formatterRegistry = formatterRegistry;
}
- public Object execute(Object source) throws ConversionException {
+ public Object execute(Object source) throws ConversionExecutionException {
throw new UnsupportedOperationException("Should never be called");
}
- public Object execute(Object source, Object context) throws ConversionException {
+ public Object execute(Object source, Object context) throws ConversionExecutionException {
String formattedValue = (String) source;
DefaultMappingContext mappingContext = (DefaultMappingContext) context;
Expression target = mappingContext.getCurrentMapping().getTargetExpression();
@@ -380,7 +380,7 @@ public abstract class AbstractMvcView implements View {
try {
return formatter.parse(formattedValue);
} catch (InvalidFormatException e) {
- throw new ConversionException(String.class, targetClass, e);
+ throw new ConversionExecutionException(formattedValue, String.class, targetClass, e);
}
} else {
return formattedValue;
diff --git a/spring-webflow/src/test/java/org/springframework/webflow/config/FlowBuilderServicesBeanDefinitionParserTests.java b/spring-webflow/src/test/java/org/springframework/webflow/config/FlowBuilderServicesBeanDefinitionParserTests.java
index cebb811e..3f8c81dc 100644
--- a/spring-webflow/src/test/java/org/springframework/webflow/config/FlowBuilderServicesBeanDefinitionParserTests.java
+++ b/spring-webflow/src/test/java/org/springframework/webflow/config/FlowBuilderServicesBeanDefinitionParserTests.java
@@ -2,7 +2,7 @@ package org.springframework.webflow.config;
import junit.framework.TestCase;
-import org.springframework.binding.convert.ConversionException;
+import org.springframework.binding.convert.ConversionExecutionException;
import org.springframework.binding.convert.ConversionExecutor;
import org.springframework.binding.convert.ConversionService;
import org.springframework.binding.convert.service.DefaultConversionService;
@@ -57,21 +57,21 @@ public class FlowBuilderServicesBeanDefinitionParserTests extends TestCase {
public static class TestConversionService implements ConversionService {
- public Class getClassByAlias(String alias) throws ConversionException {
+ public Class getClassByAlias(String alias) throws ConversionExecutionException {
throw new UnsupportedOperationException("Auto-generated method stub");
}
public ConversionExecutor getConversionExecutor(Class sourceClass, Class targetClass)
- throws ConversionException {
+ throws ConversionExecutionException {
throw new UnsupportedOperationException("Auto-generated method stub");
}
public ConversionExecutor getConversionExecutorByTargetAlias(Class sourceClass, String targetAlias)
- throws ConversionException {
+ throws ConversionExecutionException {
throw new UnsupportedOperationException("Auto-generated method stub");
}
- public ConversionExecutor[] getConversionExecutorsForSource(Class sourceClass) throws ConversionException {
+ public ConversionExecutor[] getConversionExecutorsForSource(Class sourceClass) throws ConversionExecutionException {
throw new UnsupportedOperationException("Auto-generated method stub");
}
diff --git a/spring-webflow/src/test/java/org/springframework/webflow/engine/builder/support/TextToTargetStateResolverTests.java b/spring-webflow/src/test/java/org/springframework/webflow/engine/builder/support/TextToTargetStateResolverTests.java
index f3c01ccd..af2fcf98 100644
--- a/spring-webflow/src/test/java/org/springframework/webflow/engine/builder/support/TextToTargetStateResolverTests.java
+++ b/spring-webflow/src/test/java/org/springframework/webflow/engine/builder/support/TextToTargetStateResolverTests.java
@@ -30,33 +30,36 @@ public class TextToTargetStateResolverTests extends TestCase {
public void setUp() {
}
- public void testStatic() {
+ public void testStatic() throws Exception {
String expression = "mockState";
- TargetStateResolver resolver = (TargetStateResolver) converter.convert(expression);
+ TargetStateResolver resolver = (TargetStateResolver) converter.convert(expression, TargetStateResolver.class,
+ null);
MockRequestContext context = new MockRequestContext();
Transition transition = new Transition();
assertEquals("mockState", resolver.resolveTargetState(transition, null, context).getId());
}
- public void testDynamic() {
+ public void testDynamic() throws Exception {
String expression = "${flowScope.lastState}";
- TargetStateResolver resolver = (TargetStateResolver) converter.convert(expression);
+ TargetStateResolver resolver = (TargetStateResolver) converter.convert(expression, TargetStateResolver.class,
+ null);
MockRequestContext context = new MockRequestContext();
context.getFlowScope().put("lastState", "mockState");
Transition transition = new Transition();
assertEquals("mockState", resolver.resolveTargetState(transition, null, context).getId());
}
- public void testNull() {
+ public void testNull() throws Exception {
String expression = null;
- TargetStateResolver resolver = (TargetStateResolver) converter.convert(expression);
+ TargetStateResolver resolver = (TargetStateResolver) converter.convert(expression, TargetStateResolver.class,
+ null);
assertNull(resolver);
}
- public void testEmpty() {
+ public void testEmpty() throws Exception {
String expression = "";
- TargetStateResolver resolver = (TargetStateResolver) converter.convert(expression);
+ TargetStateResolver resolver = (TargetStateResolver) converter.convert(expression, TargetStateResolver.class,
+ null);
assertNull(resolver);
}
-
}
\ No newline at end of file
diff --git a/spring-webflow/src/test/java/org/springframework/webflow/engine/builder/support/TextToTransitionCriteriaTests.java b/spring-webflow/src/test/java/org/springframework/webflow/engine/builder/support/TextToTransitionCriteriaTests.java
index 950a2fa4..1e31029b 100644
--- a/spring-webflow/src/test/java/org/springframework/webflow/engine/builder/support/TextToTransitionCriteriaTests.java
+++ b/spring-webflow/src/test/java/org/springframework/webflow/engine/builder/support/TextToTransitionCriteriaTests.java
@@ -39,40 +39,45 @@ public class TextToTransitionCriteriaTests extends TestCase {
public void setUp() {
}
- public void testAny() {
+ public void testAny() throws Exception {
String expression = "*";
- TransitionCriteria criterion = (TransitionCriteria) converter.convert(expression);
+ TransitionCriteria criterion = (TransitionCriteria) converter.convert(expression, TransitionCriteria.class,
+ null);
RequestContext ctx = getRequestContext();
assertTrue("Criterion should evaluate to true", criterion.test(ctx));
- assertSame(WildcardTransitionCriteria.INSTANCE, converter.convert("*"));
- assertSame(WildcardTransitionCriteria.INSTANCE, converter.convert(""));
- assertSame(WildcardTransitionCriteria.INSTANCE, converter.convert(null));
+ assertSame(WildcardTransitionCriteria.INSTANCE, converter.convert("*", TransitionCriteria.class, null));
+ assertSame(WildcardTransitionCriteria.INSTANCE, converter.convert("", TransitionCriteria.class, null));
+ assertSame(WildcardTransitionCriteria.INSTANCE, converter.convert(null, TransitionCriteria.class, null));
}
- public void testStaticEventId() {
+ public void testStaticEventId() throws Exception {
String expression = "sample";
- TransitionCriteria criterion = (TransitionCriteria) converter.convert(expression);
+ TransitionCriteria criterion = (TransitionCriteria) converter.convert(expression, TransitionCriteria.class,
+ null);
RequestContext ctx = getRequestContext();
assertTrue("Criterion should evaluate to true", criterion.test(ctx));
}
public void testTrueEvaluation() throws Exception {
String expression = "${flowScope.foo == 'bar'}";
- TransitionCriteria criterion = (TransitionCriteria) converter.convert(expression);
+ TransitionCriteria criterion = (TransitionCriteria) converter.convert(expression, TransitionCriteria.class,
+ null);
RequestContext ctx = getRequestContext();
assertTrue("Criterion should evaluate to true", criterion.test(ctx));
}
public void testFalseEvaluation() throws Exception {
String expression = "${flowScope.foo != 'bar'}";
- TransitionCriteria criterion = (TransitionCriteria) converter.convert(expression);
+ TransitionCriteria criterion = (TransitionCriteria) converter.convert(expression, TransitionCriteria.class,
+ null);
RequestContext ctx = getRequestContext();
assertFalse("Criterion should evaluate to false", criterion.test(ctx));
}
public void testNonStringEvaluation() throws Exception {
String expression = "${3 + 4}";
- TransitionCriteria criterion = (TransitionCriteria) converter.convert(expression);
+ TransitionCriteria criterion = (TransitionCriteria) converter.convert(expression, TransitionCriteria.class,
+ null);
MockRequestContext ctx = getRequestContext();
ctx.setCurrentEvent(new Event(this, "7"));
assertTrue("Criterion should evaluate to true", criterion.test(ctx));
@@ -84,7 +89,8 @@ public class TextToTransitionCriteriaTests extends TestCase {
return new StaticExpression(null);
}
});
- TransitionCriteria criterion = (TransitionCriteria) converter.convert("doesnt matter");
+ TransitionCriteria criterion = (TransitionCriteria) converter.convert("doesnt matter",
+ TransitionCriteria.class, null);
RequestContext ctx = getRequestContext();
assertFalse("Criterion should evaluate to false", criterion.test(ctx));
}