001: /*
002: * Copyright 2004-2007 the original author or authors.
003: *
004: * Licensed under the Apache License, Version 2.0 (the "License");
005: * you may not use this file except in compliance with the License.
006: * You may obtain a copy of the License at
007: *
008: * http://www.apache.org/licenses/LICENSE-2.0
009: *
010: * Unless required by applicable law or agreed to in writing, software
011: * distributed under the License is distributed on an "AS IS" BASIS,
012: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013: * See the License for the specific language governing permissions and
014: * limitations under the License.
015: */
016: package org.springframework.webflow.engine;
017:
018: import org.springframework.webflow.core.collection.AttributeMap;
019: import org.springframework.webflow.core.collection.MutableAttributeMap;
020: import org.springframework.webflow.execution.RequestContext;
021:
022: /**
023: * A service interface that maps attributes between two flows. Used by the
024: * subflow state to map attributes between a parent flow and its sub flow.
025: * <p>
026: * An attribute mapper may map attributes of a parent flow down to a child flow
027: * as <i>input</i> when the child is spawned as a subflow. In addition, a
028: * mapper may map output attributes of a subflow into a resuming parent flow as
029: * <i>output</i> when the child session ends and control is returned to the
030: * parent flow.
031: * <p>
032: * For example, say you have the following parent flow session:
033: * <p>
034: *
035: * <pre>
036: * Parent Flow Session
037: * -------------------
038: * -> flow = myFlow
039: * -> flowScope = [map-> attribute1=value1, attribute2=value2, attribute3=value3]
040: * </pre>
041: *
042: * <p>
043: * For the "Parent Flow Session" above, there are 3 attributes in flow scope
044: * ("attribute1", "attribute2" and "attribute3", respectively). Any of these
045: * three attributes may be mapped as input down to child subflows when those
046: * subflows are spawned. An implementation of this interface performs the actual
047: * mapping, encapsulating knowledge of <i>which</i> attributes should be
048: * mapped, and <i>how</i> they will be mapped (for example, will the same
049: * attribute names be used between flows or not?).
050: * <p>
051: * For example:
052: * <p>
053: *
054: * <pre>
055: * Flow Attribute Mapper Configuration
056: * -----------------------------------
057: * -> inputMappings = [map-> flowScope.attribute1->attribute1, flowScope.attribute3->attribute4]
058: * -> outputMappings = [map-> attribute4->flowScope.attribute3]
059: * </pre>
060: *
061: * <p>
062: * The above example "Flow Attribute Mapper" specifies
063: * <code>inputMappings</code> that define which parent attributes to map as
064: * input to the child. In this case, two attributes in flow scope of the parent
065: * are mapped, "attribute1" and "attribute3". "attribute1" is mapped with the
066: * name "attribute1" (given the same name in both flows), while "attribute3" is
067: * mapped to "attribute4", given a different name that is local to the child
068: * flow.
069: * <p>
070: * Likewise, when a child flow ends the <code>outputMappings</code> define
071: * which output attributes to map into the parent. In this case the subflow
072: * output attribute "attribute4" will be mapped up to the parent as "attribute3",
073: * updating the value of "attribute3" in the parent's flow scope. Note: only
074: * output attributes exposed by the end state of the ending subflow are eligible
075: * for mapping.
076: * <p>
077: * A FlowAttributeMapper is typically implemented using 2 distinct
078: * {@link org.springframework.binding.mapping.AttributeMapper} implementations:
079: * one responsible for input mapping and one taking care of output mapping.
080: * <p>
081: * Note: because FlowAttributeMappers are singletons, take care not to store
082: * and/or modify caller-specific state in a unsafe manner. The
083: * FlowAttributeMapper methods run in an independently executing thread on each
084: * invocation so make sure you deal only with local data or internal,
085: * thread-safe services.
086: *
087: * @see org.springframework.webflow.engine.SubflowState
088: * @see org.springframework.binding.mapping.AttributeMapper
089: *
090: * @author Keith Donald
091: * @author Erwin Vervaet
092: */
093: public interface FlowAttributeMapper {
094:
095: /**
096: * Create a map of attributes that should be passed as <i>input</i> to a
097: * spawning flow.
098: * <p>
099: * Attributes set in the map returned by this method are availale
100: * as input to the subflow when its session is spawned.
101: * @param context the current request execution context, which gives access
102: * to the parent flow scope, the request scope, any event parameters, etcetera
103: * @return a map of attributes (name=value pairs) to pass as input to the
104: * spawning subflow
105: */
106: public MutableAttributeMap createFlowInput(RequestContext context);
107:
108: /**
109: * Map output attributes of an ended flow to a resuming parent flow session.
110: * This maps the <i>output</i> of the child as new input to the resuming
111: * parent, typically adding data to flow scope.
112: * @param flowOutput the output attributes exposed by the ended subflow
113: * @param context the current request execution context, which gives access
114: * to the parent flow scope
115: */
116: public void mapFlowOutput(AttributeMap flowOutput,
117: RequestContext context);
118: }
|