2009/05/20 - Apache Shale has been retired.
For more information, please explore the Attic.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 package org.apache.shale.dialog.faces;
19
20 import javax.faces.application.NavigationHandler;
21 import javax.faces.context.FacesContext;
22
23 import org.apache.commons.logging.Log;
24 import org.apache.commons.logging.LogFactory;
25 import org.apache.shale.dialog.Constants;
26 import org.apache.shale.dialog.DialogContext;
27 import org.apache.shale.dialog.DialogContextManager;
28
29 /***
30 * <p><code>NavigationHandler</code> implementation that allows dialogs to
31 * be created via a logical outcome that returns with a specified prefix.
32 * This is not the only way to start a dialog instance (applications can also
33 * do this programmatically), but it is convenient in many cases.</p>
34 *
35 * @since 1.0.4
36 */
37 public final class DialogNavigationHandler extends NavigationHandler {
38
39
40
41
42
43 /***
44 * <p>Creates a new instance of DialogNavigationHandler that delegates
45 * to the specified original handler.</p>
46 *
47 * @param original Original NavigationHandler
48 */
49 public DialogNavigationHandler(NavigationHandler original) {
50 if (log.isInfoEnabled()) {
51 log.info("Instantiating DialogNavigationHandler (wrapping instance '"
52 + original + "')");
53 }
54 this.original = original;
55 }
56
57
58
59
60
61 /***
62 * <p>The <code>Log</code> instance for this class.</p>
63 */
64 private Log log = LogFactory.getLog(DialogNavigationHandler.class);
65
66
67 /***
68 * <p>The original <code>NavigationHandler</code> we delegate to.</p>
69 */
70 private NavigationHandler original = null;
71
72
73
74
75
76 /***
77 * <p>Handle a navigation request from the application. The following
78 * rules are applied:</p>
79 * <ul>
80 * <li>If this view is <strong>NOT</strong> currently executing
81 * a {@link DialogContext} instance:
82 * <ul>
83 * <li>If the logical outcome begins with the prefix identified
84 * by the prefix specified by context init parameter
85 * <code>Constants.DIALOG_PREFIX_PARAM</code> (with a default
86 * value of <code>Constants.DIALOG_PREFIX</code>), create and start
87 * a new {@link DialogContext} instance for a logical name
88 * based on the remainder of the logical outcome after the
89 * prefix.</li>
90 * <li>Otherwise, delegate control to the original navigation
91 * handler passed to our constructor.</li>
92 * </ul></li>
93 * <li>If this view is currently executing a {@link DialogContext}
94 * instance, advance its progress based on the specified logical
95 * outcome.</li>
96 * </ul>
97 *
98 * @param context FacesContext for the current request
99 * @param fromAction Action that was invoked
100 * @param outcome Logical outcome from the invoked action
101 */
102 public void handleNavigation(FacesContext context, String fromAction,
103 String outcome) {
104
105 if (log.isTraceEnabled()) {
106 log.trace("handleNavigation(context='"
107 + context + "', fromAction='"
108 + fromAction + "', outcome='"
109 + outcome + "')");
110 }
111
112 DialogContext dcontext = (DialogContext)
113 context.getExternalContext().getRequestMap().get(Constants.CONTEXT_BEAN);
114 String prefix = prefix(context);
115 if (dcontext == null) {
116 if ((outcome != null) && outcome.startsWith(prefix)) {
117
118 DialogContextManager manager = (DialogContextManager)
119 context.getApplication().getVariableResolver().
120 resolveVariable(context, Constants.MANAGER_BEAN);
121 dcontext =
122 manager.create(context, outcome.substring(prefix.length()));
123 dcontext.start(context);
124 if (log.isDebugEnabled()) {
125 log.debug("Starting dialog '"
126 + outcome.substring(prefix.length())
127 + "' for FacesContext instance '"
128 + context + "' with navigation to viewId '"
129 + context.getViewRoot().getViewId() + "'");
130 }
131 return;
132 } else {
133
134 original.handleNavigation(context, fromAction, outcome);
135 return;
136 }
137 } else {
138
139 dcontext.advance(context, outcome);
140 if (log.isDebugEnabled()) {
141 log.debug("Advancing dialog '"
142 + dcontext.getName() + "' for FacesContext '"
143 + context + "' with navigation to viewId '"
144 + context.getViewRoot().getViewId() + "'");
145 }
146 }
147
148 }
149
150
151
152
153
154 /***
155 * <p>Cache the calculated value of the prefix that triggers starting
156 * a dialog.</p>
157 */
158 private String prefix = null;
159
160
161 /***
162 * <p>Return the prefix string that indicates a logical outcome that
163 * should trigger starting a dialog. The default value can be overridden
164 * by an appropriate context initialization parameter.</p>
165 *
166 * @param context <code>FacesContext</code> for the current request
167 */
168 private String prefix(FacesContext context) {
169
170 if (prefix != null) {
171 return prefix;
172 }
173 prefix = context.getExternalContext().
174 getInitParameter(Constants.DIALOG_PREFIX_PARAM);
175 if (prefix == null) {
176 prefix = Constants.DIALOG_PREFIX;
177 }
178 return prefix;
179
180 }
181
182
183 }