Classes in this File | Line Coverage | Branch Coverage | Complexity | ||||
DialogNavigationHandler |
|
| 4.666666666666667;4.667 |
1 | /* | |
2 | * Licensed to the Apache Software Foundation (ASF) under one or more | |
3 | * contributor license agreements. See the NOTICE file distributed with | |
4 | * this work for additional information regarding copyright ownership. | |
5 | * The ASF licenses this file to you under the Apache License, Version 2.0 | |
6 | * (the "License"); you may not use this file except in compliance with | |
7 | * the License. You may obtain a copy of the License at | |
8 | * | |
9 | * http://www.apache.org/licenses/LICENSE-2.0 | |
10 | * | |
11 | * Unless required by applicable law or agreed to in writing, software | |
12 | * distributed under the License is distributed on an "AS IS" BASIS, | |
13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |
14 | * See the License for the specific language governing permissions and | |
15 | * limitations under the License. | |
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 | // ------------------------------------------------------------ Constructors | |
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 | 0 | public DialogNavigationHandler(NavigationHandler original) { |
50 | 0 | if (log.isInfoEnabled()) { |
51 | 0 | log.info("Instantiating DialogNavigationHandler (wrapping instance '" |
52 | + original + "')"); | |
53 | } | |
54 | 0 | this.original = original; |
55 | 0 | } |
56 | ||
57 | ||
58 | // ------------------------------------------------- DialogContext Variables | |
59 | ||
60 | ||
61 | /** | |
62 | * <p>The <code>Log</code> instance for this class.</p> | |
63 | */ | |
64 | 0 | private Log log = LogFactory.getLog(DialogNavigationHandler.class); |
65 | ||
66 | ||
67 | /** | |
68 | * <p>The original <code>NavigationHandler</code> we delegate to.</p> | |
69 | */ | |
70 | 0 | private NavigationHandler original = null; |
71 | ||
72 | ||
73 | // ----------------------------------------------- NavigationHandler Methods | |
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 | 0 | if (log.isTraceEnabled()) { |
106 | 0 | log.trace("handleNavigation(context='" |
107 | + context + "', fromAction='" | |
108 | + fromAction + "', outcome='" | |
109 | + outcome + "')"); | |
110 | } | |
111 | ||
112 | 0 | DialogContext dcontext = (DialogContext) |
113 | context.getExternalContext().getRequestMap().get(Constants.CONTEXT_BEAN); | |
114 | 0 | String prefix = prefix(context); |
115 | 0 | if (dcontext == null) { |
116 | 0 | if ((outcome != null) && outcome.startsWith(prefix)) { |
117 | // Create and start a new DialogContext instance | |
118 | 0 | DialogContextManager manager = (DialogContextManager) |
119 | context.getApplication().getVariableResolver(). | |
120 | resolveVariable(context, Constants.MANAGER_BEAN); | |
121 | 0 | dcontext = |
122 | manager.create(context, outcome.substring(prefix.length())); | |
123 | 0 | dcontext.start(context); |
124 | 0 | if (log.isDebugEnabled()) { |
125 | 0 | 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 | 0 | return; |
132 | } else { | |
133 | // No active dialog, so delegate to the original handler | |
134 | 0 | original.handleNavigation(context, fromAction, outcome); |
135 | 0 | return; |
136 | } | |
137 | } else { | |
138 | // Advance the currently active DialogContext instance | |
139 | 0 | dcontext.advance(context, outcome); |
140 | 0 | if (log.isDebugEnabled()) { |
141 | 0 | log.debug("Advancing dialog '" |
142 | + dcontext.getName() + "' for FacesContext '" | |
143 | + context + "' with navigation to viewId '" | |
144 | + context.getViewRoot().getViewId() + "'"); | |
145 | } | |
146 | } | |
147 | ||
148 | 0 | } |
149 | ||
150 | ||
151 | // --------------------------------------------------------- Private Methods | |
152 | ||
153 | ||
154 | /** | |
155 | * <p>Cache the calculated value of the prefix that triggers starting | |
156 | * a dialog.</p> | |
157 | */ | |
158 | 0 | 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 | 0 | if (prefix != null) { |
171 | 0 | return prefix; |
172 | } | |
173 | 0 | prefix = context.getExternalContext(). |
174 | getInitParameter(Constants.DIALOG_PREFIX_PARAM); | |
175 | 0 | if (prefix == null) { |
176 | 0 | prefix = Constants.DIALOG_PREFIX; |
177 | } | |
178 | 0 | return prefix; |
179 | ||
180 | } | |
181 | ||
182 | ||
183 | } |