1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 package org.apache.struts.faces.application;
23
24
25 import java.io.IOException;
26
27 import org.apache.struts.Globals;
28 import org.apache.struts.action.Action;
29 import org.apache.struts.action.ActionForm;
30 import org.apache.struts.action.ActionForward;
31 import org.apache.struts.action.ActionMapping;
32 import org.apache.struts.action.InvalidCancelException;
33 import org.apache.struts.config.FormBeanConfig;
34 import org.apache.struts.config.ForwardConfig;
35 import org.apache.struts.faces.Constants;
36 import org.apache.struts.faces.component.FormComponent;
37 import org.apache.struts.tiles.TilesRequestProcessor;
38 import org.slf4j.Logger;
39 import org.slf4j.LoggerFactory;
40
41 import jakarta.faces.FactoryFinder;
42 import jakarta.faces.application.ViewHandler;
43 import jakarta.faces.component.UICommand;
44 import jakarta.faces.component.UIComponent;
45 import jakarta.faces.context.FacesContext;
46 import jakarta.faces.context.FacesContextFactory;
47 import jakarta.faces.event.ActionEvent;
48 import jakarta.faces.lifecycle.Lifecycle;
49 import jakarta.faces.lifecycle.LifecycleFactory;
50 import jakarta.servlet.ServletException;
51 import jakarta.servlet.http.HttpServletRequest;
52 import jakarta.servlet.http.HttpServletResponse;
53
54
55
56
57
58
59
60
61
62
63
64
65
66 public class FacesTilesRequestProcessor extends TilesRequestProcessor {
67 private static final long serialVersionUID = -762245366421871701L;
68
69
70
71
72
73
74
75
76 private transient final Logger log =
77 LoggerFactory.getLogger(FacesTilesRequestProcessor.class);
78
79
80
81
82 public static final String LIFECYCLE_ID_ATTR = "jakarta.faces.LIFECYCLE_ID";
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102 protected void doForward(String uri,
103 HttpServletRequest request,
104 HttpServletResponse response)
105 throws IOException, ServletException {
106
107 if (log.isDebugEnabled()) {
108 log.debug("doForward(" + uri + ")");
109 }
110
111
112 request.removeAttribute(Constants.ACTION_EVENT_KEY);
113
114
115 if (isStrutsRequest(uri)) {
116 if (response.isCommitted()) {
117 if (log.isTraceEnabled()) {
118 log.trace(" super.doInclude(" + uri + ")");
119 }
120 super.doInclude(uri, request, response);
121 } else {
122 if (log.isTraceEnabled()) {
123 log.trace(" super.doForward(" + uri + ")");
124 }
125 super.doForward(uri, request, response);
126 }
127 return;
128 }
129
130
131 LifecycleFactory lf = (LifecycleFactory)
132 FactoryFinder.getFactory(FactoryFinder.LIFECYCLE_FACTORY);
133 Lifecycle lifecycle =
134 lf.getLifecycle(getLifecycleId());
135 boolean created = false;
136 FacesContext context = FacesContext.getCurrentInstance();
137 if (context == null) {
138 if (log.isTraceEnabled()) {
139 log.trace(" Creating new FacesContext for '" + uri + "'");
140 }
141 created = true;
142 FacesContextFactory fcf = (FacesContextFactory)
143 FactoryFinder.getFactory(FactoryFinder.FACES_CONTEXT_FACTORY);
144 context = fcf.getFacesContext(servlet.getServletContext(),
145 request, response, lifecycle);
146 }
147
148
149 ViewHandler vh = context.getApplication().getViewHandler();
150 if (log.isTraceEnabled()) {
151 log.trace(" Creating new view for '" + uri + "'");
152 }
153 context.setViewRoot(vh.createView(context, uri));
154
155
156 if (log.isTraceEnabled()) {
157 log.trace(" Rendering view for '" + uri + "'");
158 }
159 try {
160 lifecycle.render(context);
161 } finally {
162 if (created) {
163 if (log.isTraceEnabled()) {
164 log.trace(" Releasing context for '" + uri + "'");
165 }
166 context.release();
167 } else {
168 if (log.isTraceEnabled()) {
169 log.trace(" Rendering completed");
170 }
171 }
172 }
173
174 }
175
176
177
178 protected void internalModuleRelativeForward
179 (String uri, HttpServletRequest request, HttpServletResponse response)
180 throws IOException, ServletException {
181
182 if (log.isTraceEnabled()) {
183 log.trace("Performing internal module relative forward to '" +
184 uri + "'");
185 }
186 super.internalModuleRelativeForward(uri, request, response);
187
188 }
189
190
191
192 protected Action processActionCreate(HttpServletRequest request,
193 HttpServletResponse response,
194 ActionMapping mapping)
195 throws IOException {
196
197 if (log.isTraceEnabled()) {
198 log.trace("Performing standard action create");
199 }
200 Action result = super.processActionCreate(request, response, mapping);
201 if (log.isDebugEnabled()) {
202 log.debug("Standard action create returned " +
203 result.getClass().getName() + " instance");
204 }
205 return (result);
206
207 }
208
209
210
211 protected ActionForm processActionForm(HttpServletRequest request,
212 HttpServletResponse response,
213 ActionMapping mapping) {
214 if (log.isTraceEnabled()) {
215 log.trace("Performing standard action form processing");
216 String attribute = mapping.getAttribute();
217 if (attribute != null) {
218 String name = mapping.getName();
219 FormBeanConfig fbc = moduleConfig.findFormBeanConfig(name);
220 if (fbc != null) {
221 if ("request".equals(mapping.getScope())) {
222 log.trace(" Bean in request scope = " +
223 request.getAttribute(attribute));
224 } else {
225 log.trace(" Bean in session scope = " +
226 request.getSession().getAttribute(attribute));
227 }
228 } else {
229 log.trace(" No FormBeanConfig for '" + name + "'");
230 }
231 } else {
232 log.trace(" No form bean for this action");
233 }
234 }
235 ActionForm result =
236 super.processActionForm(request, response, mapping);
237 if (log.isDebugEnabled()) {
238 log.debug("Standard action form returned " +
239 result);
240 }
241 return (result);
242
243
244 }
245
246
247
248 protected ActionForward processActionPerform(HttpServletRequest request,
249 HttpServletResponse response,
250 Action action,
251 ActionForm form,
252 ActionMapping mapping)
253 throws IOException, ServletException {
254
255 if (log.isTraceEnabled()) {
256 log.trace("Performing standard action perform");
257 }
258 ActionForward result =
259 super.processActionPerform(request, response, action,
260 form, mapping);
261 if (log.isDebugEnabled()) {
262 log.debug("Standard action perform returned " +
263 (result == null ? "NULL" :
264 result.getPath()) + " forward path");
265 }
266 return (result);
267
268 }
269
270
271
272 protected boolean processForward(HttpServletRequest request,
273 HttpServletResponse response,
274 ActionMapping mapping)
275 throws IOException, ServletException {
276
277 if (log.isTraceEnabled()) {
278 log.trace("Performing standard forward handling");
279 }
280 boolean result = super.processForward
281 (request, response, mapping);
282 if (log.isDebugEnabled()) {
283 log.debug("Standard forward handling returned " + result);
284 }
285 return (result);
286
287 }
288
289
290
291 protected void processForwardConfig(HttpServletRequest request,
292 HttpServletResponse response,
293 ForwardConfig forward)
294 throws IOException, ServletException {
295
296 if (log.isTraceEnabled()) {
297 log.trace("Performing standard forward config handling");
298 }
299 super.processForwardConfig(request, response, forward);
300 if (log.isDebugEnabled()) {
301 log.debug("Standard forward config handling completed");
302 }
303
304 }
305
306
307
308 protected boolean processInclude(HttpServletRequest request,
309 HttpServletResponse response,
310 ActionMapping mapping)
311 throws IOException, ServletException {
312
313 if (log.isTraceEnabled()) {
314 log.trace("Performing standard include handling");
315 }
316 boolean result = super.processInclude
317 (request, response, mapping);
318 if (log.isDebugEnabled()) {
319 log.debug("Standard include handling returned " + result);
320 }
321 return (result);
322
323 }
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338 protected String processPath(HttpServletRequest request,
339 HttpServletResponse response)
340 throws IOException {
341
342
343 ActionEvent event = (ActionEvent)
344 request.getAttribute(Constants.ACTION_EVENT_KEY);
345
346
347 if (event == null) {
348 if (log.isTraceEnabled()) {
349 log.trace("Performing standard processPath() processing");
350 }
351 return (super.processPath(request, response));
352 }
353
354
355 UIComponent component = event.getComponent();
356 if (log.isTraceEnabled()) {
357 log.trace("Locating form parent for command component " +
358 event.getComponent());
359 }
360 while (!(component instanceof FormComponent)) {
361 component = component.getParent();
362 if (component == null) {
363 log.warn("Command component was not nested in a Struts form!");
364 return (null);
365 }
366 }
367 if (log.isTraceEnabled()) {
368 log.trace("Returning selected path of " +
369 ((FormComponent) component).getAction());
370 }
371 return (((FormComponent) component).getAction());
372
373 }
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391 protected void processPopulate(HttpServletRequest request,
392 HttpServletResponse response,
393 ActionForm form,
394 ActionMapping mapping)
395 throws ServletException {
396
397
398 ActionEvent event = (ActionEvent)
399 request.getAttribute(Constants.ACTION_EVENT_KEY);
400
401
402 if (event == null) {
403 if (log.isTraceEnabled()) {
404 log.trace("Performing standard processPopulate() processing");
405 }
406 super.processPopulate(request, response, form, mapping);
407 return;
408 }
409
410
411
412 if (log.isTraceEnabled()) {
413 log.trace("Faces request, so no processPopulate() processing");
414 }
415 UIComponent source = event.getComponent();
416 if (source instanceof UICommand) {
417 if ("cancel".equals(((UICommand) source).getId())) {
418 if (log.isTraceEnabled()) {
419 log.trace("Faces request with cancel button pressed");
420 }
421 request.setAttribute(Globals.CANCEL_KEY, Boolean.TRUE);
422 }
423 }
424
425 }
426
427
428
429 protected boolean processValidate(HttpServletRequest request,
430 HttpServletResponse response,
431 ActionForm form,
432 ActionMapping mapping)
433 throws IOException, ServletException, InvalidCancelException {
434
435 if (log.isTraceEnabled()) {
436 log.trace("Performing standard validation");
437 }
438 boolean result = super.processValidate
439 (request, response, form, mapping);
440 if (log.isDebugEnabled()) {
441 log.debug("Standard validation processing returned " + result);
442 }
443 return (result);
444
445 }
446
447
448
449
450
451
452
453
454 private String getLifecycleId()
455 {
456 String lifecycleId = this.servlet.getServletContext().getInitParameter(LIFECYCLE_ID_ATTR);
457 return lifecycleId != null ? lifecycleId : LifecycleFactory.DEFAULT_LIFECYCLE;
458 }
459
460
461
462
463
464
465
466 private boolean isStrutsRequest(String uri) {
467
468 int question = uri.indexOf("?");
469 if (question >= 0) {
470 uri = uri.substring(0, question);
471 }
472 String mapping = (String)
473 servlet.getServletContext().getAttribute(Globals.SERVLET_KEY);
474 if (mapping == null) {
475 return (false);
476 } else if (mapping.startsWith("*.")) {
477 return (uri.endsWith(mapping.substring(1)));
478 } else if (mapping.endsWith("/*")) {
479 return (uri.startsWith(mapping.substring(0, mapping.length() - 2)));
480 } else {
481 return (false);
482 }
483
484 }
485 }