1
22
23 package com.liferay.portal.action;
24
25 import com.liferay.portal.kernel.language.LanguageUtil;
26 import com.liferay.portal.kernel.portlet.PortletModeFactory;
27 import com.liferay.portal.kernel.portlet.WindowStateFactory;
28 import com.liferay.portal.kernel.servlet.BrowserSniffer;
29 import com.liferay.portal.kernel.servlet.HttpHeaders;
30 import com.liferay.portal.kernel.servlet.StringServletResponse;
31 import com.liferay.portal.kernel.util.ContentTypes;
32 import com.liferay.portal.kernel.util.HttpUtil;
33 import com.liferay.portal.kernel.util.JavaConstants;
34 import com.liferay.portal.kernel.util.ParamUtil;
35 import com.liferay.portal.kernel.util.StringPool;
36 import com.liferay.portal.kernel.util.Validator;
37 import com.liferay.portal.model.Layout;
38 import com.liferay.portal.model.LayoutTypePortlet;
39 import com.liferay.portal.model.Portlet;
40 import com.liferay.portal.model.PortletPreferencesIds;
41 import com.liferay.portal.model.User;
42 import com.liferay.portal.model.impl.LayoutImpl;
43 import com.liferay.portal.service.PortletLocalServiceUtil;
44 import com.liferay.portal.service.PortletPreferencesLocalServiceUtil;
45 import com.liferay.portal.struts.ActionConstants;
46 import com.liferay.portal.struts.StrutsUtil;
47 import com.liferay.portal.theme.ThemeDisplay;
48 import com.liferay.portal.util.PortalUtil;
49 import com.liferay.portal.util.PropsValues;
50 import com.liferay.portal.util.WebKeys;
51 import com.liferay.portlet.ActionRequestFactory;
52 import com.liferay.portlet.ActionRequestImpl;
53 import com.liferay.portlet.ActionResponseFactory;
54 import com.liferay.portlet.ActionResponseImpl;
55 import com.liferay.portlet.EventRequestFactory;
56 import com.liferay.portlet.EventRequestImpl;
57 import com.liferay.portlet.EventResponseFactory;
58 import com.liferay.portlet.EventResponseImpl;
59 import com.liferay.portlet.InvokerPortlet;
60 import com.liferay.portlet.PortletConfigFactory;
61 import com.liferay.portlet.PortletInstanceFactory;
62 import com.liferay.portlet.PortletPreferencesFactoryUtil;
63 import com.liferay.portlet.PortletRequestImpl;
64 import com.liferay.portlet.PortletURLImpl;
65 import com.liferay.portlet.RenderParametersPool;
66 import com.liferay.portlet.RenderRequestFactory;
67 import com.liferay.portlet.RenderRequestImpl;
68 import com.liferay.portlet.RenderResponseFactory;
69 import com.liferay.portlet.RenderResponseImpl;
70 import com.liferay.portlet.ResourceRequestFactory;
71 import com.liferay.portlet.ResourceRequestImpl;
72 import com.liferay.portlet.ResourceResponseFactory;
73 import com.liferay.portlet.ResourceResponseImpl;
74 import com.liferay.portlet.StateAwareResponseImpl;
75 import com.liferay.util.MapUtil;
76 import com.liferay.util.servlet.ServletResponseUtil;
77 import com.liferay.util.servlet.UploadServletRequest;
78
79 import java.io.ByteArrayInputStream;
80 import java.io.InputStream;
81
82 import java.util.HashMap;
83 import java.util.List;
84 import java.util.Map;
85
86 import javax.portlet.Event;
87 import javax.portlet.PortletConfig;
88 import javax.portlet.PortletContext;
89 import javax.portlet.PortletException;
90 import javax.portlet.PortletMode;
91 import javax.portlet.PortletPreferences;
92 import javax.portlet.PortletRequest;
93 import javax.portlet.PortletResponse;
94 import javax.portlet.PortletURL;
95 import javax.portlet.UnavailableException;
96 import javax.portlet.WindowState;
97
98 import javax.servlet.RequestDispatcher;
99 import javax.servlet.ServletContext;
100 import javax.servlet.http.HttpServletRequest;
101 import javax.servlet.http.HttpServletResponse;
102 import javax.servlet.http.HttpSession;
103 import javax.servlet.jsp.PageContext;
104
105 import javax.xml.namespace.QName;
106
107 import org.apache.commons.logging.Log;
108 import org.apache.commons.logging.LogFactory;
109 import org.apache.struts.action.Action;
110 import org.apache.struts.action.ActionForm;
111 import org.apache.struts.action.ActionForward;
112 import org.apache.struts.action.ActionMapping;
113
114
120 public class LayoutAction extends Action {
121
122 public ActionForward execute(
123 ActionMapping mapping, ActionForm form, HttpServletRequest req,
124 HttpServletResponse res)
125 throws Exception {
126
127 ThemeDisplay themeDisplay = (ThemeDisplay)req.getAttribute(
128 WebKeys.THEME_DISPLAY);
129
130 Layout layout = themeDisplay.getLayout();
131
132 Boolean layoutDefault = (Boolean)req.getAttribute(
133 WebKeys.LAYOUT_DEFAULT);
134
135 if ((layoutDefault != null) && (layoutDefault.booleanValue())) {
136 Layout requestedLayout =
137 (Layout)req.getAttribute(WebKeys.REQUESTED_LAYOUT);
138
139 if (requestedLayout != null) {
140 String redirectParam = "redirect";
141
142 if (Validator.isNotNull(PropsValues.AUTH_LOGIN_PORTLET_NAME) &&
143 Validator.isNotNull(PropsValues.AUTH_LOGIN_URL)) {
144
145 redirectParam =
146 PortalUtil.getPortletNamespace(
147 PropsValues.AUTH_LOGIN_PORTLET_NAME) +
148 redirectParam;
149 }
150
151 String url = PortalUtil.getLayoutURL(
152 requestedLayout, themeDisplay);
153
154 String redirect = HttpUtil.addParameter(
155 themeDisplay.getURLSignIn(), redirectParam, url);
156
157 if (_log.isDebugEnabled()) {
158 _log.debug("Redirect requested layout to " + redirect);
159 }
160
161 res.sendRedirect(redirect);
162 }
163 else {
164 String redirect = PortalUtil.getLayoutURL(layout, themeDisplay);
165
166 if (_log.isDebugEnabled()) {
167 _log.debug("Redirect default layout to " + redirect);
168 }
169
170 res.sendRedirect(redirect);
171 }
172
173 return null;
174 }
175
176 long plid = ParamUtil.getLong(req, "p_l_id");
177
178 if (plid > 0) {
179 return processLayout(mapping, req, res, plid);
180 }
181 else {
182 try {
183 forwardLayout(req);
184
185 return mapping.findForward(ActionConstants.COMMON_FORWARD);
186 }
187 catch (Exception e) {
188 req.setAttribute(PageContext.EXCEPTION, e);
189
190 return mapping.findForward(ActionConstants.COMMON_ERROR);
191 }
192 }
193 }
194
195 protected void forwardLayout(HttpServletRequest req) throws Exception {
196 Layout layout = (Layout)req.getAttribute(WebKeys.LAYOUT);
197 long plid = LayoutImpl.DEFAULT_PLID;
198 String layoutFriendlyURL = null;
199
200 ThemeDisplay themeDisplay =
201 (ThemeDisplay)req.getAttribute(WebKeys.THEME_DISPLAY);
202
203 if (layout != null) {
204 plid = layout.getPlid();
205 layoutFriendlyURL =
206 PortalUtil.getLayoutFriendlyURL(layout, themeDisplay);
207 }
208
209 String forwardURL = layoutFriendlyURL;
210
211 if (Validator.isNull(forwardURL)) {
212 forwardURL =
213 themeDisplay.getPathMain() + "/portal/layout?p_l_id=" + plid;
214
215 if (Validator.isNotNull(themeDisplay.getDoAsUserId())) {
216 forwardURL = HttpUtil.addParameter(
217 forwardURL, "doAsUserId", themeDisplay.getDoAsUserId());
218 }
219 }
220
221 if (_log.isDebugEnabled()) {
222 _log.debug("Forward layout to " + forwardURL);
223 }
224
225 req.setAttribute(WebKeys.FORWARD_URL, forwardURL);
226 }
227
228 protected void includeLayoutContent(
229 HttpServletRequest req, HttpServletResponse res,
230 ThemeDisplay themeDisplay, Layout layout)
231 throws Exception {
232
233 ServletContext ctx = (ServletContext)req.getAttribute(WebKeys.CTX);
234
235 String path = StrutsUtil.TEXT_HTML_DIR;
236
237 if (BrowserSniffer.is_wap_xhtml(req)) {
238 path = StrutsUtil.TEXT_WAP_DIR;
239 }
240
241
243 if (themeDisplay.isStateExclusive() ||
244 Validator.isNotNull(ParamUtil.getString(req, "p_p_id"))) {
245
246 path += "/portal/layout/view/portlet.jsp";
247 }
248 else {
249 path += PortalUtil.getLayoutViewPage(layout);
250 }
251
252 RequestDispatcher rd = ctx.getRequestDispatcher(path);
253
254 StringServletResponse stringServletRes = new StringServletResponse(res);
255
256 rd.include(req, stringServletRes);
257
258 req.setAttribute(WebKeys.LAYOUT_CONTENT, stringServletRes.getString());
259 }
260
261 protected void processEvent(
262 PortletRequestImpl portletReqImpl,
263 StateAwareResponseImpl stateAwareResImpl, Portlet portlet,
264 List<Portlet> portlets, Event event)
265 throws Exception {
266
267 HttpServletRequest req = portletReqImpl.getHttpServletRequest();
268 HttpServletResponse res = stateAwareResImpl.getHttpServletResponse();
269
270 String portletId = portlet.getPortletId();
271
272 ServletContext ctx = (ServletContext)req.getAttribute(WebKeys.CTX);
273
274 InvokerPortlet invokerPortlet = PortletInstanceFactory.create(
275 portlet, ctx);
276
277 PortletConfig portletConfig = PortletConfigFactory.create(portlet, ctx);
278 PortletContext portletCtx = portletConfig.getPortletContext();
279
280 WindowState windowState = portletReqImpl.getWindowState();
281 PortletMode portletMode = portletReqImpl.getPortletMode();
282
283 User user = stateAwareResImpl.getUser();
284 Layout layout = stateAwareResImpl.getLayout();
285
286 PortletPreferences portletPreferences =
287 portletReqImpl.getPreferencesImpl();
288
289 EventRequestImpl eventReqImpl = EventRequestFactory.create(
290 req, portlet, invokerPortlet, portletCtx, windowState,
291 portletMode, portletPreferences, layout.getPlid());
292
293 eventReqImpl.setEvent(event);
294
295 EventResponseImpl eventResImpl = EventResponseFactory.create(
296 eventReqImpl, res, portletId, user, layout, windowState,
297 portletMode);
298
299 eventReqImpl.defineObjects(portletConfig, eventResImpl);
300
301 try {
302 try {
303 invokerPortlet.processEvent(eventReqImpl, eventResImpl);
304
305 if (eventResImpl.isCalledSetRenderParameter()) {
306 Map<String, String[]> renderParameterMap =
307 new HashMap<String, String[]>();
308
309 MapUtil.copy(
310 eventResImpl.getRenderParameterMap(),
311 renderParameterMap);
312
313 RenderParametersPool.put(
314 req, layout.getPlid(), portletId, renderParameterMap);
315 }
316 }
317 catch (UnavailableException ue) {
318 throw ue;
319 }
320 catch (PortletException pe) {
321 eventResImpl.setWindowState(windowState);
322 eventResImpl.setPortletMode(portletMode);
323 }
324
325 processEvents(eventReqImpl, eventResImpl, portlets);
326 }
327 finally {
328 EventRequestFactory.recycle(eventReqImpl);
329 EventResponseFactory.recycle(eventResImpl);
330 }
331 }
332
333 protected void processEvents(
334 PortletRequestImpl portletReqImpl,
335 StateAwareResponseImpl stateAwareResImpl, List<Portlet> portlets)
336 throws Exception {
337
338 List<Event> events = stateAwareResImpl.getEvents();
339
340 if (events.size() == 0) {
341 return;
342 }
343
344 for (Event event : events) {
345 QName qName = event.getQName();
346
347 for (Portlet portlet : portlets) {
348 QName processingQName = portlet.getProcessingEvent(
349 qName.getNamespaceURI(), qName.getLocalPart());
350
351 if (processingQName != null) {
352 processEvent(
353 portletReqImpl, stateAwareResImpl, portlet, portlets,
354 event);
355 }
356 }
357 }
358 }
359
360 protected ActionForward processLayout(
361 ActionMapping mapping, HttpServletRequest req,
362 HttpServletResponse res, long plid)
363 throws Exception {
364
365 ThemeDisplay themeDisplay = (ThemeDisplay)req.getAttribute(
366 WebKeys.THEME_DISPLAY);
367
368 try {
369 Layout layout = themeDisplay.getLayout();
370
371 boolean resetLayout = ParamUtil.getBoolean(
372 req, "p_l_reset", PropsValues.LAYOUT_DEFAULT_P_L_RESET);
373
374 if (!PropsValues.TCK_URL && resetLayout) {
375 RenderParametersPool.clear(req, plid);
376 }
377
378 if (themeDisplay.isLifecycleAction()) {
379 Portlet portlet = processPortletRequest(
380 req, res, PortletRequest.ACTION_PHASE);
381
382 if (portlet != null) {
383 ActionResponseImpl actionResImpl =
384 (ActionResponseImpl)req.getAttribute(
385 JavaConstants.JAVAX_PORTLET_RESPONSE);
386
387 String redirectLocation =
388 actionResImpl.getRedirectLocation();
389
390 if (Validator.isNotNull(redirectLocation)) {
391 res.sendRedirect(redirectLocation);
392
393 return null;
394 }
395
396 if (portlet.isActionURLRedirect()) {
397 redirectActionURL(
398 req, res, actionResImpl, portlet);
399
400 return null;
401 }
402 }
403 }
404 else if (themeDisplay.isLifecycleRender()) {
405 processPortletRequest(req, res, PortletRequest.RENDER_PHASE);
406 }
407
408 if (themeDisplay.isLifecycleResource()) {
409 processPortletRequest(req, res, PortletRequest.RESOURCE_PHASE);
410
411 return null;
412 }
413 else {
414 if (layout != null) {
415
416
420 includeLayoutContent(req, res, themeDisplay, layout);
421
422 if (themeDisplay.isStateExclusive()) {
423 renderExclusive(req, res, themeDisplay);
424
425 return null;
426 }
427 }
428
429 return mapping.findForward("portal.layout");
430 }
431 }
432 catch (Exception e) {
433 req.setAttribute(PageContext.EXCEPTION, e);
434
435 return mapping.findForward(ActionConstants.COMMON_ERROR);
436 }
437 finally {
438 PortletRequest portletReq = (PortletRequest)req.getAttribute(
439 JavaConstants.JAVAX_PORTLET_REQUEST);
440
441 try {
442 if (portletReq != null) {
443 if (themeDisplay.isLifecycleAction()) {
444 ActionRequestImpl actionReqImpl =
445 (ActionRequestImpl)portletReq;
446
447 ActionRequestFactory.recycle(actionReqImpl);
448 }
449 else if (themeDisplay.isLifecycleRender()) {
450 RenderRequestImpl renderReqImpl =
451 (RenderRequestImpl)portletReq;
452
453 RenderRequestFactory.recycle(renderReqImpl);
454 }
455 else if (themeDisplay.isLifecycleResource()) {
456 ResourceRequestImpl resourceReqImpl =
457 (ResourceRequestImpl)portletReq;
458
459 ResourceRequestFactory.recycle(resourceReqImpl);
460 }
461 }
462 }
463 catch (Exception e) {
464 _log.error(e);
465 }
466
467 req.removeAttribute(JavaConstants.JAVAX_PORTLET_REQUEST);
468
469 PortletResponse portletRes = (PortletResponse)req.getAttribute(
470 JavaConstants.JAVAX_PORTLET_RESPONSE);
471
472 try {
473 if (portletRes != null) {
474 if (themeDisplay.isLifecycleAction()) {
475 ActionResponseImpl actionResImpl =
476 (ActionResponseImpl)portletRes;
477
478 ActionResponseFactory.recycle(actionResImpl);
479 }
480 else if (themeDisplay.isLifecycleRender()) {
481 RenderResponseImpl renderResImpl =
482 (RenderResponseImpl)portletRes;
483
484 RenderResponseFactory.recycle(renderResImpl);
485 }
486 else if (themeDisplay.isLifecycleResource()) {
487 ResourceResponseImpl resourceResImpl =
488 (ResourceResponseImpl)portletRes;
489
490 ResourceResponseFactory.recycle(resourceResImpl);
491 }
492 }
493 }
494 catch (Exception e) {
495 _log.error(e);
496 }
497
498 req.removeAttribute(JavaConstants.JAVAX_PORTLET_RESPONSE);
499 }
500 }
501
502 protected Portlet processPortletRequest(
503 HttpServletRequest req, HttpServletResponse res, String lifecycle)
504 throws Exception {
505
506 HttpSession ses = req.getSession();
507
508 long companyId = PortalUtil.getCompanyId(req);
509 User user = PortalUtil.getUser(req);
510 Layout layout = (Layout)req.getAttribute(WebKeys.LAYOUT);
511
512 String portletId = ParamUtil.getString(req, "p_p_id");
513
514 Portlet portlet = PortletLocalServiceUtil.getPortletById(
515 companyId, portletId);
516
517 if (portlet == null) {
518 return null;
519 }
520
521 ServletContext ctx = (ServletContext)req.getAttribute(WebKeys.CTX);
522
523 InvokerPortlet invokerPortlet = PortletInstanceFactory.create(
524 portlet, ctx);
525
526 if (user != null) {
527 InvokerPortlet.clearResponse(
528 ses, layout.getPrimaryKey(), portletId,
529 LanguageUtil.getLanguageId(req));
530 }
531
532 PortletConfig portletConfig = PortletConfigFactory.create(portlet, ctx);
533 PortletContext portletCtx = portletConfig.getPortletContext();
534
535 WindowState windowState = WindowStateFactory.getWindowState(
536 ParamUtil.getString(req, "p_p_state"));
537
538 PortletMode portletMode = PortletModeFactory.getPortletMode(
539 ParamUtil.getString(req, "p_p_mode"));
540
541 PortletPreferencesIds portletPreferencesIds =
542 PortletPreferencesFactoryUtil.getPortletPreferencesIds(
543 req, portletId);
544
545 PortletPreferences portletPreferences =
546 PortletPreferencesLocalServiceUtil.getPreferences(
547 portletPreferencesIds);
548
549 if (lifecycle.equals(PortletRequest.ACTION_PHASE)) {
550 String contentType = req.getHeader(HttpHeaders.CONTENT_TYPE);
551
552 if (_log.isDebugEnabled()) {
553 _log.debug("Content type " + contentType);
554 }
555
556 UploadServletRequest uploadReq = null;
557
558 try {
559 if ((contentType != null) &&
560 (contentType.startsWith(
561 ContentTypes.MULTIPART_FORM_DATA))) {
562
563 if (!invokerPortlet.getPortletConfig().isWARFile() ||
564 invokerPortlet.isStrutsPortlet()) {
565
566 uploadReq = new UploadServletRequest(req);
567
568 req = uploadReq;
569 }
570 }
571
572 ActionRequestImpl actionReqImpl = ActionRequestFactory.create(
573 req, portlet, invokerPortlet, portletCtx, windowState,
574 portletMode, portletPreferences, layout.getPlid());
575
576 ActionResponseImpl actionResImpl = ActionResponseFactory.create(
577 actionReqImpl, res, portletId, user, layout, windowState,
578 portletMode);
579
580 actionReqImpl.defineObjects(portletConfig, actionResImpl);
581
582 invokerPortlet.processAction(actionReqImpl, actionResImpl);
583
584 RenderParametersPool.put(
585 req, layout.getPlid(), portletId,
586 actionResImpl.getRenderParameterMap());
587
588 if (actionResImpl.getEvents().size() > 0) {
589 if (layout.getType().equals(LayoutImpl.TYPE_PORTLET)) {
590 LayoutTypePortlet layoutTypePortlet =
591 (LayoutTypePortlet)layout.getLayoutType();
592
593 List<Portlet> portlets =
594 layoutTypePortlet.getPortlets();
595
596 processEvents(actionReqImpl, actionResImpl, portlets);
597
598 actionReqImpl.defineObjects(
599 portletConfig, actionResImpl);
600 }
601 }
602 }
603 finally {
604 if (uploadReq != null) {
605 uploadReq.cleanUp();
606 }
607 }
608 }
609 else if (lifecycle.equals(PortletRequest.RENDER_PHASE) ||
610 lifecycle.equals(PortletRequest.RESOURCE_PHASE)) {
611
612 PortalUtil.updateWindowState(
613 portletId, user, layout, windowState, req);
614
615 PortalUtil.updatePortletMode(
616 portletId, user, layout, portletMode, req);
617 }
618
619 if (lifecycle.equals(PortletRequest.RESOURCE_PHASE)) {
620 ResourceRequestImpl resourceReqImpl =
621 ResourceRequestFactory.create(
622 req, portlet, invokerPortlet, portletCtx, windowState,
623 portletMode, portletPreferences, layout.getPlid());
624
625 StringServletResponse stringServletRes = new StringServletResponse(
626 res);
627
628 ResourceResponseImpl resourceResImpl =
629 ResourceResponseFactory.create(
630 resourceReqImpl, stringServletRes, portletId, companyId);
631
632 resourceReqImpl.defineObjects(portletConfig, resourceResImpl);
633
634 invokerPortlet.serveResource(resourceReqImpl, resourceResImpl);
635
636 if (stringServletRes.isCalledGetOutputStream()) {
637 InputStream is = new ByteArrayInputStream(
638 stringServletRes.getByteArrayMaker().toByteArray());
639
640 ServletResponseUtil.sendFile(
641 res, resourceReqImpl.getResourceID(), is,
642 resourceResImpl.getContentType());
643 }
644 else {
645 byte[] content = stringServletRes.getString().getBytes(
646 StringPool.UTF8);
647
648 ServletResponseUtil.sendFile(
649 res, resourceReqImpl.getResourceID(), content,
650 resourceResImpl.getContentType());
651 }
652 }
653
654 return portlet;
655 }
656
657 protected void redirectActionURL(
658 HttpServletRequest req, HttpServletResponse res,
659 ActionResponseImpl actionResImpl, Portlet portlet)
660 throws Exception {
661
662 ActionRequestImpl actionReqImpl = (ActionRequestImpl)req.getAttribute(
663 JavaConstants.JAVAX_PORTLET_REQUEST);
664
665 Layout layout = (Layout)req.getAttribute(WebKeys.LAYOUT);
666
667 PortletURL portletURL = new PortletURLImpl(
668 actionReqImpl, actionReqImpl.getPortletName(), layout.getLayoutId(),
669 PortletRequest.RENDER_PHASE);
670
671 Map<String, String[]> renderParameters =
672 actionResImpl.getRenderParameterMap();
673
674 for (Map.Entry<String, String[]> entry : renderParameters.entrySet()) {
675 String key = entry.getKey();
676 String[] value = entry.getValue();
677
678 portletURL.setParameter(key, value);
679 }
680
681 res.sendRedirect(portletURL.toString());
682 }
683
684 protected void renderExclusive(
685 HttpServletRequest req, HttpServletResponse res,
686 ThemeDisplay themeDisplay)
687 throws Exception {
688
689 RenderRequestImpl renderReqImpl = (RenderRequestImpl)req.getAttribute(
690 JavaConstants.JAVAX_PORTLET_REQUEST);
691
692 RenderResponseImpl renderResImpl = (RenderResponseImpl)req.getAttribute(
693 JavaConstants.JAVAX_PORTLET_RESPONSE);
694
695 StringServletResponse stringServletRes =
696 (StringServletResponse)renderReqImpl.getAttribute(
697 WebKeys.STRING_SERVLET_RESPONSE);
698
699 renderResImpl.transferHeaders(res);
700
701 if (stringServletRes.isCalledGetOutputStream()) {
702 InputStream is = new ByteArrayInputStream(
703 stringServletRes.getByteArrayMaker().toByteArray());
704
705 ServletResponseUtil.sendFile(
706 res, renderResImpl.getResourceName(), is,
707 renderResImpl.getContentType());
708 }
709 else {
710 byte[] content = stringServletRes.getString().getBytes(
711 StringPool.UTF8);
712
713 ServletResponseUtil.sendFile(
714 res, renderResImpl.getResourceName(), content,
715 renderResImpl.getContentType());
716 }
717
718 RenderRequestFactory.recycle(renderReqImpl);
719 RenderResponseFactory.recycle(renderResImpl);
720 }
721
722 private static Log _log = LogFactory.getLog(LayoutAction.class);
723
724 }