01: /*
02: * Created on 6 Aug 2006
03: */
04: package uk.org.ponder.rsf.flow.support;
05:
06: import uk.org.ponder.rsf.flow.ARIResult;
07: import uk.org.ponder.rsf.preservation.StatePreservationManager;
08: import uk.org.ponder.rsf.state.ErrorStateManager;
09: import uk.org.ponder.rsf.viewstate.ViewParameters;
10:
11: /** Manages adjustment of ARIResult fields and scopes to take account of
12: * changes in flow state. Relatively tightly coupled to RSFActionHandler,
13: * since control is shared of the state of StatePreservationManager.
14: * @author Antranig Basman (antranig@caret.cam.ac.uk)
15: *
16: */
17:
18: public class FlowStateManager {
19: private ErrorStateManager errorstatemanager;
20: private StatePreservationManager presmanager; // no, not that of OS/2
21:
22: public void setErrorStateManager(ErrorStateManager errorstatemanager) {
23: this .errorstatemanager = errorstatemanager;
24: }
25:
26: public void setStatePreservationManager(
27: StatePreservationManager presmanager) {
28: this .presmanager = presmanager;
29: }
30:
31: public void inferFlowState(ViewParameters viewparams,
32: ARIResult ariresult) {
33:
34: String prop = ariresult.propagateBeans; // propagation code for this cycle
35: // An external URL must naturally end any flow
36: if (!(ariresult.resultingView instanceof ViewParameters)) {
37: if (viewparams.flowtoken != null) {
38: presmanager.flowEnd(viewparams.flowtoken);
39: }
40: return;
41: }
42: ViewParameters newview = (ViewParameters) ariresult.resultingView;
43:
44: if (!prop.equals(ARIResult.FLOW_END)
45: && !prop.equals(ARIResult.FLOW_ONESTEP)) {
46: // TODO: consider whether we want to allow ARI to allocate a NEW TOKEN
47: // for a FLOW FORK. Some call this, "continuations".
48: if (newview.flowtoken == null) {
49: if (prop.equals(ARIResult.FLOW_START)
50: || prop.equals(ARIResult.FLOW_FASTSTART)) {
51: // if the ARI wanted one and hasn't allocated one, allocate flow
52: // token.
53: newview.flowtoken = errorstatemanager
54: .allocateToken();
55: } else { // else assume existing flow continues.
56: if (viewparams.flowtoken == null) {
57: throw new IllegalStateException(
58: "Cannot propagate flow state without active flow");
59: }
60: newview.flowtoken = viewparams.flowtoken;
61: }
62: }
63: // On a FLOW_START, **ONLY** the flow state itself is to be saved,
64: // since any other existing bean state will be non-flow or end-flow.
65: presmanager.preserve(newview.flowtoken, prop
66: .equals(ARIResult.FLOW_START));
67: } else if (prop.equals(ARIResult.FLOW_ONESTEP)) {
68: if (viewparams.endflow != null
69: || viewparams.flowtoken != null) {
70: throw new IllegalStateException(
71: "Cannot use one-step flow from previous flow state");
72: }
73: newview.flowtoken = errorstatemanager.allocateToken();
74: newview.endflow = "1";
75: presmanager.flowEnd(newview.flowtoken);
76: } else { // it is a flow end.
77: if (viewparams.flowtoken != null) {
78: newview.endflow = "1";
79: newview.flowtoken = viewparams.flowtoken;
80: presmanager.flowEnd(viewparams.flowtoken);
81: }
82: }
83: }
84: }
|