diff --git a/spring-binding/src/main/java/org/springframework/binding/convert/ConversionExecutor.java b/spring-binding/src/main/java/org/springframework/binding/convert/ConversionExecutor.java index ea83458e..b5093e05 100644 --- a/spring-binding/src/main/java/org/springframework/binding/convert/ConversionExecutor.java +++ b/spring-binding/src/main/java/org/springframework/binding/convert/ConversionExecutor.java @@ -47,6 +47,6 @@ public interface ConversionExecutor { * @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, ConversionContext context) throws ConversionException; + public Object execute(Object source, Object context) throws ConversionException; } \ No newline at end of file diff --git a/spring-binding/src/main/java/org/springframework/binding/convert/Converter.java b/spring-binding/src/main/java/org/springframework/binding/convert/Converter.java index 9d95a123..72d08b8f 100644 --- a/spring-binding/src/main/java/org/springframework/binding/convert/Converter.java +++ b/spring-binding/src/main/java/org/springframework/binding/convert/Converter.java @@ -52,6 +52,6 @@ public interface Converter { * @return the converted object, an instance of the target type * @throws ConversionException an exception occurred during the type conversion */ - public Object convert(Object source, Class targetClass, ConversionContext context) throws ConversionException; + public Object convert(Object source, Class targetClass, Object context) throws ConversionException; } \ No newline at end of file diff --git a/spring-binding/src/main/java/org/springframework/binding/convert/support/AbstractConverter.java b/spring-binding/src/main/java/org/springframework/binding/convert/support/AbstractConverter.java index 974845a2..d7e3abc5 100644 --- a/spring-binding/src/main/java/org/springframework/binding/convert/support/AbstractConverter.java +++ b/spring-binding/src/main/java/org/springframework/binding/convert/support/AbstractConverter.java @@ -15,7 +15,6 @@ */ package org.springframework.binding.convert.support; -import org.springframework.binding.convert.ConversionContext; import org.springframework.binding.convert.ConversionException; import org.springframework.binding.convert.Converter; @@ -58,11 +57,11 @@ public abstract class AbstractConverter implements Converter { * @return the converted object * @throws ConversionException an exception occured converting the source value */ - public Object convert(Object source, ConversionContext context) throws ConversionException { + public Object convert(Object source, Object context) throws ConversionException { return convert(source, getTargetClasses()[0], context); } - public Object convert(Object source, Class targetClass, ConversionContext context) throws ConversionException { + public Object convert(Object source, Class targetClass, Object context) throws ConversionException { try { return doConvert(source, targetClass, context); } catch (ConversionException e) { @@ -82,8 +81,8 @@ public abstract class AbstractConverter implements Converter { * @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 occured, will be wrapped in a conversion exception if necessary + * @throws Exception an exception occurred, will be wrapped in a conversion exception if necessary */ - protected abstract Object doConvert(Object source, Class targetClass, ConversionContext context) throws Exception; + protected abstract Object doConvert(Object source, Class targetClass, Object context) throws Exception; } \ No newline at end of file diff --git a/spring-binding/src/main/java/org/springframework/binding/convert/support/AbstractFormattingConverter.java b/spring-binding/src/main/java/org/springframework/binding/convert/support/AbstractFormattingConverter.java index 700a5e0c..ded7cc18 100644 --- a/spring-binding/src/main/java/org/springframework/binding/convert/support/AbstractFormattingConverter.java +++ b/spring-binding/src/main/java/org/springframework/binding/convert/support/AbstractFormattingConverter.java @@ -15,7 +15,6 @@ */ package org.springframework.binding.convert.support; -import org.springframework.binding.convert.ConversionContext; import org.springframework.binding.format.FormatterRegistry; import org.springframework.util.Assert; @@ -45,7 +44,7 @@ public abstract class AbstractFormattingConverter extends AbstractConverter { return formatterRegistry; } - protected Object doConvert(Object source, Class targetClass, ConversionContext context) throws Exception { + protected Object doConvert(Object source, Class targetClass, Object context) throws Exception { return getFormatterRegistry().getFormatter(targetClass).parseValue((String) source); } } \ No newline at end of file diff --git a/spring-binding/src/main/java/org/springframework/binding/convert/support/ConversionExecutorImpl.java b/spring-binding/src/main/java/org/springframework/binding/convert/support/ConversionExecutorImpl.java index 898b8efd..4ee2c36e 100644 --- a/spring-binding/src/main/java/org/springframework/binding/convert/support/ConversionExecutorImpl.java +++ b/spring-binding/src/main/java/org/springframework/binding/convert/support/ConversionExecutorImpl.java @@ -15,7 +15,6 @@ */ package org.springframework.binding.convert.support; -import org.springframework.binding.convert.ConversionContext; import org.springframework.binding.convert.ConversionException; import org.springframework.binding.convert.ConversionExecutor; import org.springframework.binding.convert.Converter; @@ -91,7 +90,7 @@ class ConversionExecutorImpl implements ConversionExecutor { return execute(source, null); } - public Object execute(Object source, ConversionContext context) throws ConversionException { + public Object execute(Object source, Object context) throws ConversionException { if (targetClass.isInstance(source)) { // source is already assignment compatible with target class return source; diff --git a/spring-binding/src/main/java/org/springframework/binding/convert/support/FormatterBackedConversionExecutor.java b/spring-binding/src/main/java/org/springframework/binding/convert/support/FormatterBackedConversionExecutor.java deleted file mode 100644 index e109213f..00000000 --- a/spring-binding/src/main/java/org/springframework/binding/convert/support/FormatterBackedConversionExecutor.java +++ /dev/null @@ -1,35 +0,0 @@ -package org.springframework.binding.convert.support; - -import org.springframework.binding.convert.ConversionContext; -import org.springframework.binding.convert.ConversionException; -import org.springframework.binding.convert.ConversionExecutor; -import org.springframework.binding.format.Formatter; - -public class FormatterBackedConversionExecutor implements ConversionExecutor { - - private Formatter formatter; - - private Class targetClass; - - public FormatterBackedConversionExecutor(Formatter formatter, Class targetClass) { - this.formatter = formatter; - this.targetClass = targetClass; - } - - public Object execute(Object source) throws ConversionException { - return execute(source, null); - } - - public Object execute(Object source, ConversionContext context) throws ConversionException { - return formatter.parseValue((String) source); - } - - public Class getSourceClass() { - return String.class; - } - - public Class getTargetClass() { - return targetClass; - } - -} diff --git a/spring-binding/src/main/java/org/springframework/binding/convert/support/NoOpConverter.java b/spring-binding/src/main/java/org/springframework/binding/convert/support/NoOpConverter.java index 4222fa7b..180718ee 100644 --- a/spring-binding/src/main/java/org/springframework/binding/convert/support/NoOpConverter.java +++ b/spring-binding/src/main/java/org/springframework/binding/convert/support/NoOpConverter.java @@ -15,7 +15,6 @@ */ package org.springframework.binding.convert.support; -import org.springframework.binding.convert.ConversionContext; /** * Package private converter that is a "no op". @@ -36,7 +35,7 @@ class NoOpConverter extends AbstractConverter { this.targetClass = targetClass; } - protected Object doConvert(Object source, Class targetClass, ConversionContext context) throws Exception { + protected Object doConvert(Object source, Class targetClass, Object context) throws Exception { return source; } diff --git a/spring-binding/src/main/java/org/springframework/binding/convert/support/RuntimeBindingConversionExecutor.java b/spring-binding/src/main/java/org/springframework/binding/convert/support/RuntimeBindingConversionExecutor.java index a0ae9ed0..dee3cf14 100644 --- a/spring-binding/src/main/java/org/springframework/binding/convert/support/RuntimeBindingConversionExecutor.java +++ b/spring-binding/src/main/java/org/springframework/binding/convert/support/RuntimeBindingConversionExecutor.java @@ -1,6 +1,5 @@ package org.springframework.binding.convert.support; -import org.springframework.binding.convert.ConversionContext; import org.springframework.binding.convert.ConversionException; import org.springframework.binding.convert.ConversionExecutor; import org.springframework.binding.convert.ConversionService; @@ -52,7 +51,7 @@ public class RuntimeBindingConversionExecutor implements ConversionExecutor { return execute(source, null); } - public Object execute(Object source, ConversionContext context) throws ConversionException { + public Object execute(Object source, Object context) throws ConversionException { return conversionService.getConversionExecutor(source.getClass(), targetClass).execute(source); } diff --git a/spring-binding/src/main/java/org/springframework/binding/convert/support/TextToBoolean.java b/spring-binding/src/main/java/org/springframework/binding/convert/support/TextToBoolean.java index 459cd1e1..b3a3961e 100644 --- a/spring-binding/src/main/java/org/springframework/binding/convert/support/TextToBoolean.java +++ b/spring-binding/src/main/java/org/springframework/binding/convert/support/TextToBoolean.java @@ -15,7 +15,6 @@ */ package org.springframework.binding.convert.support; -import org.springframework.binding.convert.ConversionContext; import org.springframework.util.StringUtils; /** @@ -71,7 +70,7 @@ public class TextToBoolean extends AbstractConverter { return new Class[] { Boolean.class }; } - protected Object doConvert(Object source, Class targetClass, ConversionContext context) throws Exception { + protected Object doConvert(Object source, Class targetClass, Object context) throws Exception { String text = (String) source; if (!StringUtils.hasText(text)) { return null; diff --git a/spring-binding/src/main/java/org/springframework/binding/convert/support/TextToClass.java b/spring-binding/src/main/java/org/springframework/binding/convert/support/TextToClass.java index 5ca3641b..3e806dab 100644 --- a/spring-binding/src/main/java/org/springframework/binding/convert/support/TextToClass.java +++ b/spring-binding/src/main/java/org/springframework/binding/convert/support/TextToClass.java @@ -20,7 +20,6 @@ import java.math.BigInteger; import java.util.HashMap; import java.util.Map; -import org.springframework.binding.convert.ConversionContext; import org.springframework.core.enums.LabeledEnum; import org.springframework.util.ClassUtils; import org.springframework.util.StringUtils; @@ -53,7 +52,7 @@ public class TextToClass extends AbstractConverter { return new Class[] { Class.class }; } - protected Object doConvert(Object source, Class targetClass, ConversionContext context) throws Exception { + protected Object doConvert(Object source, Class targetClass, Object context) throws Exception { String text = (String) source; if (StringUtils.hasText(text)) { text = text.trim(); diff --git a/spring-binding/src/main/java/org/springframework/binding/convert/support/TextToLabeledEnum.java b/spring-binding/src/main/java/org/springframework/binding/convert/support/TextToLabeledEnum.java index 8a844505..441690a0 100644 --- a/spring-binding/src/main/java/org/springframework/binding/convert/support/TextToLabeledEnum.java +++ b/spring-binding/src/main/java/org/springframework/binding/convert/support/TextToLabeledEnum.java @@ -15,7 +15,6 @@ */ package org.springframework.binding.convert.support; -import org.springframework.binding.convert.ConversionContext; import org.springframework.core.enums.LabeledEnum; import org.springframework.core.enums.LabeledEnumResolver; import org.springframework.core.enums.StaticLabeledEnumResolver; @@ -37,7 +36,7 @@ public class TextToLabeledEnum extends AbstractConverter { return new Class[] { LabeledEnum.class }; } - protected Object doConvert(Object source, Class targetClass, ConversionContext context) throws Exception { + protected Object doConvert(Object source, Class targetClass, Object context) throws Exception { String label = (String) source; return labeledEnumResolver.getLabeledEnumByLabel(targetClass, label); } diff --git a/spring-binding/src/main/java/org/springframework/binding/expression/support/StaticExpression.java b/spring-binding/src/main/java/org/springframework/binding/expression/support/StaticExpression.java index 7cbd8073..2dc1dc86 100644 --- a/spring-binding/src/main/java/org/springframework/binding/expression/support/StaticExpression.java +++ b/spring-binding/src/main/java/org/springframework/binding/expression/support/StaticExpression.java @@ -26,11 +26,10 @@ import org.springframework.util.ObjectUtils; */ public final class StaticExpression implements Expression { - /** - * The value expression. - */ private Object value; + private String expressionString; + /** * Create a static evaluator for the given value. * @param value the value @@ -64,11 +63,19 @@ public final class StaticExpression implements Expression { } public Class getValueType(Object context) { - return Object.class; + return value.getClass(); } public String getExpressionString() { - return null; + return expressionString; + } + + /** + * Sets the static expression string. + * @param expressionString the static expression string + */ + public void setExpressionString(String expressionString) { + this.expressionString = expressionString; } public String toString() { diff --git a/spring-binding/src/main/java/org/springframework/binding/mapping/impl/DefaultMapping.java b/spring-binding/src/main/java/org/springframework/binding/mapping/impl/DefaultMapping.java index 69dafd1f..8eaa2d1f 100644 --- a/spring-binding/src/main/java/org/springframework/binding/mapping/impl/DefaultMapping.java +++ b/spring-binding/src/main/java/org/springframework/binding/mapping/impl/DefaultMapping.java @@ -23,6 +23,7 @@ import org.springframework.binding.convert.ConversionService; import org.springframework.binding.expression.EvaluationException; import org.springframework.binding.expression.Expression; import org.springframework.binding.mapping.Mapping; +import org.springframework.core.style.StylerUtils; import org.springframework.util.Assert; /** @@ -128,7 +129,7 @@ public class DefaultMapping implements Mapping { if (sourceValue != null) { if (typeConverter != null) { try { - targetValue = typeConverter.execute(targetValue); + targetValue = typeConverter.execute(targetValue, context); } catch (ConversionException e) { context.setTypeConversionErrorResult(sourceValue, e.getTargetClass()); return; @@ -147,7 +148,7 @@ public class DefaultMapping implements Mapping { try { ConversionExecutor typeConverter = conversionService.getConversionExecutor(sourceValue .getClass(), targetType); - targetValue = typeConverter.execute(sourceValue); + targetValue = typeConverter.execute(sourceValue, context); } catch (ConversionException e) { context.setTypeConversionErrorResult(sourceValue, e.getTargetClass()); return; @@ -156,12 +157,15 @@ public class DefaultMapping implements Mapping { } } } - if (logger.isDebugEnabled()) { - logger.debug("Mapping '" + sourceExpression + "' value [" + sourceValue + "] to target '" - + targetExpression + "'; setting target value to [" + targetValue + "]"); - } try { targetExpression.setValue(context.getTarget(), targetValue); + if (logger.isDebugEnabled()) { + String sourceType = sourceValue != null ? sourceValue.getClass().getName() : "null"; + String targetType = targetValue != null ? targetValue.getClass().getName() : "null"; + logger.debug("Mapped source [" + sourceType + "] " + sourceExpression + " value " + + StylerUtils.style(sourceValue) + " to target [" + targetType + "] " + targetExpression + + " value " + StylerUtils.style(targetValue)); + } context.setSuccessResult(sourceValue, targetValue); } catch (EvaluationException e) { context.setTargetAccessError(sourceValue, e); @@ -191,4 +195,5 @@ public class DefaultMapping implements Mapping { public String toString() { return sourceExpression + " -> " + targetExpression; } + } \ No newline at end of file diff --git a/spring-binding/src/main/java/org/springframework/binding/mapping/impl/DefaultMappingContext.java b/spring-binding/src/main/java/org/springframework/binding/mapping/impl/DefaultMappingContext.java index 4510d5ef..3636e0ad 100644 --- a/spring-binding/src/main/java/org/springframework/binding/mapping/impl/DefaultMappingContext.java +++ b/spring-binding/src/main/java/org/springframework/binding/mapping/impl/DefaultMappingContext.java @@ -49,6 +49,10 @@ class DefaultMappingContext implements MappingContext { return conversionService; } + public Mapping getCurrentMapping() { + return currentMapping; + } + public void setCurrentMapping(Mapping mapping) { if (this.currentMapping != null) { throw new IllegalStateException("The current mapping has not finished yet"); diff --git a/spring-binding/src/main/java/org/springframework/binding/mapping/impl/MappingContext.java b/spring-binding/src/main/java/org/springframework/binding/mapping/impl/MappingContext.java index 0d0f0b5e..0b6614a5 100644 --- a/spring-binding/src/main/java/org/springframework/binding/mapping/impl/MappingContext.java +++ b/spring-binding/src/main/java/org/springframework/binding/mapping/impl/MappingContext.java @@ -42,6 +42,12 @@ public interface MappingContext { */ public ConversionService getConversionService(); + /** + * Returns the current mapping. + * @return the current mapping + */ + public Mapping getCurrentMapping(); + /** * Sets the current mapping. Called when a single mapping operation is about to begin. This updates progress of the * overall mapping transaction. diff --git a/spring-binding/src/test/java/org/springframework/binding/convert/support/ConversionExecutorImplTests.java b/spring-binding/src/test/java/org/springframework/binding/convert/support/ConversionExecutorImplTests.java index 23d57b95..86e73cfe 100644 --- a/spring-binding/src/test/java/org/springframework/binding/convert/support/ConversionExecutorImplTests.java +++ b/spring-binding/src/test/java/org/springframework/binding/convert/support/ConversionExecutorImplTests.java @@ -19,7 +19,6 @@ import java.util.Date; import junit.framework.TestCase; -import org.springframework.binding.convert.ConversionContext; import org.springframework.binding.convert.ConversionException; /** @@ -65,7 +64,7 @@ public class ConversionExecutorImplTests extends TestCase { return new Class[] { Date.class }; } - protected Object doConvert(Object source, Class targetClass, ConversionContext context) throws Exception { + protected Object doConvert(Object source, Class targetClass, Object context) throws Exception { return source == null ? null : new Date(); } } diff --git a/spring-faces/src/main/java/org/springframework/faces/model/converter/DataModelConverter.java b/spring-faces/src/main/java/org/springframework/faces/model/converter/DataModelConverter.java index c94c7f08..bd31b23d 100644 --- a/spring-faces/src/main/java/org/springframework/faces/model/converter/DataModelConverter.java +++ b/spring-faces/src/main/java/org/springframework/faces/model/converter/DataModelConverter.java @@ -20,13 +20,12 @@ import java.util.List; import javax.faces.model.DataModel; -import org.springframework.binding.convert.ConversionContext; import org.springframework.binding.convert.support.AbstractConverter; import org.springframework.util.ClassUtils; public class DataModelConverter extends AbstractConverter { - protected Object doConvert(Object source, Class targetClass, ConversionContext context) throws Exception { + 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); diff --git a/spring-webflow/.classpath b/spring-webflow/.classpath index 82423b83..53fd089a 100644 --- a/spring-webflow/.classpath +++ b/spring-webflow/.classpath @@ -1,7 +1,7 @@ - - + + diff --git a/spring-webflow/src/main/java/org/springframework/webflow/definition/Annotated.java b/spring-webflow/src/main/java/org/springframework/webflow/definition/Annotated.java index dcb74f1c..0e6f139e 100644 --- a/spring-webflow/src/main/java/org/springframework/webflow/definition/Annotated.java +++ b/spring-webflow/src/main/java/org/springframework/webflow/definition/Annotated.java @@ -15,7 +15,7 @@ */ package org.springframework.webflow.definition; -import org.springframework.webflow.core.collection.AttributeMap; +import org.springframework.webflow.core.collection.MutableAttributeMap; /** * An interface to be implemented by objects that are annotated with attributes they wish to expose to clients. @@ -38,10 +38,10 @@ public interface Annotated { public String getDescription(); /** - * Returns an immutable attribute map containing the attributes annotating this object. These attributes provide - * descriptive characteristics or properties that may affect object behavior. + * Returns a attribute map containing the attributes annotating this object. These attributes provide descriptive + * characteristics or properties that may affect object behavior. * @return the attribute map */ - public AttributeMap getAttributes(); + public MutableAttributeMap getAttributes(); } \ No newline at end of file diff --git a/spring-webflow/src/main/java/org/springframework/webflow/engine/AnnotatedAction.java b/spring-webflow/src/main/java/org/springframework/webflow/engine/AnnotatedAction.java index df15acd4..c67d3575 100644 --- a/spring-webflow/src/main/java/org/springframework/webflow/engine/AnnotatedAction.java +++ b/spring-webflow/src/main/java/org/springframework/webflow/engine/AnnotatedAction.java @@ -92,7 +92,7 @@ public class AnnotatedAction extends AnnotatedObject implements Action { * @see #postProcessResult(Event) */ public String getName() { - return getAttributeMap().getString(NAME_ATTRIBUTE); + return getAttributes().getString(NAME_ATTRIBUTE); } /** @@ -100,7 +100,7 @@ public class AnnotatedAction extends AnnotatedObject implements Action { * @param name the action name */ public void setName(String name) { - getAttributeMap().put(NAME_ATTRIBUTE, name); + getAttributes().put(NAME_ATTRIBUTE, name); } /** @@ -116,7 +116,7 @@ public class AnnotatedAction extends AnnotatedObject implements Action { * Returns the name of the action method to invoke when the target action is executed. */ public String getMethod() { - return getAttributeMap().getString(METHOD_ATTRIBUTE); + return getAttributes().getString(METHOD_ATTRIBUTE); } /** @@ -124,7 +124,7 @@ public class AnnotatedAction extends AnnotatedObject implements Action { * @param method the action method name */ public void setMethod(String method) { - getAttributeMap().put(METHOD_ATTRIBUTE, method); + getAttributes().put(METHOD_ATTRIBUTE, method); } /** @@ -132,17 +132,16 @@ public class AnnotatedAction extends AnnotatedObject implements Action { * @param attributeName the name of the attribute to set * @param attributeValue the value of the attribute * @return this object, to support call chaining - * @since 1.0.4 */ public AnnotatedAction putAttribute(String attributeName, Object attributeValue) { - getAttributeMap().put(attributeName, attributeValue); + getAttributes().put(attributeName, attributeValue); return this; } public Event execute(RequestContext context) throws Exception { - AttributeMap originalAttributes = getAttributeMap(); + AttributeMap originalAttributes = getAttributes(); try { - context.setAttributes(getAttributeMap()); + context.setAttributes(getAttributes()); Event result = getTargetAction().execute(context); return postProcessResult(result); } finally { @@ -171,7 +170,7 @@ public class AnnotatedAction extends AnnotatedObject implements Action { } public String toString() { - return new ToStringCreator(this).append("targetAction", getTargetAction()).append("attributes", - getAttributeMap()).toString(); + return new ToStringCreator(this).append("targetAction", getTargetAction()) + .append("attributes", getAttributes()).toString(); } } \ No newline at end of file diff --git a/spring-webflow/src/main/java/org/springframework/webflow/engine/AnnotatedObject.java b/spring-webflow/src/main/java/org/springframework/webflow/engine/AnnotatedObject.java index 2ecde296..b19e9ad2 100644 --- a/spring-webflow/src/main/java/org/springframework/webflow/engine/AnnotatedObject.java +++ b/spring-webflow/src/main/java/org/springframework/webflow/engine/AnnotatedObject.java @@ -15,7 +15,6 @@ */ package org.springframework.webflow.engine; -import org.springframework.webflow.core.collection.AttributeMap; import org.springframework.webflow.core.collection.LocalAttributeMap; import org.springframework.webflow.core.collection.MutableAttributeMap; import org.springframework.webflow.definition.Annotated; @@ -56,7 +55,7 @@ public abstract class AnnotatedObject implements Annotated { return attributes.getString(DESCRIPTION_PROPERTY); } - public AttributeMap getAttributes() { + public MutableAttributeMap getAttributes() { return attributes; } @@ -78,10 +77,4 @@ public abstract class AnnotatedObject implements Annotated { attributes.put(DESCRIPTION_PROPERTY, description); } - /** - * Returns the mutable attribute map for this annotated object. May be used to set attributes after construction. - */ - public MutableAttributeMap getAttributeMap() { - return attributes; - } } \ No newline at end of file diff --git a/spring-webflow/src/main/java/org/springframework/webflow/engine/Flow.java b/spring-webflow/src/main/java/org/springframework/webflow/engine/Flow.java index 6d4aa7d7..0d011184 100644 --- a/spring-webflow/src/main/java/org/springframework/webflow/engine/Flow.java +++ b/spring-webflow/src/main/java/org/springframework/webflow/engine/Flow.java @@ -196,7 +196,7 @@ public class Flow extends AnnotatedObject implements FlowDefinition { */ public static Flow create(String id, AttributeMap attributes) { Flow flow = new Flow(id); - flow.getAttributeMap().putAll(attributes); + flow.getAttributes().putAll(attributes); return flow; } diff --git a/spring-webflow/src/main/java/org/springframework/webflow/engine/builder/FlowArtifactFactory.java b/spring-webflow/src/main/java/org/springframework/webflow/engine/builder/FlowArtifactFactory.java index b5d738a9..5b28218e 100644 --- a/spring-webflow/src/main/java/org/springframework/webflow/engine/builder/FlowArtifactFactory.java +++ b/spring-webflow/src/main/java/org/springframework/webflow/engine/builder/FlowArtifactFactory.java @@ -211,7 +211,7 @@ public class FlowArtifactFactory { if (executionCriteria != null) { transition.setExecutionCriteria(executionCriteria); } - transition.getAttributeMap().putAll(attributes); + transition.getAttributes().putAll(attributes); return transition; } @@ -234,6 +234,6 @@ public class FlowArtifactFactory { FlowExecutionExceptionHandler[] exceptionHandlers, AttributeMap attributes) { state.getEntryActionList().addAll(entryActions); state.getExceptionHandlerSet().addAll(exceptionHandlers); - state.getAttributeMap().putAll(attributes); + state.getAttributes().putAll(attributes); } } \ No newline at end of file diff --git a/spring-webflow/src/main/java/org/springframework/webflow/engine/builder/support/TextToTargetStateResolver.java b/spring-webflow/src/main/java/org/springframework/webflow/engine/builder/support/TextToTargetStateResolver.java index b84ccaff..713d3afd 100644 --- a/spring-webflow/src/main/java/org/springframework/webflow/engine/builder/support/TextToTargetStateResolver.java +++ b/spring-webflow/src/main/java/org/springframework/webflow/engine/builder/support/TextToTargetStateResolver.java @@ -15,7 +15,6 @@ */ package org.springframework.webflow.engine.builder.support; -import org.springframework.binding.convert.ConversionContext; import org.springframework.binding.convert.support.AbstractConverter; import org.springframework.binding.expression.Expression; import org.springframework.binding.expression.ExpressionParser; @@ -64,7 +63,7 @@ class TextToTargetStateResolver extends AbstractConverter { return new Class[] { TargetStateResolver.class }; } - protected Object doConvert(Object source, Class targetClass, ConversionContext context) throws Exception { + protected Object doConvert(Object source, Class targetClass, Object context) throws Exception { String targetStateId = (String) source; if (!StringUtils.hasText(targetStateId)) { return null; diff --git a/spring-webflow/src/main/java/org/springframework/webflow/engine/builder/support/TextToTransitionCriteria.java b/spring-webflow/src/main/java/org/springframework/webflow/engine/builder/support/TextToTransitionCriteria.java index 7ab425ac..76dfe477 100644 --- a/spring-webflow/src/main/java/org/springframework/webflow/engine/builder/support/TextToTransitionCriteria.java +++ b/spring-webflow/src/main/java/org/springframework/webflow/engine/builder/support/TextToTransitionCriteria.java @@ -15,7 +15,6 @@ */ package org.springframework.webflow.engine.builder.support; -import org.springframework.binding.convert.ConversionContext; import org.springframework.binding.convert.ConversionException; import org.springframework.binding.convert.support.AbstractConverter; import org.springframework.binding.expression.Expression; @@ -71,7 +70,7 @@ class TextToTransitionCriteria extends AbstractConverter { return new Class[] { TransitionCriteria.class }; } - protected Object doConvert(Object source, Class targetClass, ConversionContext context) throws Exception { + protected Object doConvert(Object source, Class targetClass, Object context) throws Exception { String encodedCriteria = (String) source; ExpressionParser parser = flowBuilderContext.getExpressionParser(); if (!StringUtils.hasText(encodedCriteria) diff --git a/spring-webflow/src/main/java/org/springframework/webflow/mvc/view/MvcView.java b/spring-webflow/src/main/java/org/springframework/webflow/mvc/view/MvcView.java index 726e8866..dbdedbf8 100644 --- a/spring-webflow/src/main/java/org/springframework/webflow/mvc/view/MvcView.java +++ b/spring-webflow/src/main/java/org/springframework/webflow/mvc/view/MvcView.java @@ -24,7 +24,9 @@ import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.springframework.binding.collection.MapAdaptable; -import org.springframework.binding.convert.support.FormatterBackedConversionExecutor; +import org.springframework.binding.convert.ConversionException; +import org.springframework.binding.convert.ConversionExecutor; +import org.springframework.binding.expression.EvaluationException; import org.springframework.binding.expression.Expression; import org.springframework.binding.expression.ExpressionParser; import org.springframework.binding.expression.support.ParserContextImpl; @@ -38,6 +40,7 @@ import org.springframework.binding.mapping.MappingResults; import org.springframework.binding.mapping.MappingResultsCriteria; import org.springframework.binding.mapping.impl.DefaultMapper; import org.springframework.binding.mapping.impl.DefaultMapping; +import org.springframework.binding.mapping.impl.MappingContext; import org.springframework.binding.mapping.results.TargetAccessError; import org.springframework.validation.BindingResult; import org.springframework.webflow.core.collection.ParameterMap; @@ -62,7 +65,7 @@ class MvcView implements View { private MappingResults mappingResults; - private boolean postbackSuccess; + private boolean viewErrors; private String eventId; @@ -101,30 +104,29 @@ class MvcView implements View { public void resume() { determineEventId(context); if (eventId == null) { + // nothing to do return; } Object model = getModelObject(); if (model == null) { - postbackSuccess = true; return; } if (shouldBind(model)) { mappingResults = bind(model); - if (!mappingResults.hasErrorResults()) { - postbackSuccess = true; - } else { - if (onlyPropertyNotFoundErrorsPresent(mappingResults)) { - postbackSuccess = true; - } + if (mappingResults.hasErrorResults() && !onlyPropertyNotFoundErrorsPresent(mappingResults)) { + viewErrors = true; } } } public boolean eventSignaled() { - return postbackSuccess && eventId != null; + return eventId != null && !viewErrors; } public Event getEvent() { + if (!eventSignaled()) { + return null; + } return new Event(this, eventId, context.getRequestParameters().asAttributeMap()); } @@ -146,7 +148,7 @@ class MvcView implements View { BindingModel bindingModel = new BindingModel(modelObject, expressionParser, formatterRegistry, context .getMessageContext()); bindingModel.setMappingResults(mappingResults); - model.put(BindingResult.MODEL_KEY_PREFIX + getModelExpression().getExpressionString(), model); + model.put(BindingResult.MODEL_KEY_PREFIX + getModelExpression().getExpressionString(), bindingModel); } } @@ -171,7 +173,7 @@ class MvcView implements View { return transition.getAttributes().getBoolean("bind").booleanValue(); } } - return false; + return true; } private MappingResults bind(Object model) { @@ -187,9 +189,7 @@ class MvcView implements View { .parseExpression(name, new ParserContextImpl().eval(MapAdaptable.class)); Expression target = expressionParser.parseExpression(name, new ParserContextImpl().eval(model.getClass())); DefaultMapping mapping = new DefaultMapping(source, target); - Class targetClass = target.getValueType(model); - Formatter formatter = formatterRegistry.getFormatter(target.getExpressionString(), targetClass); - mapping.setTypeConverter(new FormatterBackedConversionExecutor(formatter, targetClass)); + mapping.setTypeConverter(new FormatterBackedMappingConversionExecutor(formatterRegistry)); mapper.addMapping(mapping); } } @@ -252,4 +252,49 @@ class MvcView implements View { } } + private static class FormatterBackedMappingConversionExecutor implements ConversionExecutor { + + private FormatterRegistry formatterRegistry; + + public FormatterBackedMappingConversionExecutor(FormatterRegistry formatterRegistry) { + this.formatterRegistry = formatterRegistry; + } + + public Object execute(Object source) throws ConversionException { + throw new UnsupportedOperationException("Should never be called"); + } + + public Object execute(Object source, Object context) throws ConversionException { + String formattedValue = (String) source; + MappingContext mappingContext = (MappingContext) context; + Expression target = mappingContext.getCurrentMapping().getTargetExpression(); + Class targetClass = getTargetClass(); + if (targetClass == null) { + try { + targetClass = target.getValueType(mappingContext.getTarget()); + } catch (EvaluationException e) { + // ignore + } + } + if (targetClass == null) { + return formattedValue; + } + Formatter formatter = formatterRegistry.getFormatter(target.getExpressionString(), targetClass); + if (formatter != null) { + return formatter.parseValue(formattedValue); + } else { + return formattedValue; + } + } + + public Class getSourceClass() { + return String.class; + } + + public Class getTargetClass() { + return null; + } + + } + } \ No newline at end of file diff --git a/spring-webflow/src/main/java/org/springframework/webflow/test/MockExternalContext.java b/spring-webflow/src/main/java/org/springframework/webflow/test/MockExternalContext.java index 68365ccd..30a5d56d 100644 --- a/spring-webflow/src/main/java/org/springframework/webflow/test/MockExternalContext.java +++ b/spring-webflow/src/main/java/org/springframework/webflow/test/MockExternalContext.java @@ -21,8 +21,6 @@ import java.security.Principal; import java.util.HashMap; import org.springframework.binding.collection.SharedMapDecorator; -import org.springframework.security.context.SecurityContextHolder; -import org.springframework.util.ClassUtils; import org.springframework.webflow.context.ExternalContext; import org.springframework.webflow.core.collection.AttributeMap; import org.springframework.webflow.core.collection.LocalAttributeMap; @@ -56,6 +54,8 @@ public class MockExternalContext implements ExternalContext { private Object nativeResponse = new Object(); + private Principal currentUser; + private StringWriter responseWriter = new StringWriter(); private boolean ajaxRequest; @@ -114,10 +114,7 @@ public class MockExternalContext implements ExternalContext { } public Principal getCurrentUser() { - if (ClassUtils.isPresent("org.springframework.security.context.SecurityContextHolder")) - return SecurityContextHolder.getContext().getAuthentication(); - else - return null; + return currentUser; } public Object getNativeContext() { @@ -238,6 +235,14 @@ public class MockExternalContext implements ExternalContext { this.nativeResponse = nativeResponse; } + /** + * Sets the current user principal as a string. + * @param currentUser the current user name + */ + public void setCurrentUser(String currentUser) { + this.currentUser = new MockPrincipal(currentUser); + } + // convenience helpers /** @@ -342,4 +347,17 @@ public class MockExternalContext implements ExternalContext { return redirectInPopup; } + private class MockPrincipal implements Principal { + private String name; + + private MockPrincipal(String name) { + this.name = name; + } + + public String getName() { + return name; + } + + } + } \ No newline at end of file diff --git a/spring-webflow/src/main/java/org/springframework/webflow/test/MockFlowSession.java b/spring-webflow/src/main/java/org/springframework/webflow/test/MockFlowSession.java index eefc3eef..cba37efd 100644 --- a/spring-webflow/src/main/java/org/springframework/webflow/test/MockFlowSession.java +++ b/spring-webflow/src/main/java/org/springframework/webflow/test/MockFlowSession.java @@ -23,6 +23,7 @@ import org.springframework.webflow.definition.StateDefinition; import org.springframework.webflow.engine.Flow; import org.springframework.webflow.engine.RequestControlContext; import org.springframework.webflow.engine.State; +import org.springframework.webflow.engine.TransitionableState; import org.springframework.webflow.execution.FlowExecutionException; import org.springframework.webflow.execution.FlowSession; @@ -50,7 +51,7 @@ public class MockFlowSession implements FlowSession { */ public MockFlowSession() { setDefinition(new Flow("mockFlow")); - State state = new State(definition, "mockState") { + State state = new TransitionableState(definition, "mockState") { protected void doEnter(RequestControlContext context) throws FlowExecutionException { // nothing to do } diff --git a/spring-webflow/src/test/java/org/springframework/webflow/definition/registry/FlowDefinitionRegistryImplTests.java b/spring-webflow/src/test/java/org/springframework/webflow/definition/registry/FlowDefinitionRegistryImplTests.java index 199bd6e5..d36b6743 100644 --- a/spring-webflow/src/test/java/org/springframework/webflow/definition/registry/FlowDefinitionRegistryImplTests.java +++ b/spring-webflow/src/test/java/org/springframework/webflow/definition/registry/FlowDefinitionRegistryImplTests.java @@ -19,7 +19,7 @@ import junit.framework.TestCase; import org.springframework.beans.factory.BeanFactory; import org.springframework.core.io.ResourceLoader; -import org.springframework.webflow.core.collection.AttributeMap; +import org.springframework.webflow.core.collection.MutableAttributeMap; import org.springframework.webflow.definition.FlowDefinition; import org.springframework.webflow.definition.StateDefinition; @@ -80,7 +80,7 @@ public class FlowDefinitionRegistryImplTests extends TestCase { private static class FooFlow implements FlowDefinition { private String id = "foo"; - public AttributeMap getAttributes() { + public MutableAttributeMap getAttributes() { return null; } @@ -118,7 +118,7 @@ public class FlowDefinitionRegistryImplTests extends TestCase { private static class BarFlow implements FlowDefinition { private String id = "bar"; - public AttributeMap getAttributes() { + public MutableAttributeMap getAttributes() { return null; } diff --git a/spring-webflow/src/test/java/org/springframework/webflow/engine/AnnotatedObjectTests.java b/spring-webflow/src/test/java/org/springframework/webflow/engine/AnnotatedObjectTests.java index 46b940f0..908e8306 100644 --- a/spring-webflow/src/test/java/org/springframework/webflow/engine/AnnotatedObjectTests.java +++ b/spring-webflow/src/test/java/org/springframework/webflow/engine/AnnotatedObjectTests.java @@ -32,8 +32,8 @@ public class AnnotatedObjectTests extends TestCase { } public void testPutCustomAttributes() { - object.getAttributeMap().put("foo", "bar"); - assertEquals("bar", object.getAttributeMap().get("foo")); + object.getAttributes().put("foo", "bar"); + assertEquals("bar", object.getAttributes().get("foo")); } } diff --git a/spring-webflow/src/test/java/org/springframework/webflow/engine/AnnotedActionTests.java b/spring-webflow/src/test/java/org/springframework/webflow/engine/AnnotedActionTests.java index a50b814c..335d4f7f 100644 --- a/spring-webflow/src/test/java/org/springframework/webflow/engine/AnnotedActionTests.java +++ b/spring-webflow/src/test/java/org/springframework/webflow/engine/AnnotedActionTests.java @@ -39,7 +39,7 @@ public class AnnotedActionTests extends TestCase { } public void testExecuteWithCustomAttribute() throws Exception { - action.getAttributeMap().put("attr", "value"); + action.getAttributes().put("attr", "value"); action.setTargetAction(new AbstractAction() { protected Event doExecute(RequestContext context) throws Exception { assertEquals("value", context.getAttributes().getString("attr")); @@ -50,7 +50,7 @@ public class AnnotedActionTests extends TestCase { } public void testExecuteWithName() throws Exception { - action.getAttributeMap().put("name", "foo"); + action.getAttributes().put("name", "foo"); action.setTargetAction(new AbstractAction() { protected Event doExecute(RequestContext context) throws Exception { assertEquals("foo", context.getAttributes().getString("name")); diff --git a/spring-webflow/src/test/java/org/springframework/webflow/expression/WebFlowOgnlExpressionParserTests.java b/spring-webflow/src/test/java/org/springframework/webflow/expression/WebFlowOgnlExpressionParserTests.java index ce396f58..be82e226 100644 --- a/spring-webflow/src/test/java/org/springframework/webflow/expression/WebFlowOgnlExpressionParserTests.java +++ b/spring-webflow/src/test/java/org/springframework/webflow/expression/WebFlowOgnlExpressionParserTests.java @@ -1,14 +1,12 @@ package org.springframework.webflow.expression; +import java.security.Principal; + import junit.framework.TestCase; import org.springframework.beans.factory.support.StaticListableBeanFactory; import org.springframework.binding.expression.Expression; import org.springframework.binding.expression.support.ParserContextImpl; -import org.springframework.security.Authentication; -import org.springframework.security.context.SecurityContextHolder; -import org.springframework.security.context.SecurityContextImpl; -import org.springframework.security.providers.TestingAuthenticationToken; import org.springframework.webflow.TestBean; import org.springframework.webflow.action.FormAction; import org.springframework.webflow.core.collection.AttributeMap; @@ -50,13 +48,10 @@ public class WebFlowOgnlExpressionParserTests extends TestCase { } public void testResolveCurrentUser() { - SecurityContextImpl security = new SecurityContextImpl(); - Authentication auth = new TestingAuthenticationToken("user", "password", null); - security.setAuthentication(auth); - SecurityContextHolder.setContext(security); MockRequestContext context = new MockRequestContext(); + context.getMockExternalContext().setCurrentUser("Keith"); Expression exp = parser.parseExpression("currentUser", new ParserContextImpl().eval(RequestContext.class)); - assertSame(auth, exp.getValue(context)); + assertEquals("Keith", ((Principal) exp.getValue(context)).getName()); } public void testResolveRequestScope() { diff --git a/spring-webflow/src/test/java/org/springframework/webflow/expression/el/WebFlowELExpressionParserTests.java b/spring-webflow/src/test/java/org/springframework/webflow/expression/el/WebFlowELExpressionParserTests.java index 58b700e6..1fbb9635 100644 --- a/spring-webflow/src/test/java/org/springframework/webflow/expression/el/WebFlowELExpressionParserTests.java +++ b/spring-webflow/src/test/java/org/springframework/webflow/expression/el/WebFlowELExpressionParserTests.java @@ -1,15 +1,13 @@ package org.springframework.webflow.expression.el; +import java.security.Principal; + import junit.framework.TestCase; import org.springframework.beans.factory.support.StaticListableBeanFactory; import org.springframework.binding.expression.Expression; import org.springframework.binding.expression.el.DefaultExpressionFactoryUtils; import org.springframework.binding.expression.support.ParserContextImpl; -import org.springframework.security.Authentication; -import org.springframework.security.context.SecurityContextHolder; -import org.springframework.security.context.SecurityContextImpl; -import org.springframework.security.providers.TestingAuthenticationToken; import org.springframework.webflow.TestBean; import org.springframework.webflow.action.FormAction; import org.springframework.webflow.core.collection.AttributeMap; @@ -52,13 +50,10 @@ public class WebFlowELExpressionParserTests extends TestCase { } public void testResolveCurrentUser() { - SecurityContextImpl security = new SecurityContextImpl(); - Authentication auth = new TestingAuthenticationToken("user", "password", null); - security.setAuthentication(auth); - SecurityContextHolder.setContext(security); MockRequestContext context = new MockRequestContext(); + context.getMockExternalContext().setCurrentUser("Keith"); Expression exp = parser.parseExpression("currentUser", new ParserContextImpl().eval(RequestContext.class)); - assertSame(auth, exp.getValue(context)); + assertEquals("Keith", ((Principal) exp.getValue(context)).getName()); } public void testResolveRequestScope() { diff --git a/spring-webflow/src/test/java/org/springframework/webflow/mvc/MvcViewFactoryTests.java b/spring-webflow/src/test/java/org/springframework/webflow/mvc/view/MvcViewFactoryTests.java similarity index 99% rename from spring-webflow/src/test/java/org/springframework/webflow/mvc/MvcViewFactoryTests.java rename to spring-webflow/src/test/java/org/springframework/webflow/mvc/view/MvcViewFactoryTests.java index b49fa10f..487830a8 100644 --- a/spring-webflow/src/test/java/org/springframework/webflow/mvc/MvcViewFactoryTests.java +++ b/spring-webflow/src/test/java/org/springframework/webflow/mvc/view/MvcViewFactoryTests.java @@ -1,4 +1,4 @@ -package org.springframework.webflow.mvc; +package org.springframework.webflow.mvc.view; import java.io.IOException; import java.io.InputStream; diff --git a/spring-webflow/src/test/java/org/springframework/webflow/mvc/view/MvcViewTests.java b/spring-webflow/src/test/java/org/springframework/webflow/mvc/view/MvcViewTests.java new file mode 100644 index 00000000..2c27a591 --- /dev/null +++ b/spring-webflow/src/test/java/org/springframework/webflow/mvc/view/MvcViewTests.java @@ -0,0 +1,183 @@ +package org.springframework.webflow.mvc.view; + +import java.security.Principal; +import java.util.Calendar; +import java.util.Date; +import java.util.Map; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import junit.framework.TestCase; + +import org.springframework.binding.expression.support.StaticExpression; +import org.springframework.mock.web.MockHttpServletRequest; +import org.springframework.mock.web.MockHttpServletResponse; +import org.springframework.mock.web.MockServletContext; +import org.springframework.validation.BindingResult; +import org.springframework.web.servlet.View; +import org.springframework.webflow.test.MockFlowExecutionKey; +import org.springframework.webflow.test.MockRequestContext; + +public class MvcViewTests extends TestCase { + + private boolean renderCalled; + + private Map model; + + public void testRender() throws Exception { + MockRequestContext context = new MockRequestContext(); + context.getRequestScope().put("foo", "bar"); + context.getFlowScope().put("bar", "baz"); + context.getFlowScope().put("bindBean", new BindBean()); + context.getConversationScope().put("baz", "boop"); + context.getFlashScope().put("boop", "bing"); + context.getMockExternalContext().setCurrentUser("Keith"); + context.getMockExternalContext().setNativeContext(new MockServletContext()); + context.getMockExternalContext().setNativeRequest(new MockHttpServletRequest()); + context.getMockExternalContext().setNativeResponse(new MockHttpServletResponse()); + context.getMockFlowExecutionContext().setKey(new MockFlowExecutionKey("c1v1")); + org.springframework.web.servlet.View mvcView = new MockView(); + MvcView view = new MvcView(mvcView, context); + view.render(); + assertTrue(renderCalled); + assertEquals("bar", model.get("foo")); + assertEquals("baz", model.get("bar")); + assertEquals("boop", model.get("baz")); + assertEquals("bing", model.get("boop")); + assertEquals("c1v1", model.get("flowExecutionKey")); + assertEquals("Keith", ((Principal) model.get("currentUser")).getName()); + assertEquals(context, model.get("flowRequestContext")); + assertEquals("/mockFlow?execution=c1v1", model.get("flowExecutionUrl")); + assertNull(model.get(BindingResult.MODEL_KEY_PREFIX + "bindBean")); + } + + public void testRenderWithBindingModel() throws Exception { + MockRequestContext context = new MockRequestContext(); + Object bindBean = new BindBean(); + StaticExpression modelObject = new StaticExpression(bindBean); + modelObject.setExpressionString("bindBean"); + context.getCurrentState().getAttributes().put("model", modelObject); + context.getFlowScope().put("bindBean", bindBean); + context.getMockExternalContext().setNativeContext(new MockServletContext()); + context.getMockExternalContext().setNativeRequest(new MockHttpServletRequest()); + context.getMockExternalContext().setNativeResponse(new MockHttpServletResponse()); + context.getMockFlowExecutionContext().setKey(new MockFlowExecutionKey("c1v1")); + org.springframework.web.servlet.View mvcView = new MockView(); + MvcView view = new MvcView(mvcView, context); + view.render(); + assertEquals(context.getFlowScope().get("bindBean"), model.get("bindBean")); + BindingModel bm = (BindingModel) model.get(BindingResult.MODEL_KEY_PREFIX + "bindBean"); + assertNotNull(bm); + assertEquals(null, bm.getFieldValue("stringProperty")); + assertEquals("3", bm.getFieldValue("integerProperty")); + assertEquals("1/1/08", bm.getFieldValue("dateProperty")); + } + + public void testResumeNoEvent() throws Exception { + MockRequestContext context = new MockRequestContext(); + context.getMockExternalContext().setNativeContext(new MockServletContext()); + context.getMockExternalContext().setNativeRequest(new MockHttpServletRequest()); + context.getMockExternalContext().setNativeResponse(new MockHttpServletResponse()); + context.getMockFlowExecutionContext().setKey(new MockFlowExecutionKey("c1v1")); + org.springframework.web.servlet.View mvcView = new MockView(); + MvcView view = new MvcView(mvcView, context); + view.resume(); + assertFalse(view.eventSignaled()); + assertNull(view.getEvent()); + } + + public void testResumeEventNoModelBinding() throws Exception { + MockRequestContext context = new MockRequestContext(); + context.putRequestParameter("_eventId", "submit"); + context.getMockExternalContext().setNativeContext(new MockServletContext()); + context.getMockExternalContext().setNativeRequest(new MockHttpServletRequest()); + context.getMockExternalContext().setNativeResponse(new MockHttpServletResponse()); + context.getMockFlowExecutionContext().setKey(new MockFlowExecutionKey("c1v1")); + org.springframework.web.servlet.View mvcView = new MockView(); + MvcView view = new MvcView(mvcView, context); + view.resume(); + assertTrue(view.eventSignaled()); + assertEquals("submit", view.getEvent().getId()); + } + + public void testResumeEventModelBinding() throws Exception { + MockRequestContext context = new MockRequestContext(); + context.putRequestParameter("_eventId", "submit"); + context.putRequestParameter("stringProperty", "foo"); + context.putRequestParameter("integerProperty", "5"); + context.putRequestParameter("dateProperty", "1/1/07"); + BindBean bindBean = new BindBean(); + StaticExpression modelObject = new StaticExpression(bindBean); + modelObject.setExpressionString("bindBean"); + context.getCurrentState().getAttributes().put("model", modelObject); + context.getFlowScope().put("bindBean", bindBean); + context.getMockExternalContext().setNativeContext(new MockServletContext()); + context.getMockExternalContext().setNativeRequest(new MockHttpServletRequest()); + context.getMockExternalContext().setNativeResponse(new MockHttpServletResponse()); + context.getMockFlowExecutionContext().setKey(new MockFlowExecutionKey("c1v1")); + org.springframework.web.servlet.View mvcView = new MockView(); + MvcView view = new MvcView(mvcView, context); + view.resume(); + assertTrue(view.eventSignaled()); + assertEquals("submit", view.getEvent().getId()); + assertEquals("foo", bindBean.getStringProperty()); + assertEquals(new Integer(5), bindBean.getIntegerProperty()); + Calendar cal = Calendar.getInstance(); + cal.clear(); + cal.set(Calendar.YEAR, 2007); + assertEquals(cal.getTime(), bindBean.getDateProperty()); + } + + private class MockView implements View { + + public String getContentType() { + return "text/html"; + } + + public void render(Map model, HttpServletRequest request, HttpServletResponse response) throws Exception { + renderCalled = true; + MvcViewTests.this.model = model; + } + + } + + public static class BindBean { + private String stringProperty; + private Integer integerProperty = new Integer(3); + private Date dateProperty; + + public BindBean() { + Calendar cal = Calendar.getInstance(); + cal.clear(); + cal.set(Calendar.YEAR, 2008); + dateProperty = cal.getTime(); + } + + public String getStringProperty() { + return stringProperty; + } + + public void setStringProperty(String stringProperty) { + this.stringProperty = stringProperty; + } + + public Integer getIntegerProperty() { + return integerProperty; + } + + public void setIntegerProperty(Integer integerProperty) { + this.integerProperty = integerProperty; + } + + public Date getDateProperty() { + return dateProperty; + } + + public void setDateProperty(Date dateProperty) { + this.dateProperty = dateProperty; + } + + } + +} diff --git a/spring-webflow/src/test/java/org/springframework/webflow/persistence/HibernateFlowExecutionListenerTests.java b/spring-webflow/src/test/java/org/springframework/webflow/persistence/HibernateFlowExecutionListenerTests.java index d1a992d5..379922ee 100644 --- a/spring-webflow/src/test/java/org/springframework/webflow/persistence/HibernateFlowExecutionListenerTests.java +++ b/spring-webflow/src/test/java/org/springframework/webflow/persistence/HibernateFlowExecutionListenerTests.java @@ -69,7 +69,7 @@ public class HibernateFlowExecutionListenerTests extends TestCase { public void testSameSession() { MockRequestContext context = new MockRequestContext(); MockFlowSession flowSession = new MockFlowSession(); - flowSession.getDefinitionInternal().getAttributeMap().put("persistenceContext", "true"); + flowSession.getDefinition().getAttributes().put("persistenceContext", "true"); hibernateListener.sessionStarting(context, flowSession, null); context.setActiveSession(flowSession); assertSessionBound(); @@ -105,7 +105,7 @@ public class HibernateFlowExecutionListenerTests extends TestCase { assertEquals("Table should only have one row", 1, jdbcTemplate.queryForInt("select count(*) from T_BEAN")); MockRequestContext context = new MockRequestContext(); MockFlowSession flowSession = new MockFlowSession(); - flowSession.getDefinitionInternal().getAttributeMap().put("persistenceContext", "true"); + flowSession.getDefinition().getAttributes().put("persistenceContext", "true"); hibernateListener.sessionStarting(context, flowSession, null); context.setActiveSession(flowSession); assertSessionBound(); @@ -115,7 +115,7 @@ public class HibernateFlowExecutionListenerTests extends TestCase { assertEquals("Table should still only have one row", 1, jdbcTemplate.queryForInt("select count(*) from T_BEAN")); EndState endState = new EndState(flowSession.getDefinitionInternal(), "success"); - endState.getAttributeMap().put("commit", Boolean.TRUE); + endState.getAttributes().put("commit", Boolean.TRUE); flowSession.setState(endState); hibernateListener.sessionEnded(context, flowSession, null); @@ -128,7 +128,7 @@ public class HibernateFlowExecutionListenerTests extends TestCase { assertEquals("Table should only have one row", 1, jdbcTemplate.queryForInt("select count(*) from T_BEAN")); MockRequestContext context = new MockRequestContext(); MockFlowSession flowSession = new MockFlowSession(); - flowSession.getDefinitionInternal().getAttributeMap().put("persistenceContext", "true"); + flowSession.getDefinition().getAttributes().put("persistenceContext", "true"); hibernateListener.sessionStarting(context, flowSession, null); context.setActiveSession(flowSession); assertSessionBound(); @@ -146,7 +146,7 @@ public class HibernateFlowExecutionListenerTests extends TestCase { assertSessionBound(); EndState endState = new EndState(flowSession.getDefinitionInternal(), "success"); - endState.getAttributeMap().put("commit", Boolean.TRUE); + endState.getAttributes().put("commit", Boolean.TRUE); flowSession.setState(endState); hibernateListener.sessionEnded(context, flowSession, null); @@ -162,7 +162,7 @@ public class HibernateFlowExecutionListenerTests extends TestCase { assertEquals("Table should only have one row", 1, jdbcTemplate.queryForInt("select count(*) from T_BEAN")); MockRequestContext context = new MockRequestContext(); MockFlowSession flowSession = new MockFlowSession(); - flowSession.getDefinitionInternal().getAttributeMap().put("persistenceContext", "true"); + flowSession.getDefinition().getAttributes().put("persistenceContext", "true"); hibernateListener.sessionStarting(context, flowSession, null); context.setActiveSession(flowSession); assertSessionBound(); @@ -172,7 +172,7 @@ public class HibernateFlowExecutionListenerTests extends TestCase { assertEquals("Table should still only have one row", 1, jdbcTemplate.queryForInt("select count(*) from T_BEAN")); EndState endState = new EndState(flowSession.getDefinitionInternal(), "cancel"); - endState.getAttributeMap().put("commit", Boolean.FALSE); + endState.getAttributes().put("commit", Boolean.FALSE); flowSession.setState(endState); hibernateListener.sessionEnded(context, flowSession, null); assertEquals("Table should only have two rows", 1, jdbcTemplate.queryForInt("select count(*) from T_BEAN")); @@ -184,7 +184,7 @@ public class HibernateFlowExecutionListenerTests extends TestCase { assertEquals("Table should only have one row", 1, jdbcTemplate.queryForInt("select count(*) from T_BEAN")); MockRequestContext context = new MockRequestContext(); MockFlowSession flowSession = new MockFlowSession(); - flowSession.getDefinitionInternal().getAttributeMap().put("persistenceContext", "true"); + flowSession.getDefinition().getAttributes().put("persistenceContext", "true"); hibernateListener.sessionStarting(context, flowSession, null); context.setActiveSession(flowSession); assertSessionBound(); @@ -204,7 +204,7 @@ public class HibernateFlowExecutionListenerTests extends TestCase { assertEquals("Table should only have one row", 1, jdbcTemplate.queryForInt("select count(*) from T_BEAN")); MockRequestContext context = new MockRequestContext(); MockFlowSession flowSession = new MockFlowSession(); - flowSession.getDefinitionInternal().getAttributeMap().put("persistenceContext", "true"); + flowSession.getDefinition().getAttributes().put("persistenceContext", "true"); hibernateListener.sessionStarting(context, flowSession, null); context.setActiveSession(flowSession); assertSessionBound(); @@ -222,7 +222,7 @@ public class HibernateFlowExecutionListenerTests extends TestCase { assertEquals("Table should only have one row", 1, jdbcTemplate.queryForInt("select count(*) from T_BEAN")); MockRequestContext context = new MockRequestContext(); MockFlowSession flowSession = new MockFlowSession(); - flowSession.getDefinitionInternal().getAttributeMap().put("persistenceContext", "true"); + flowSession.getDefinition().getAttributes().put("persistenceContext", "true"); assertSessionNotBound(); hibernateListener.exceptionThrown(context, new FlowExecutionException("foo", "bar", "test")); assertSessionNotBound(); @@ -231,7 +231,7 @@ public class HibernateFlowExecutionListenerTests extends TestCase { public void testLazyInitializedCollection() { MockRequestContext context = new MockRequestContext(); MockFlowSession flowSession = new MockFlowSession(); - flowSession.getDefinitionInternal().getAttributeMap().put("persistenceContext", "true"); + flowSession.getDefinition().getAttributes().put("persistenceContext", "true"); hibernateListener.sessionStarting(context, flowSession, null); context.setActiveSession(flowSession); assertSessionBound(); diff --git a/spring-webflow/src/test/java/org/springframework/webflow/persistence/JpaFlowExecutionListenerTests.java b/spring-webflow/src/test/java/org/springframework/webflow/persistence/JpaFlowExecutionListenerTests.java index 589ff47b..710b1fb3 100644 --- a/spring-webflow/src/test/java/org/springframework/webflow/persistence/JpaFlowExecutionListenerTests.java +++ b/spring-webflow/src/test/java/org/springframework/webflow/persistence/JpaFlowExecutionListenerTests.java @@ -55,7 +55,7 @@ public class JpaFlowExecutionListenerTests extends TestCase { assertEquals("Table should only have one row", 1, jdbcTemplate.queryForInt("select count(*) from T_BEAN")); MockRequestContext context = new MockRequestContext(); MockFlowSession flowSession = new MockFlowSession(); - flowSession.getDefinitionInternal().getAttributeMap().put("persistenceContext", "true"); + flowSession.getDefinition().getAttributes().put("persistenceContext", "true"); jpaListener.sessionStarting(context, flowSession, null); context.setActiveSession(flowSession); assertSessionBound(); @@ -65,7 +65,7 @@ public class JpaFlowExecutionListenerTests extends TestCase { assertEquals("Table should still only have one row", 1, jdbcTemplate.queryForInt("select count(*) from T_BEAN")); EndState endState = new EndState(flowSession.getDefinitionInternal(), "success"); - endState.getAttributeMap().put("commit", Boolean.TRUE); + endState.getAttributes().put("commit", Boolean.TRUE); flowSession.setState(endState); jpaListener.sessionEnded(context, flowSession, null); @@ -78,7 +78,7 @@ public class JpaFlowExecutionListenerTests extends TestCase { assertEquals("Table should only have one row", 1, jdbcTemplate.queryForInt("select count(*) from T_BEAN")); MockRequestContext context = new MockRequestContext(); MockFlowSession flowSession = new MockFlowSession(); - flowSession.getDefinitionInternal().getAttributeMap().put("persistenceContext", "true"); + flowSession.getDefinition().getAttributes().put("persistenceContext", "true"); jpaListener.sessionStarting(context, flowSession, null); context.setActiveSession(flowSession); assertSessionBound(); @@ -96,7 +96,7 @@ public class JpaFlowExecutionListenerTests extends TestCase { assertSessionBound(); EndState endState = new EndState(flowSession.getDefinitionInternal(), "success"); - endState.getAttributeMap().put("commit", Boolean.TRUE); + endState.getAttributes().put("commit", Boolean.TRUE); flowSession.setState(endState); jpaListener.sessionEnded(context, flowSession, null); @@ -111,7 +111,7 @@ public class JpaFlowExecutionListenerTests extends TestCase { assertEquals("Table should only have one row", 1, jdbcTemplate.queryForInt("select count(*) from T_BEAN")); MockRequestContext context = new MockRequestContext(); MockFlowSession flowSession = new MockFlowSession(); - flowSession.getDefinitionInternal().getAttributeMap().put("persistenceContext", "true"); + flowSession.getDefinition().getAttributes().put("persistenceContext", "true"); jpaListener.sessionStarting(context, flowSession, null); context.setActiveSession(flowSession); assertSessionBound(); @@ -121,7 +121,7 @@ public class JpaFlowExecutionListenerTests extends TestCase { assertEquals("Table should still only have one row", 1, jdbcTemplate.queryForInt("select count(*) from T_BEAN")); EndState endState = new EndState(flowSession.getDefinitionInternal(), "cancel"); - endState.getAttributeMap().put("commit", Boolean.FALSE); + endState.getAttributes().put("commit", Boolean.FALSE); flowSession.setState(endState); jpaListener.sessionEnded(context, flowSession, null); assertEquals("Table should only have two rows", 1, jdbcTemplate.queryForInt("select count(*) from T_BEAN")); @@ -133,7 +133,7 @@ public class JpaFlowExecutionListenerTests extends TestCase { assertEquals("Table should only have one row", 1, jdbcTemplate.queryForInt("select count(*) from T_BEAN")); MockRequestContext context = new MockRequestContext(); MockFlowSession flowSession = new MockFlowSession(); - flowSession.getDefinitionInternal().getAttributeMap().put("persistenceContext", "true"); + flowSession.getDefinition().getAttributes().put("persistenceContext", "true"); jpaListener.sessionStarting(context, flowSession, null); context.setActiveSession(flowSession); assertSessionBound(); @@ -153,7 +153,7 @@ public class JpaFlowExecutionListenerTests extends TestCase { assertEquals("Table should only have one row", 1, jdbcTemplate.queryForInt("select count(*) from T_BEAN")); MockRequestContext context = new MockRequestContext(); MockFlowSession flowSession = new MockFlowSession(); - flowSession.getDefinitionInternal().getAttributeMap().put("persistenceContext", "true"); + flowSession.getDefinition().getAttributes().put("persistenceContext", "true"); jpaListener.sessionStarting(context, flowSession, null); context.setActiveSession(flowSession); assertSessionBound(); @@ -171,7 +171,7 @@ public class JpaFlowExecutionListenerTests extends TestCase { assertEquals("Table should only have one row", 1, jdbcTemplate.queryForInt("select count(*) from T_BEAN")); MockRequestContext context = new MockRequestContext(); MockFlowSession flowSession = new MockFlowSession(); - flowSession.getDefinitionInternal().getAttributeMap().put("persistenceContext", "true"); + flowSession.getDefinition().getAttributes().put("persistenceContext", "true"); assertSessionNotBound(); jpaListener.exceptionThrown(context, new FlowExecutionException("foo", "bar", "test")); assertSessionNotBound(); diff --git a/spring-webflow/src/test/resources/log4j.xml b/spring-webflow/src/test/resources/log4j.xml index b50d654b..b33a7753 100644 --- a/spring-webflow/src/test/resources/log4j.xml +++ b/spring-webflow/src/test/resources/log4j.xml @@ -14,7 +14,11 @@ - + + + + +