fixes for known 2.0.0 bugs reported since release - see changelog
This commit is contained in:
@@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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() + "'";
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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;
|
||||
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
|
||||
}
|
||||
@@ -50,8 +50,8 @@ public interface Converter {
|
||||
* <code>targetClasses</code>
|
||||
* @param context an optional conversion context that may be used to influence the conversion process
|
||||
* @return the converted object, an instance of the target type
|
||||
* @throws ConversionException an exception 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;
|
||||
|
||||
}
|
||||
@@ -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
|
||||
* <code>targetClasses</code>
|
||||
* @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;
|
||||
|
||||
}
|
||||
@@ -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;
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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() + "'");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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";
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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) {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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(""));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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(""));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -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(""));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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();
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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");
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -85,13 +85,15 @@
|
||||
<sect1 id="conversationScopedPersistenceContext">
|
||||
<title>ConversationScoped PersistenceContext</title>
|
||||
<para>
|
||||
This pattern creates a <code>PersistenceContext</code> in <code>conversationScope</code> on flow startup,
|
||||
and uses that context for data access until the conversation ends.
|
||||
This pattern creates a <code>PersistenceContext</code> in <code>conversationScope</code> 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.
|
||||
</para>
|
||||
<para>
|
||||
An implementation of this flow-managed persistence pattern is not yet available in the Web Flow distribution, and will be considered for future releases.
|
||||
</para>
|
||||
</sect1>
|
||||
<sect1 id="viewScopedPersistenceContext">
|
||||
<title>ViewState PersistenceContext</title>
|
||||
@@ -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.
|
||||
</para>
|
||||
<para>
|
||||
An implementation of this flow-managed persistence pattern is not yet available in the Web Flow distribution, and will be considered for future releases.
|
||||
</para>
|
||||
</sect1>
|
||||
</chapter>
|
||||
@@ -181,6 +181,32 @@ public class BookingFlowHandler extends AbstractFlowHandler {
|
||||
]]>
|
||||
</programlisting>
|
||||
</sect2>
|
||||
<sect2 id="spring-mvc-flow-handler-redirects">
|
||||
<title>FlowHandler Redirects</title>
|
||||
<para>
|
||||
A FlowHandler handling a FlowExecutionOutcome or FlowException returns a <code>String</code> to indicate the resource to redirect to after handling.
|
||||
In the previous example, the <code>BookingFlowHandler</code> redirects to the <code>booking/show</code> resource URI for <code>bookingConfirmed</code> outcomes,
|
||||
and the <code>hotels/index</code> resource URI for all other outcomes.
|
||||
</para>
|
||||
<para>
|
||||
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.
|
||||
</para>
|
||||
<para>
|
||||
The explicit redirect prefixes supported are:
|
||||
</para>
|
||||
<itemizedlist>
|
||||
<listitem><para><code>servletRelative:</code> - redirect to a resource relative to the current servlet</para></listitem>
|
||||
<listitem><para><code>contextRelative:</code> - redirect to a resource relative to the current web application context path</para></listitem>
|
||||
<listitem><para><code>serverRelative:</code> - redirect to a resource relative to the server root</para></listitem>
|
||||
<listitem><para><code>http://</code> or <code>https://</code> - redirect to a fully-qualified resource URI</para></listitem>
|
||||
</itemizedlist>
|
||||
<para>
|
||||
These same redirect prefixes are also supported within a flow definition when using the <code>externalRedirect:</code> directive in
|
||||
conjunction with a view-state or end-state; for example, <code>view="externalRedirect:http://springframework.org"</code>
|
||||
</para>
|
||||
</sect2>
|
||||
</sect1>
|
||||
<sect1 id="spring-mvc-config-spring-flow-controllers">
|
||||
<title>Flow Controller</title>
|
||||
|
||||
@@ -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.
|
||||
</para>
|
||||
<para>
|
||||
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.
|
||||
</para>
|
||||
</sect1>
|
||||
<sect1 id="view-bind">
|
||||
<title>Suppressing binding</title>
|
||||
|
||||
@@ -1,10 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<beans xmlns="http://www.springframework.org/schema/beans"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="
|
||||
http://www.springframework.org/schema/beans
|
||||
http://www.springframework.org/schema/beans/spring-beans-2.5.xsd">
|
||||
|
||||
<!-- No special configuration needed here - all configuration is driven by web-application-config.xml -->
|
||||
|
||||
</beans>
|
||||
@@ -65,7 +65,7 @@
|
||||
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
|
||||
<init-param>
|
||||
<param-name>contextConfigLocation</param-name>
|
||||
<param-value>/WEB-INF/config/dispatcher-servlet-config.xml</param-value>
|
||||
<param-value></param-value>
|
||||
</init-param>
|
||||
<load-on-startup>2</load-on-startup>
|
||||
</servlet>
|
||||
|
||||
@@ -47,7 +47,7 @@
|
||||
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
|
||||
<init-param>
|
||||
<param-name>contextConfigLocation</param-name>
|
||||
<param-value>/WEB-INF/config/dispatcher-servlet-config.xml</param-value>
|
||||
<param-value></param-value>
|
||||
</init-param>
|
||||
<load-on-startup>1</load-on-startup>
|
||||
</servlet>
|
||||
|
||||
@@ -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++) {
|
||||
|
||||
@@ -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 <code>String</code> 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 <code>String</code> 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 <code>null</code> 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 <code>null</code> 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 <code>null</code> 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 <code>null</code> 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 <code>null</code> if no value is found.
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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");
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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));
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user