01: /*
02: * Created on 10-Feb-2006
03: */
04: package uk.org.ponder.rsf.flow.jsfnav;
05:
06: import java.util.List;
07: import java.util.Map;
08:
09: import uk.org.ponder.messageutil.TargettedMessageList;
10: import uk.org.ponder.rsf.flow.ARIResult;
11: import uk.org.ponder.rsf.flow.ActionResultInterpreter;
12: import uk.org.ponder.rsf.viewstate.ViewParameters;
13:
14: /** An ActionResultInterpreter implementing "JSF-style" navigation semantics.
15: * Encodes a one-step (contextless) rule mapping action result to resulting
16: * view, by matching one of a set of "NavigationRules" which may map on
17: * String result and/or source view.
18: * @author Antranig Basman (antranig@caret.cam.ac.uk)
19: *
20: */
21:
22: public class JSFNavActionResultInterpreter implements
23: ActionResultInterpreter {
24:
25: private NavigationMap map;
26:
27: private Map fromviews;
28:
29: private TargettedMessageList messages;
30:
31: public void setNavigationMap(NavigationMap map) {
32: this .map = map;
33: }
34:
35: public void setNavigationCasePooler(NavigationCasePooler pooler) {
36: fromviews = pooler.getPooledMap();
37: }
38:
39: public void setTargettedMessageList(TargettedMessageList messages) {
40: this .messages = messages;
41: }
42:
43: private static void processCaseList(List caselist, ARIResult togo,
44: Object result) {
45: if (caselist != null) {
46: for (int j = 0; j < caselist.size(); ++j) {
47: NavigationCase navcase = (NavigationCase) caselist
48: .get(j);
49: // TODO: Fix up these rules wrt. specificity of overrides to agree
50: // more with JSF semantics
51: if (navcase.fromOutcome == null
52: || navcase.fromOutcome.equals(result)) {
53: if (navcase.resultingView != null) {
54: togo.resultingView = navcase.resultingView
55: .copy();
56: }
57: togo.propagateBeans = navcase.flowCondition;
58: }
59: }
60: }
61: }
62:
63: public ARIResult interpretActionResult(ViewParameters incoming,
64: Object result) {
65: ARIResult togo = new ARIResult();
66: togo.resultingView = incoming;
67: togo.propagateBeans = ARIResult.FLOW_END;
68:
69: boolean matchingrule = false;
70:
71: if (map.navigationRules != null) {
72: for (int i = 0; i < map.navigationRules.size(); ++i) {
73: NavigationRule rule = (NavigationRule) map.navigationRules
74: .get(i);
75: if (rule.fromViewId.viewID.equals(incoming.viewID)) {
76: matchingrule = true;
77: processCaseList(rule.navigationCases, togo, result);
78: }
79: }
80: }
81: List rulesfromviews = (List) fromviews.get(incoming.viewID);
82: if (rulesfromviews != null && rulesfromviews.size() > 0) {
83: matchingrule = true;
84: }
85: processCaseList(rulesfromviews, togo, result);
86: if (messages.isError()) {
87: // Apply this default EARLY so that a following ARI2 can see our decision
88: // However, we *do* need to pick up any flow condition from the desired
89: // NavigationCase. In fact we probably need a separate "onError" form of
90: // NavigationCase "fromOutcome".
91: togo.resultingView = incoming.copyBase();
92: }
93: return matchingrule ? togo : null;
94: }
95:
96: }
|