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.action.RequestProcessor;
34 import org.apache.struts.config.FormBeanConfig;
35 import org.apache.struts.config.ForwardConfig;
36 import org.apache.struts.faces.Constants;
37 import org.apache.struts.faces.component.FormComponent;
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
67 public class FacesRequestProcessor extends RequestProcessor {
68 private static final long serialVersionUID = 4303368318034722173L;
69
70
71
72
73
74
75
76
77 private transient final Logger log =
78 LoggerFactory.getLogger(FacesRequestProcessor.class);
79
80
81
82
83
84 public static final String LIFECYCLE_ID_ATTR = "jakarta.faces.LIFECYCLE_ID";
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103 protected void doForward(String uri,
104 HttpServletRequest request,
105 HttpServletResponse response)
106 throws IOException, ServletException {
107
108 log.debug("doForward({})", uri);
109
110
111 request.removeAttribute(Constants.ACTION_EVENT_KEY);
112
113
114 if (isStrutsRequest(uri)) {
115 if (response.isCommitted()) {
116 log.trace(" super.doInclude({})", uri);
117 super.doInclude(uri, request, response);
118 } else {
119 log.trace(" super.doForward({})", uri);
120 super.doForward(uri, request, response);
121 }
122 return;
123 }
124
125
126 LifecycleFactory lf = (LifecycleFactory)
127 FactoryFinder.getFactory(FactoryFinder.LIFECYCLE_FACTORY);
128 Lifecycle lifecycle =
129 lf.getLifecycle(getLifecycleId());
130 boolean created = false;
131 FacesContext context = FacesContext.getCurrentInstance();
132 if (context == null) {
133 log.trace(" Creating new FacesContext for '{}'", uri);
134 created = true;
135 FacesContextFactory fcf = (FacesContextFactory)
136 FactoryFinder.getFactory(FactoryFinder.FACES_CONTEXT_FACTORY);
137 context = fcf.getFacesContext(servlet.getServletContext(),
138 request, response, lifecycle);
139 }
140
141
142 ViewHandler vh = context.getApplication().getViewHandler();
143 log.trace(" Creating new view for '{}'", uri);
144 context.setViewRoot(vh.createView(context, uri));
145
146
147 log.trace(" Rendering view for '{}'", uri);
148 try {
149 lifecycle.render(context);
150 } finally {
151 if (created) {
152 log.trace(" Releasing context for '{}'", uri);
153 context.release();
154 } else {
155 log.trace(" Rendering completed");
156 }
157 }
158
159 }
160
161
162
163 protected Action processActionCreate(HttpServletRequest request,
164 HttpServletResponse response,
165 ActionMapping mapping)
166 throws IOException {
167
168 log.trace("Performing standard action create");
169 Action result = super.processActionCreate(request, response, mapping);
170 log.debug("Standard action create returned {} instance",
171 result.getClass().getName());
172 return (result);
173
174 }
175
176
177
178 protected ActionForm processActionForm(HttpServletRequest request,
179 HttpServletResponse response,
180 ActionMapping mapping) {
181 if (log.isTraceEnabled()) {
182 log.trace("Performing standard action form processing");
183 String attribute = mapping.getAttribute();
184 if (attribute != null) {
185 String name = mapping.getName();
186 FormBeanConfig fbc = moduleConfig.findFormBeanConfig(name);
187 if (fbc != null) {
188 if ("request".equals(mapping.getScope())) {
189 log.trace(" Bean in request scope = {}",
190 request.getAttribute(attribute));
191 } else {
192 log.trace(" Bean in session scope = {}",
193 request.getSession().getAttribute(attribute));
194 }
195 } else {
196 log.trace(" No FormBeanConfig for '{}'", name);
197 }
198 } else {
199 log.trace(" No form bean for this action");
200 }
201 }
202 ActionForm result =
203 super.processActionForm(request, response, mapping);
204 log.debug("Standard action form returned {}",
205 result);
206 return (result);
207
208
209 }
210
211
212
213 protected ActionForward processActionPerform(HttpServletRequest request,
214 HttpServletResponse response,
215 Action action,
216 ActionForm form,
217 ActionMapping mapping)
218 throws IOException, ServletException {
219
220 log.trace("Performing standard action perform");
221 ActionForward result =
222 super.processActionPerform(request, response, action,
223 form, mapping);
224 log.atDebug()
225 .setMessage("Standard action perform returned {} forward path")
226 .addArgument(() -> result == null ? "NULL" : result.getPath())
227 .log();
228 return (result);
229
230 }
231
232
233
234 protected boolean processForward(HttpServletRequest request,
235 HttpServletResponse response,
236 ActionMapping mapping)
237 throws IOException, ServletException {
238
239 log.trace("Performing standard forward handling");
240 boolean result = super.processForward
241 (request, response, mapping);
242 log.debug("Standard forward handling returned {}", result);
243 return (result);
244
245 }
246
247
248
249 protected void processForwardConfig(HttpServletRequest request,
250 HttpServletResponse response,
251 ForwardConfig forward)
252 throws IOException, ServletException {
253
254 log.trace("Performing standard forward config handling");
255 super.processForwardConfig(request, response, forward);
256 log.debug("Standard forward config handling completed");
257
258 }
259
260
261
262 protected boolean processInclude(HttpServletRequest request,
263 HttpServletResponse response,
264 ActionMapping mapping)
265 throws IOException, ServletException {
266
267 log.trace("Performing standard include handling");
268 boolean result = super.processInclude
269 (request, response, mapping);
270 log.debug("Standard include handling returned {}", result);
271 return (result);
272
273 }
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288 protected String processPath(HttpServletRequest request,
289 HttpServletResponse response)
290 throws IOException {
291
292
293 ActionEvent event = (ActionEvent)
294 request.getAttribute(Constants.ACTION_EVENT_KEY);
295
296
297 if (event == null) {
298 log.trace("Performing standard processPath() processing");
299 return (super.processPath(request, response));
300 }
301
302
303 UIComponent component = event.getComponent();
304 log.trace("Locating form parent for command component {}",
305 event.getComponent());
306 while (!(component instanceof FormComponent)) {
307 component = component.getParent();
308 if (component == null) {
309 log.warn("Command component was not nested in a Struts form!");
310 return (null);
311 }
312 }
313 String action = ((FormComponent) component).getAction();
314 log.debug("Returning selected path of '{}'", action);
315 return action;
316
317 }
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335 protected void processPopulate(HttpServletRequest request,
336 HttpServletResponse response,
337 ActionForm form,
338 ActionMapping mapping)
339 throws ServletException {
340
341
342 ActionEvent event = (ActionEvent)
343 request.getAttribute(Constants.ACTION_EVENT_KEY);
344
345
346 if (event == null) {
347 log.trace("Performing standard processPopulate() processing");
348 super.processPopulate(request, response, form, mapping);
349 return;
350 }
351
352
353
354 log.trace("Faces request, so no processPopulate() processing");
355 UIComponent source = event.getComponent();
356 if (source instanceof UICommand) {
357 if ("cancel".equals(((UICommand) source).getId())) {
358 log.trace("Faces request with cancel button pressed");
359 request.setAttribute(Globals.CANCEL_KEY, Boolean.TRUE);
360 }
361 }
362
363 }
364
365
366
367 protected boolean processValidate(HttpServletRequest request,
368 HttpServletResponse response,
369 ActionForm form,
370 ActionMapping mapping)
371 throws IOException, ServletException, InvalidCancelException {
372
373 log.trace("Performing standard validation");
374 boolean result = super.processValidate
375 (request, response, form, mapping);
376 log.debug("Standard validation processing returned {}", result);
377 return (result);
378
379 }
380
381
382
383
384
385
386
387
388 private String getLifecycleId()
389 {
390 String lifecycleId = this.servlet.getServletContext().getInitParameter(LIFECYCLE_ID_ATTR);
391 return lifecycleId != null ? lifecycleId : LifecycleFactory.DEFAULT_LIFECYCLE;
392 }
393
394
395
396
397
398
399
400 private boolean isStrutsRequest(String uri) {
401
402 int question = uri.indexOf("?");
403 if (question >= 0) {
404 uri = uri.substring(0, question);
405 }
406 String mapping = (String)
407 servlet.getServletContext().getAttribute(Globals.SERVLET_KEY);
408 if (mapping == null) {
409 return (false);
410 } else if (mapping.startsWith("*.")) {
411 return (uri.endsWith(mapping.substring(1)));
412 } else if (mapping.endsWith("/*")) {
413 return (uri.startsWith(mapping.substring(0, mapping.length() - 2)));
414 } else {
415 return (false);
416 }
417
418 }
419 }