This commit is contained in:
@@ -21,6 +21,7 @@ import java.io.ObjectOutputStream;
|
||||
import java.io.Serializable;
|
||||
import java.util.Collection;
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.Map;
|
||||
|
||||
import org.springframework.binding.collection.MapAccessor;
|
||||
@@ -232,6 +233,18 @@ public class LocalAttributeMap implements MutableAttributeMap, Serializable {
|
||||
return this;
|
||||
}
|
||||
|
||||
public MutableAttributeMap removeAll(MutableAttributeMap attributes) {
|
||||
if (attributes == null) {
|
||||
return this;
|
||||
}
|
||||
Iterator it = attributes.asMap().keySet().iterator();
|
||||
Map internal = getMapInternal();
|
||||
while (it.hasNext()) {
|
||||
internal.remove(it.next());
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
public Object remove(String attributeName) {
|
||||
return getMapInternal().remove(attributeName);
|
||||
}
|
||||
|
||||
@@ -45,6 +45,13 @@ public interface MutableAttributeMap extends AttributeMap {
|
||||
*/
|
||||
public MutableAttributeMap putAll(AttributeMap attributes);
|
||||
|
||||
/**
|
||||
* Remove all attributes in the map provided from this map.
|
||||
* @param attributes the attributes to remove from this map
|
||||
* @return this, to support call chaining
|
||||
*/
|
||||
public MutableAttributeMap removeAll(MutableAttributeMap attributes);
|
||||
|
||||
/**
|
||||
* Remove an attribute from this map.
|
||||
* @param attributeName the name of the attribute to remove
|
||||
|
||||
@@ -18,7 +18,7 @@ package org.springframework.webflow.engine;
|
||||
import org.springframework.core.style.ToStringCreator;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.StringUtils;
|
||||
import org.springframework.webflow.core.collection.AttributeMap;
|
||||
import org.springframework.webflow.action.MultiAction;
|
||||
import org.springframework.webflow.execution.Action;
|
||||
import org.springframework.webflow.execution.Event;
|
||||
import org.springframework.webflow.execution.RequestContext;
|
||||
@@ -43,7 +43,6 @@ public class AnnotatedAction extends AnnotatedObject implements Action {
|
||||
* <p>
|
||||
* The name attribute is often used as a qualifier for an action's result event, and is typically used to allow the
|
||||
* flow to respond to a specific action's outcome within a larger action execution chain.
|
||||
* @see ActionState
|
||||
*/
|
||||
public static final String NAME_ATTRIBUTE = "name";
|
||||
|
||||
@@ -51,8 +50,7 @@ public class AnnotatedAction extends AnnotatedObject implements Action {
|
||||
* The action execution method attribute ("method").
|
||||
* <p>
|
||||
* The method property is a hint about what method should be invoked; for example, the name of a specific target
|
||||
* method on a {@link org.springframework.webflow.action.MultiAction multi action}.
|
||||
* @see ActionState
|
||||
* method on a {@link MultiAction multi-action}.
|
||||
*/
|
||||
public static final String METHOD_ATTRIBUTE = "method";
|
||||
|
||||
@@ -139,14 +137,12 @@ public class AnnotatedAction extends AnnotatedObject implements Action {
|
||||
}
|
||||
|
||||
public Event execute(RequestContext context) throws Exception {
|
||||
AttributeMap originalAttributes = getAttributes();
|
||||
try {
|
||||
context.setAttributes(getAttributes());
|
||||
context.getAttributes().putAll(getAttributes());
|
||||
Event result = getTargetAction().execute(context);
|
||||
return postProcessResult(result);
|
||||
} finally {
|
||||
// restore original attributes
|
||||
context.setAttributes(originalAttributes);
|
||||
context.getAttributes().removeAll(getAttributes());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -18,8 +18,6 @@ package org.springframework.webflow.engine.impl;
|
||||
import org.springframework.binding.message.MessageContext;
|
||||
import org.springframework.core.style.ToStringCreator;
|
||||
import org.springframework.webflow.context.ExternalContext;
|
||||
import org.springframework.webflow.core.collection.AttributeMap;
|
||||
import org.springframework.webflow.core.collection.CollectionUtils;
|
||||
import org.springframework.webflow.core.collection.LocalAttributeMap;
|
||||
import org.springframework.webflow.core.collection.MutableAttributeMap;
|
||||
import org.springframework.webflow.core.collection.ParameterMap;
|
||||
@@ -70,10 +68,9 @@ class RequestControlContextImpl implements RequestControlContext {
|
||||
private LocalAttributeMap requestScope = new LocalAttributeMap();
|
||||
|
||||
/**
|
||||
* Holder for contextual properties describing the currently executing request; never null, initially empty and
|
||||
* immutable.
|
||||
* Holder for contextual properties describing the currently executing request; never null, initially empty.
|
||||
*/
|
||||
private AttributeMap attributes = CollectionUtils.EMPTY_ATTRIBUTE_MAP;
|
||||
private LocalAttributeMap attributes = new LocalAttributeMap();
|
||||
|
||||
/**
|
||||
* The current event being processed by this flow; initially null.
|
||||
@@ -157,18 +154,10 @@ class RequestControlContextImpl implements RequestControlContext {
|
||||
return currentTransition;
|
||||
}
|
||||
|
||||
public AttributeMap getAttributes() {
|
||||
public MutableAttributeMap getAttributes() {
|
||||
return attributes;
|
||||
}
|
||||
|
||||
public void setAttributes(AttributeMap attributes) {
|
||||
if (attributes == null) {
|
||||
this.attributes = CollectionUtils.EMPTY_ATTRIBUTE_MAP;
|
||||
} else {
|
||||
this.attributes = attributes;
|
||||
}
|
||||
}
|
||||
|
||||
// implementing RequestControlContext
|
||||
|
||||
public String getFlowExecutionUrl() {
|
||||
|
||||
@@ -17,7 +17,6 @@ package org.springframework.webflow.execution;
|
||||
|
||||
import org.springframework.binding.message.MessageContext;
|
||||
import org.springframework.webflow.context.ExternalContext;
|
||||
import org.springframework.webflow.core.collection.AttributeMap;
|
||||
import org.springframework.webflow.core.collection.MutableAttributeMap;
|
||||
import org.springframework.webflow.core.collection.ParameterMap;
|
||||
import org.springframework.webflow.definition.FlowDefinition;
|
||||
@@ -175,17 +174,11 @@ public interface RequestContext {
|
||||
public TransitionDefinition getCurrentTransition();
|
||||
|
||||
/**
|
||||
* Returns a context map for accessing arbitrary attributes about the state of the current request. These attributes
|
||||
* may be used to influence flow execution behavior.
|
||||
* @return the current attributes of this request, or empty if not set
|
||||
* Returns a context map for accessing attributes about the state of the current request. These attributes may be
|
||||
* used to influence flow execution behavior.
|
||||
* @return the current attributes of this request, or empty if none are set
|
||||
*/
|
||||
public AttributeMap getAttributes();
|
||||
|
||||
/**
|
||||
* Set the contextual attributes describing the state of this request. Overwrites any pre-existing collection.
|
||||
* @param attributes the attributes
|
||||
*/
|
||||
public void setAttributes(AttributeMap attributes);
|
||||
public MutableAttributeMap getAttributes();
|
||||
|
||||
/**
|
||||
* Returns the context-relative URL of this flow execution. Needed by response writers that write out the URL of
|
||||
|
||||
@@ -166,14 +166,10 @@ public class MockRequestContext implements RequestContext {
|
||||
return currentTransition;
|
||||
}
|
||||
|
||||
public AttributeMap getAttributes() {
|
||||
public MutableAttributeMap getAttributes() {
|
||||
return attributes;
|
||||
}
|
||||
|
||||
public void setAttributes(AttributeMap attributes) {
|
||||
this.attributes.replaceWith(attributes);
|
||||
}
|
||||
|
||||
public String getFlowExecutionUrl() {
|
||||
if (flowExecutionContext.getKey() == null) {
|
||||
throw new IllegalStateException(
|
||||
|
||||
@@ -18,6 +18,7 @@ package org.springframework.webflow.engine;
|
||||
import junit.framework.TestCase;
|
||||
|
||||
import org.springframework.webflow.action.AbstractAction;
|
||||
import org.springframework.webflow.engine.AnnotatedAction;
|
||||
import org.springframework.webflow.execution.Event;
|
||||
import org.springframework.webflow.execution.RequestContext;
|
||||
import org.springframework.webflow.execution.TestAction;
|
||||
@@ -47,6 +48,22 @@ public class AnnotedActionTests extends TestCase {
|
||||
}
|
||||
});
|
||||
assertEquals("success", action.execute(context).getId());
|
||||
assertEquals(0, context.getAttributes().size());
|
||||
}
|
||||
|
||||
public void testExecuteWithChainOfCustomAttributes() throws Exception {
|
||||
AnnotatedAction action2 = new AnnotatedAction(action);
|
||||
action2.getAttributes().put("attr2", "value");
|
||||
action.getAttributes().put("attr", "value");
|
||||
action.setTargetAction(new AbstractAction() {
|
||||
protected Event doExecute(RequestContext context) throws Exception {
|
||||
assertEquals("value", context.getAttributes().getString("attr"));
|
||||
assertEquals("value", context.getAttributes().getString("attr2"));
|
||||
return success();
|
||||
}
|
||||
});
|
||||
assertEquals("success", action2.execute(context).getId());
|
||||
assertEquals(0, context.getAttributes().size());
|
||||
}
|
||||
|
||||
public void testExecuteWithName() throws Exception {
|
||||
|
||||
Reference in New Issue
Block a user