1
22
23 package com.liferay.portal.struts;
24
25 import com.liferay.portal.kernel.portlet.LiferayPortletURL;
26 import com.liferay.portal.kernel.security.permission.ActionKeys;
27 import com.liferay.portal.kernel.security.permission.PermissionChecker;
28 import com.liferay.portal.kernel.util.JavaConstants;
29 import com.liferay.portal.kernel.util.StringPool;
30 import com.liferay.portal.kernel.util.Validator;
31 import com.liferay.portal.model.Layout;
32 import com.liferay.portal.model.Portlet;
33 import com.liferay.portal.model.User;
34 import com.liferay.portal.security.auth.PrincipalException;
35 import com.liferay.portal.service.PortletLocalServiceUtil;
36 import com.liferay.portal.service.permission.PortletPermissionUtil;
37 import com.liferay.portal.theme.ThemeDisplay;
38 import com.liferay.portal.util.PortalUtil;
39 import com.liferay.portal.util.PropsValues;
40 import com.liferay.portal.util.WebKeys;
41 import com.liferay.portlet.ActionResponseImpl;
42 import com.liferay.portlet.PortletConfigImpl;
43 import com.liferay.portlet.PortletRequestDispatcherImpl;
44
45 import java.io.IOException;
46
47 import java.lang.reflect.Constructor;
48
49 import javax.portlet.ActionRequest;
50 import javax.portlet.ActionResponse;
51 import javax.portlet.PortletException;
52 import javax.portlet.RenderRequest;
53 import javax.portlet.RenderResponse;
54
55 import javax.servlet.ServletException;
56 import javax.servlet.http.HttpServletRequest;
57 import javax.servlet.http.HttpServletResponse;
58
59 import org.apache.commons.logging.Log;
60 import org.apache.commons.logging.LogFactory;
61 import org.apache.struts.Globals;
62 import org.apache.struts.action.Action;
63 import org.apache.struts.action.ActionErrors;
64 import org.apache.struts.action.ActionForm;
65 import org.apache.struts.action.ActionForward;
66 import org.apache.struts.action.ActionMapping;
67 import org.apache.struts.action.ActionServlet;
68 import org.apache.struts.config.ForwardConfig;
69 import org.apache.struts.config.ModuleConfig;
70 import org.apache.struts.tiles.TilesRequestProcessor;
71
72
78 public class PortletRequestProcessor extends TilesRequestProcessor {
79
80 public static PortletRequestProcessor getInstance(
81 ActionServlet servlet, ModuleConfig config)
82 throws ServletException {
83
84 try {
85 String className = PropsValues.STRUTS_PORTLET_REQUEST_PROCESSOR;
86
87 Class clazz = Class.forName(className);
88
89 Constructor constructor = clazz.getConstructor(
90 new Class[] {
91 ActionServlet.class, ModuleConfig.class
92 }
93 );
94
95 PortletRequestProcessor portletReqProcessor =
96 (PortletRequestProcessor)constructor.newInstance(
97 new Object[] {
98 servlet, config
99 }
100 );
101
102 return portletReqProcessor;
103 }
104 catch (Exception e) {
105 _log.error(e);
106
107 return new PortletRequestProcessor(servlet, config);
108 }
109 }
110
111 public PortletRequestProcessor(ActionServlet servlet, ModuleConfig config)
112 throws ServletException {
113
114 init(servlet, config);
115 }
116
117 public void process(RenderRequest req, RenderResponse res)
118 throws IOException, ServletException {
119
120 HttpServletRequest httpReq = PortalUtil.getHttpServletRequest(req);
121 HttpServletResponse httpRes = PortalUtil.getHttpServletResponse(res);
122
123 process(httpReq, httpRes);
124 }
125
126 public void process(ActionRequest req, ActionResponse res, String path)
127 throws IOException, ServletException {
128
129 ActionResponseImpl resImpl = (ActionResponseImpl)res;
130
131 HttpServletRequest httpReq = PortalUtil.getHttpServletRequest(req);
132 HttpServletResponse httpRes = PortalUtil.getHttpServletResponse(res);
133
134 ActionMapping mapping = processMapping(httpReq, httpRes, path);
135
136 if (mapping == null) {
137 return;
138 }
139
140 if (!processRoles(httpReq, httpRes, mapping, true)) {
141 return;
142 }
143
144 ActionForm form = processActionForm(httpReq, httpRes, mapping);
145
146 processPopulate(httpReq, httpRes, form, mapping);
147
148 if (!processValidateAction(httpReq, httpRes, form, mapping)) {
149 return;
150 }
151
152 PortletAction action =
153 (PortletAction)processActionCreate(httpReq, httpRes, mapping);
154
155 if (action == null) {
156 return;
157 }
158
159 PortletConfigImpl portletConfig = (PortletConfigImpl)req.getAttribute(
160 JavaConstants.JAVAX_PORTLET_CONFIG);
161
162 try {
163 if (action.isCheckMethodOnProcessAction()) {
164 if (!PortalUtil.isMethodPost(req)) {
165 String currentURL = PortalUtil.getCurrentURL(req);
166
167 throw new PrincipalException(currentURL);
168 }
169 }
170
171 action.processAction(mapping, form, portletConfig, req, res);
172 }
173 catch (Exception e) {
174 String exceptionId =
175 WebKeys.PORTLET_STRUTS_EXCEPTION + StringPool.PERIOD +
176 portletConfig.getPortletId();
177
178 req.setAttribute(exceptionId, e);
179 }
180
181 String forward =
182 (String)req.getAttribute(PortletAction.getForwardKey(req));
183
184 if (forward != null) {
185 String queryString = StringPool.BLANK;
186
187 int pos = forward.indexOf("?");
188
189 if (pos != -1) {
190 queryString = forward.substring(pos + 1, forward.length());
191 forward = forward.substring(0, pos);
192 }
193
194 ActionForward actionForward = mapping.findForward(forward);
195
196 if ((actionForward != null) && (actionForward.getRedirect())) {
197 String forwardPath = actionForward.getPath();
198
199 if (forwardPath.startsWith("/")) {
200 LiferayPortletURL forwardURL =
201 (LiferayPortletURL)resImpl.createRenderURL();
202
203 forwardURL.setParameter("struts_action", forwardPath);
204
205 StrutsURLEncoder.setParameters(forwardURL, queryString);
206
207 forwardPath = forwardURL.toString();
208 }
209
210 res.sendRedirect(forwardPath);
211 }
212 }
213 }
214
215 protected ActionForm processActionForm(
216 HttpServletRequest req, HttpServletResponse res,
217 ActionMapping mapping) {
218
219 ActionForm form = super.processActionForm(req, res, mapping);
220
221 if (form instanceof InitializableActionForm) {
222 InitializableActionForm initForm = (InitializableActionForm)form;
223
224 initForm.init(req, res, mapping);
225 }
226
227 return form;
228 }
229
230 protected ActionForward processActionPerform(
231 HttpServletRequest req, HttpServletResponse res, Action action,
232 ActionForm form, ActionMapping mapping)
233 throws IOException, ServletException {
234
235 PortletConfigImpl portletConfig = (PortletConfigImpl)req.getAttribute(
236 JavaConstants.JAVAX_PORTLET_CONFIG);
237
238 String exceptionId =
239 WebKeys.PORTLET_STRUTS_EXCEPTION + StringPool.PERIOD +
240 portletConfig.getPortletId();
241
242 Exception e = (Exception)req.getAttribute(exceptionId);
243
244 if (e != null) {
245 return processException(req, res, e, form, mapping);
246 }
247 else {
248 return super.processActionPerform(req, res, action, form, mapping);
249 }
250 }
251
252 protected void processForwardConfig(
253 HttpServletRequest req, HttpServletResponse res,
254 ForwardConfig forward)
255 throws IOException, ServletException {
256
257 if (forward == null) {
258 _log.error("Forward does not exist");
259 }
260 else {
261
262
265 if (forward.getPath().equals(ActionConstants.COMMON_NULL)) {
266 return;
267 }
268 }
269
270 super.processForwardConfig(req, res, forward);
271 }
272
273 public ActionMapping processMapping(
274 HttpServletRequest req, HttpServletResponse res, String path)
275 throws IOException {
276
277 if (path == null) {
278 return null;
279 }
280
281 return super.processMapping(req, res, path);
282 }
283
284 protected boolean processRoles(
285 HttpServletRequest req, HttpServletResponse res,
286 ActionMapping mapping)
287 throws IOException, ServletException {
288
289 return processRoles(req, res, mapping, false);
290 }
291
292 protected boolean processRoles(
293 HttpServletRequest req, HttpServletResponse res,
294 ActionMapping mapping, boolean action)
295 throws IOException, ServletException {
296
297 User user = null;
298
299 try {
300 user = PortalUtil.getUser(req);
301 }
302 catch (Exception e) {
303 }
304
305 if (user == null) {
306 return true;
307 }
308
309 String path = mapping.getPath();
310
311 try {
312 PortletConfigImpl portletConfig =
313 (PortletConfigImpl)req.getAttribute(
314 JavaConstants.JAVAX_PORTLET_CONFIG);
315
316 Portlet portlet = PortletLocalServiceUtil.getPortletById(
317 user.getCompanyId(), portletConfig.getPortletId());
318
319 if (portlet == null) {
320 return false;
321 }
322
323 String strutsPath = path.substring(
324 1, path.lastIndexOf(StringPool.SLASH));
325
326 if (!strutsPath.equals(portlet.getStrutsPath())) {
327 if (_log.isWarnEnabled()) {
328 _log.warn(
329 "The struts path " + strutsPath + " does not belong " +
330 "to portlet " + portlet.getPortletId() + ". " +
331 "Check the definition in liferay-portlet.xml");
332 }
333
334 throw new PrincipalException();
335 }
336 else if (portlet.isActive()) {
337 ThemeDisplay themeDisplay =
338 (ThemeDisplay)req.getAttribute(WebKeys.THEME_DISPLAY);
339
340 Layout layout = themeDisplay.getLayout();
341 PermissionChecker permissionChecker =
342 themeDisplay.getPermissionChecker();
343
344 if (!PortletPermissionUtil.contains(
345 permissionChecker, layout.getPlid(), portlet,
346 ActionKeys.VIEW)) {
347
348 throw new PrincipalException();
349 }
350 }
351 else if (!portlet.isActive()) {
352 ForwardConfig forwardConfig =
353 mapping.findForward(_PATH_PORTAL_PORTLET_INACTIVE);
354
355 if (!action) {
356 processForwardConfig(req, res, forwardConfig);
357 }
358
359 return false;
360 }
361 }
362 catch (Exception e) {
363 if (_log.isWarnEnabled()) {
364 _log.warn(e.getMessage());
365 }
366
367 ForwardConfig forwardConfig =
368 mapping.findForward(_PATH_PORTAL_PORTLET_ACCESS_DENIED);
369
370 if (!action) {
371 processForwardConfig(req, res, forwardConfig);
372 }
373
374 return false;
375 }
376
377 return true;
378 }
379
380 protected boolean processValidateAction(
381 HttpServletRequest req, HttpServletResponse res, ActionForm form,
382 ActionMapping mapping)
383 throws IOException, ServletException {
384
385 if (form == null) {
386 return true;
387 }
388
389 if (req.getAttribute(Globals.CANCEL_KEY) != null) {
390 return true;
391 }
392
393 if (!mapping.getValidate()) {
394 return true;
395 }
396
397 ActionErrors errors = form.validate(mapping, req);
398
399 if ((errors == null) || errors.isEmpty()) {
400 return true;
401 }
402
403 if (form.getMultipartRequestHandler() != null) {
404 form.getMultipartRequestHandler().rollback();
405 }
406
407 String input = mapping.getInput();
408
409 if (input == null) {
410 _log.error("Validation failed but no input form is available");
411
412 return false;
413 }
414
415 req.setAttribute(Globals.ERROR_KEY, errors);
416
417
420 req.setAttribute(PortletAction.getForwardKey(req), input);
421
422 return false;
423 }
424
425 protected void doForward(
426 String uri, HttpServletRequest req, HttpServletResponse res)
427 throws IOException, ServletException {
428
429 doInclude(uri, req, res);
430 }
431
432 protected void doInclude(
433 String uri, HttpServletRequest req, HttpServletResponse res)
434 throws IOException, ServletException {
435
436 PortletConfigImpl portletConfig = (PortletConfigImpl)req.getAttribute(
437 JavaConstants.JAVAX_PORTLET_CONFIG);
438
439 RenderRequest renderRequest = (RenderRequest)req.getAttribute(
440 JavaConstants.JAVAX_PORTLET_REQUEST);
441
442 RenderResponse renderResponse = (RenderResponse)req.getAttribute(
443 JavaConstants.JAVAX_PORTLET_RESPONSE);
444
445 PortletRequestDispatcherImpl prd = (PortletRequestDispatcherImpl)
446 portletConfig.getPortletContext().getRequestDispatcher(
447 StrutsUtil.TEXT_HTML_DIR + uri);
448
449 try {
450 if (prd == null) {
451 _log.error(uri + " is not a valid include");
452 }
453 else {
454 prd.include(renderRequest, renderResponse, true);
455 }
456 }
457 catch (PortletException pe) {
458 Throwable cause = pe.getCause();
459
460 if (cause instanceof ServletException) {
461 throw (ServletException)cause;
462 }
463 else {
464 _log.error(cause, cause);
465 }
466 }
467 }
468
469 protected HttpServletRequest processMultipart(HttpServletRequest req) {
470
471
473 return req;
474 }
475
476 protected String processPath(
477 HttpServletRequest req, HttpServletResponse res)
478 throws IOException {
479
480 String path = req.getParameter("struts_action");
481
482 if (_log.isDebugEnabled()) {
483 _log.debug("Getting request parameter path " + path);
484 }
485
486 if (Validator.isNull(path)) {
487 if (_log.isDebugEnabled()) {
488 _log.debug("Getting request attribute path " + path);
489 }
490
491 path = (String)req.getAttribute(WebKeys.PORTLET_STRUTS_ACTION);
492 }
493
494 if (path == null) {
495 PortletConfigImpl portletConfig =
496 (PortletConfigImpl)req.getAttribute(
497 JavaConstants.JAVAX_PORTLET_CONFIG);
498
499 _log.error(
500 portletConfig.getPortletName() +
501 " does not have any paths specified");
502 }
503 else {
504 if (_log.isDebugEnabled()) {
505 _log.debug("Processing path " + path);
506 }
507 }
508
509 return path;
510 }
511
512 private static final String _PATH_PORTAL_PORTLET_ACCESS_DENIED =
513 "/portal/portlet_access_denied";
514
515 private static final String _PATH_PORTAL_PORTLET_INACTIVE =
516 "/portal/portlet_inactive";
517
518 private static Log _log = LogFactory.getLog(PortletRequestProcessor.class);
519
520 }