001
014
015 package com.liferay.portal.action;
016
017 import com.liferay.portal.kernel.audit.AuditMessage;
018 import com.liferay.portal.kernel.audit.AuditRouterUtil;
019 import com.liferay.portal.kernel.exception.PortalException;
020 import com.liferay.portal.kernel.exception.SystemException;
021 import com.liferay.portal.kernel.io.unsync.UnsyncByteArrayInputStream;
022 import com.liferay.portal.kernel.io.unsync.UnsyncByteArrayOutputStream;
023 import com.liferay.portal.kernel.io.unsync.UnsyncStringWriter;
024 import com.liferay.portal.kernel.language.LanguageUtil;
025 import com.liferay.portal.kernel.log.Log;
026 import com.liferay.portal.kernel.log.LogFactoryUtil;
027 import com.liferay.portal.kernel.messaging.DestinationNames;
028 import com.liferay.portal.kernel.messaging.MessageBusUtil;
029 import com.liferay.portal.kernel.portlet.LiferayPortletMode;
030 import com.liferay.portal.kernel.portlet.PortletModeFactory;
031 import com.liferay.portal.kernel.portlet.WindowStateFactory;
032 import com.liferay.portal.kernel.servlet.BrowserSnifferUtil;
033 import com.liferay.portal.kernel.servlet.HeaderCacheServletResponse;
034 import com.liferay.portal.kernel.servlet.HttpHeaders;
035 import com.liferay.portal.kernel.servlet.PipingServletResponse;
036 import com.liferay.portal.kernel.servlet.ServletResponseUtil;
037 import com.liferay.portal.kernel.servlet.StringServletResponse;
038 import com.liferay.portal.kernel.servlet.TempAttributesServletRequest;
039 import com.liferay.portal.kernel.struts.LastPath;
040 import com.liferay.portal.kernel.upload.UploadServletRequest;
041 import com.liferay.portal.kernel.util.ArrayUtil;
042 import com.liferay.portal.kernel.util.Base64;
043 import com.liferay.portal.kernel.util.ContentTypes;
044 import com.liferay.portal.kernel.util.HttpUtil;
045 import com.liferay.portal.kernel.util.JavaConstants;
046 import com.liferay.portal.kernel.util.ParamUtil;
047 import com.liferay.portal.kernel.util.PropsKeys;
048 import com.liferay.portal.kernel.util.ServerDetector;
049 import com.liferay.portal.kernel.util.StringBundler;
050 import com.liferay.portal.kernel.util.StringPool;
051 import com.liferay.portal.kernel.util.Validator;
052 import com.liferay.portal.kernel.webdav.WebDAVStorage;
053 import com.liferay.portal.kernel.xml.QName;
054 import com.liferay.portal.model.Layout;
055 import com.liferay.portal.model.LayoutConstants;
056 import com.liferay.portal.model.LayoutTypePortlet;
057 import com.liferay.portal.model.Portlet;
058 import com.liferay.portal.model.PortletPreferencesIds;
059 import com.liferay.portal.model.PublicRenderParameter;
060 import com.liferay.portal.model.User;
061 import com.liferay.portal.security.auth.AuthTokenUtil;
062 import com.liferay.portal.security.permission.ActionKeys;
063 import com.liferay.portal.security.permission.PermissionChecker;
064 import com.liferay.portal.security.permission.PermissionThreadLocal;
065 import com.liferay.portal.service.LayoutLocalServiceUtil;
066 import com.liferay.portal.service.PortletLocalServiceUtil;
067 import com.liferay.portal.service.PortletPreferencesLocalServiceUtil;
068 import com.liferay.portal.service.ServiceContext;
069 import com.liferay.portal.service.ServiceContextFactory;
070 import com.liferay.portal.service.ServiceContextThreadLocal;
071 import com.liferay.portal.service.permission.PortletPermissionUtil;
072 import com.liferay.portal.struts.ActionConstants;
073 import com.liferay.portal.struts.StrutsUtil;
074 import com.liferay.portal.theme.PortletDisplay;
075 import com.liferay.portal.theme.ThemeDisplay;
076 import com.liferay.portal.upload.UploadServletRequestImpl;
077 import com.liferay.portal.util.PortalUtil;
078 import com.liferay.portal.util.PrefsPropsUtil;
079 import com.liferay.portal.util.PropsValues;
080 import com.liferay.portal.util.WebKeys;
081 import com.liferay.portlet.ActionRequestFactory;
082 import com.liferay.portlet.ActionRequestImpl;
083 import com.liferay.portlet.ActionResponseFactory;
084 import com.liferay.portlet.ActionResponseImpl;
085 import com.liferay.portlet.EventImpl;
086 import com.liferay.portlet.EventRequestFactory;
087 import com.liferay.portlet.EventRequestImpl;
088 import com.liferay.portlet.EventResponseFactory;
089 import com.liferay.portlet.EventResponseImpl;
090 import com.liferay.portlet.InvokerPortlet;
091 import com.liferay.portlet.InvokerPortletImpl;
092 import com.liferay.portlet.PortletConfigFactoryUtil;
093 import com.liferay.portlet.PortletConfigImpl;
094 import com.liferay.portlet.PortletInstanceFactoryUtil;
095 import com.liferay.portlet.PortletPreferencesFactoryUtil;
096 import com.liferay.portlet.PortletQName;
097 import com.liferay.portlet.PortletQNameUtil;
098 import com.liferay.portlet.PortletRequestImpl;
099 import com.liferay.portlet.PortletURLImpl;
100 import com.liferay.portlet.PublicRenderParametersPool;
101 import com.liferay.portlet.RenderParametersPool;
102 import com.liferay.portlet.RenderRequestImpl;
103 import com.liferay.portlet.RenderResponseImpl;
104 import com.liferay.portlet.ResourceRequestFactory;
105 import com.liferay.portlet.ResourceRequestImpl;
106 import com.liferay.portlet.ResourceResponseFactory;
107 import com.liferay.portlet.ResourceResponseImpl;
108 import com.liferay.portlet.StateAwareResponseImpl;
109 import com.liferay.portlet.layoutconfiguration.util.RuntimePortletUtil;
110 import com.liferay.portlet.login.util.LoginUtil;
111 import com.liferay.util.servlet.filters.CacheResponseUtil;
112
113 import java.io.InputStream;
114 import java.io.Serializable;
115
116 import java.util.ArrayList;
117 import java.util.Enumeration;
118 import java.util.HashMap;
119 import java.util.List;
120 import java.util.Map;
121
122 import javax.portlet.Event;
123 import javax.portlet.PortletConfig;
124 import javax.portlet.PortletContext;
125 import javax.portlet.PortletMode;
126 import javax.portlet.PortletPreferences;
127 import javax.portlet.PortletRequest;
128 import javax.portlet.PortletURL;
129 import javax.portlet.UnavailableException;
130 import javax.portlet.WindowState;
131
132 import javax.servlet.RequestDispatcher;
133 import javax.servlet.ServletContext;
134 import javax.servlet.http.HttpServletRequest;
135 import javax.servlet.http.HttpServletResponse;
136 import javax.servlet.http.HttpSession;
137
138 import org.apache.struts.action.Action;
139 import org.apache.struts.action.ActionForm;
140 import org.apache.struts.action.ActionForward;
141 import org.apache.struts.action.ActionMapping;
142
143
146 public class LayoutAction extends Action {
147
148 @Override
149 public ActionForward execute(
150 ActionMapping mapping, ActionForm form, HttpServletRequest request,
151 HttpServletResponse response)
152 throws Exception {
153
154 HeaderCacheServletResponse headerCacheServletResponse = null;
155
156 if (response instanceof HeaderCacheServletResponse) {
157 headerCacheServletResponse = (HeaderCacheServletResponse)response;
158 }
159 else {
160 headerCacheServletResponse = new HeaderCacheServletResponse(
161 response);
162 }
163
164 ThemeDisplay themeDisplay = (ThemeDisplay)request.getAttribute(
165 WebKeys.THEME_DISPLAY);
166
167 Layout layout = themeDisplay.getLayout();
168
169 Boolean layoutDefault = (Boolean)request.getAttribute(
170 WebKeys.LAYOUT_DEFAULT);
171
172 if ((layoutDefault != null) && layoutDefault.booleanValue()) {
173 Layout requestedLayout = (Layout)request.getAttribute(
174 WebKeys.REQUESTED_LAYOUT);
175
176 if (requestedLayout != null) {
177 String redirectParam = "redirect";
178
179 if (Validator.isNotNull(PropsValues.AUTH_LOGIN_PORTLET_NAME)) {
180 redirectParam =
181 PortalUtil.getPortletNamespace(
182 PropsValues.AUTH_LOGIN_PORTLET_NAME) +
183 redirectParam;
184 }
185
186 String authLoginURL = null;
187
188 if (PrefsPropsUtil.getBoolean(
189 themeDisplay.getCompanyId(), PropsKeys.CAS_AUTH_ENABLED,
190 PropsValues.CAS_AUTH_ENABLED) ||
191 PrefsPropsUtil.getBoolean(
192 themeDisplay.getCompanyId(),
193 PropsKeys.OPEN_SSO_AUTH_ENABLED,
194 PropsValues.OPEN_SSO_AUTH_ENABLED)) {
195
196 authLoginURL = themeDisplay.getURLSignIn();
197 }
198
199 if (Validator.isNull(authLoginURL)) {
200 authLoginURL = PortalUtil.getSiteLoginURL(themeDisplay);
201 }
202
203 if (Validator.isNull(authLoginURL)) {
204 authLoginURL = PropsValues.AUTH_LOGIN_URL;
205 }
206
207 if (Validator.isNull(authLoginURL)) {
208 PortletURL loginURL = LoginUtil.getLoginURL(
209 request, themeDisplay.getPlid());
210
211 authLoginURL = loginURL.toString();
212 }
213
214 authLoginURL = HttpUtil.setParameter(
215 authLoginURL, "p_p_id",
216 PropsValues.AUTH_LOGIN_PORTLET_NAME);
217
218 String currentURL = PortalUtil.getCurrentURL(request);
219
220 authLoginURL = HttpUtil.setParameter(
221 authLoginURL, redirectParam, currentURL);
222
223 if (_log.isDebugEnabled()) {
224 _log.debug("Redirect requested layout to " + authLoginURL);
225 }
226
227 headerCacheServletResponse.sendRedirect(authLoginURL);
228 }
229 else {
230 String redirect = PortalUtil.getLayoutURL(layout, themeDisplay);
231
232 if (_log.isDebugEnabled()) {
233 _log.debug("Redirect default layout to " + redirect);
234 }
235
236 headerCacheServletResponse.sendRedirect(redirect);
237 }
238
239 return null;
240 }
241
242 long plid = ParamUtil.getLong(request, "p_l_id");
243
244 if (_log.isDebugEnabled()) {
245 _log.debug("p_l_id is " + plid);
246 }
247
248 if (plid > 0) {
249 ActionForward actionForward = processLayout(
250 mapping, request, headerCacheServletResponse, plid);
251
252 String contentType = response.getContentType();
253
254 CacheResponseUtil.setHeaders(
255 response, headerCacheServletResponse.getHeaders());
256
257 if (contentType != null) {
258 response.setContentType(contentType);
259 }
260
261 return actionForward;
262 }
263 else {
264 try {
265 forwardLayout(request);
266
267 return mapping.findForward(ActionConstants.COMMON_FORWARD_JSP);
268 }
269 catch (Exception e) {
270 PortalUtil.sendError(e, request, headerCacheServletResponse);
271
272 CacheResponseUtil.setHeaders(
273 response, headerCacheServletResponse.getHeaders());
274
275 return null;
276 }
277 }
278 }
279
280 protected void forwardLayout(HttpServletRequest request) throws Exception {
281 Layout layout = (Layout)request.getAttribute(WebKeys.LAYOUT);
282
283 long plid = LayoutConstants.DEFAULT_PLID;
284
285 String layoutFriendlyURL = null;
286
287 ThemeDisplay themeDisplay = (ThemeDisplay)request.getAttribute(
288 WebKeys.THEME_DISPLAY);
289
290 if (layout != null) {
291 plid = layout.getPlid();
292
293 layoutFriendlyURL = PortalUtil.getLayoutFriendlyURL(
294 layout, themeDisplay);
295 }
296
297 String forwardURL = layoutFriendlyURL;
298
299 if (Validator.isNull(forwardURL)) {
300 forwardURL =
301 themeDisplay.getPathMain() + "/portal/layout?p_l_id=" + plid;
302 }
303
304 if (Validator.isNotNull(themeDisplay.getDoAsUserId())) {
305 forwardURL = HttpUtil.addParameter(
306 forwardURL, "doAsUserId", themeDisplay.getDoAsUserId());
307 }
308
309 if (Validator.isNotNull(themeDisplay.getDoAsUserLanguageId())) {
310 forwardURL = HttpUtil.addParameter(
311 forwardURL, "doAsUserLanguageId",
312 themeDisplay.getDoAsUserLanguageId());
313 }
314
315 if (_log.isDebugEnabled()) {
316 _log.debug("Forward layout to " + forwardURL);
317 }
318
319 request.setAttribute(WebKeys.FORWARD_URL, forwardURL);
320 }
321
322 protected List<LayoutTypePortlet> getLayoutTypePortlets(
323 long groupId, boolean privateLayout)
324 throws Exception {
325
326 List<LayoutTypePortlet> layoutTypePortlets =
327 new ArrayList<LayoutTypePortlet>();
328
329 List<Layout> layouts = LayoutLocalServiceUtil.getLayouts(
330 groupId, privateLayout, LayoutConstants.TYPE_PORTLET);
331
332 for (Layout layout : layouts) {
333 if (!layout.isTypePortlet()) {
334 continue;
335 }
336
337 LayoutTypePortlet layoutTypePortlet =
338 (LayoutTypePortlet)layout.getLayoutType();
339
340 layoutTypePortlets.add(layoutTypePortlet);
341 }
342
343 return layoutTypePortlets;
344 }
345
346 protected HttpServletRequest getOwnerLayoutRequestWrapper(
347 HttpServletRequest request, Portlet portlet)
348 throws Exception {
349
350 if (!PropsValues.PORTLET_EVENT_DISTRIBUTION_LAYOUT_SET) {
351 return request;
352 }
353
354 ThemeDisplay themeDisplay =
355 (ThemeDisplay)request.getAttribute(WebKeys.THEME_DISPLAY);
356
357 Layout currentLayout = themeDisplay.getLayout();
358
359 Layout requestLayout = (Layout)request.getAttribute(WebKeys.LAYOUT);
360
361 List<LayoutTypePortlet> layoutTypePortlets = getLayoutTypePortlets(
362 requestLayout.getGroupId(), requestLayout.isPrivateLayout());
363
364 Layout ownerLayout = null;
365 LayoutTypePortlet ownerLayoutTypePortlet = null;
366
367 for (LayoutTypePortlet layoutTypePortlet : layoutTypePortlets) {
368 if (layoutTypePortlet.hasPortletId(portlet.getPortletId())) {
369 ownerLayoutTypePortlet = layoutTypePortlet;
370
371 ownerLayout = layoutTypePortlet.getLayout();
372
373 break;
374 }
375 }
376
377 if ((ownerLayout != null) && !currentLayout.equals(ownerLayout)) {
378 ThemeDisplay themeDisplayClone = (ThemeDisplay)themeDisplay.clone();
379
380 themeDisplayClone.setLayout(ownerLayout);
381 themeDisplayClone.setLayoutTypePortlet(ownerLayoutTypePortlet);
382
383 TempAttributesServletRequest tempAttributesServletRequest =
384 new TempAttributesServletRequest(request);
385
386 tempAttributesServletRequest.setTempAttribute(
387 WebKeys.THEME_DISPLAY, themeDisplayClone);
388 tempAttributesServletRequest.setTempAttribute(
389 WebKeys.LAYOUT, ownerLayout);
390
391 return tempAttributesServletRequest;
392 }
393
394 return request;
395 }
396
397 protected long getScopeGroupId(
398 HttpServletRequest request, LayoutTypePortlet layoutTypePortlet,
399 String portletId)
400 throws PortalException, SystemException {
401
402 long scopeGroupId = 0;
403
404 Layout layoutTypePortletLayout = layoutTypePortlet.getLayout();
405
406 Layout requestLayout = (Layout)request.getAttribute(WebKeys.LAYOUT);
407
408 try {
409 request.setAttribute(WebKeys.LAYOUT, layoutTypePortletLayout);
410
411 scopeGroupId = PortalUtil.getScopeGroupId(request, portletId);
412 }
413 finally {
414 request.setAttribute(WebKeys.LAYOUT, requestLayout);
415 }
416
417 if (scopeGroupId <= 0) {
418 scopeGroupId = PortalUtil.getScopeGroupId(
419 layoutTypePortletLayout, portletId);
420 }
421
422 return scopeGroupId;
423 }
424
425 protected void includeLayoutContent(
426 HttpServletRequest request, HttpServletResponse response,
427 ThemeDisplay themeDisplay, Layout layout)
428 throws Exception {
429
430 ServletContext servletContext = (ServletContext)request.getAttribute(
431 WebKeys.CTX);
432
433 String path = StrutsUtil.TEXT_HTML_DIR;
434
435 if (BrowserSnifferUtil.isWap(request)) {
436 path = StrutsUtil.TEXT_WAP_DIR;
437 }
438
439
440
441 if (themeDisplay.isStateExclusive() ||
442 Validator.isNotNull(ParamUtil.getString(request, "p_p_id"))) {
443
444 if (layout.isTypePanel()) {
445 path += "/portal/layout/view/panel.jsp";
446 }
447 else if (layout.isTypeControlPanel()) {
448 path += "/portal/layout/view/control_panel.jsp";
449 }
450 else {
451 path += "/portal/layout/view/portlet.jsp";
452 }
453 }
454 else {
455 path += PortalUtil.getLayoutViewPage(layout);
456 }
457
458 RequestDispatcher requestDispatcher =
459 servletContext.getRequestDispatcher(path);
460
461 UnsyncStringWriter unsyncStringWriter = new UnsyncStringWriter();
462
463 PipingServletResponse pipingServletResponse = new PipingServletResponse(
464 response, unsyncStringWriter);
465
466 String contentType = pipingServletResponse.getContentType();
467
468 requestDispatcher.include(request, pipingServletResponse);
469
470 if (contentType != null) {
471 response.setContentType(contentType);
472 }
473
474 request.setAttribute(
475 WebKeys.LAYOUT_CONTENT, unsyncStringWriter.getStringBundler());
476 }
477
478 protected void processEvent(
479 PortletRequestImpl portletRequestImpl,
480 StateAwareResponseImpl stateAwareResponseImpl,
481 List<LayoutTypePortlet> layoutTypePortlets,
482 LayoutTypePortlet layoutTypePortlet, Portlet portlet, Event event)
483 throws Exception {
484
485 HttpServletRequest request = portletRequestImpl.getHttpServletRequest();
486 HttpServletResponse response =
487 stateAwareResponseImpl.getHttpServletResponse();
488 HttpSession session = request.getSession();
489
490 String portletId = portlet.getPortletId();
491
492 ServletContext servletContext =
493 (ServletContext)request.getAttribute(WebKeys.CTX);
494
495 InvokerPortlet invokerPortlet = PortletInstanceFactoryUtil.create(
496 portlet, servletContext);
497
498 PortletConfig portletConfig = PortletConfigFactoryUtil.create(
499 portlet, servletContext);
500 PortletContext portletContext = portletConfig.getPortletContext();
501
502 WindowState windowState = null;
503
504 if (layoutTypePortlet.hasStateMaxPortletId(portletId)) {
505 windowState = WindowState.MAXIMIZED;
506 }
507 else if (layoutTypePortlet.hasStateMinPortletId(portletId)) {
508 windowState = WindowState.MINIMIZED;
509 }
510 else {
511 windowState = WindowState.NORMAL;
512 }
513
514 PortletMode portletMode = null;
515
516 if (layoutTypePortlet.hasModeAboutPortletId(portletId)) {
517 portletMode = LiferayPortletMode.ABOUT;
518 }
519 else if (layoutTypePortlet.hasModeConfigPortletId(portletId)) {
520 portletMode = LiferayPortletMode.CONFIG;
521 }
522 else if (layoutTypePortlet.hasModeEditPortletId(portletId)) {
523 portletMode = PortletMode.EDIT;
524 }
525 else if (layoutTypePortlet.hasModeEditDefaultsPortletId(portletId)) {
526 portletMode = LiferayPortletMode.EDIT_DEFAULTS;
527 }
528 else if (layoutTypePortlet.hasModeEditGuestPortletId(portletId)) {
529 portletMode = LiferayPortletMode.EDIT_GUEST;
530 }
531 else if (layoutTypePortlet.hasModeHelpPortletId(portletId)) {
532 portletMode = PortletMode.HELP;
533 }
534 else if (layoutTypePortlet.hasModePreviewPortletId(portletId)) {
535 portletMode = LiferayPortletMode.PREVIEW;
536 }
537 else if (layoutTypePortlet.hasModePrintPortletId(portletId)) {
538 portletMode = LiferayPortletMode.PRINT;
539 }
540 else {
541 portletMode = PortletMode.VIEW;
542 }
543
544 long scopeGroupId = getScopeGroupId(
545 request, layoutTypePortlet, portletId);
546
547 Layout layoutTypePortletLayout = layoutTypePortlet.getLayout();
548
549 PortletPreferences portletPreferences =
550 PortletPreferencesFactoryUtil.getPortletSetup(
551 scopeGroupId, layoutTypePortletLayout, portletId, null);
552
553 EventRequestImpl eventRequestImpl = EventRequestFactory.create(
554 request, portlet, invokerPortlet, portletContext, windowState,
555 portletMode, portletPreferences, layoutTypePortletLayout.getPlid());
556
557 eventRequestImpl.setEvent(
558 serializeEvent(event, invokerPortlet.getPortletClassLoader()));
559
560 Layout layout = stateAwareResponseImpl.getLayout();
561
562 EventResponseImpl eventResponseImpl = EventResponseFactory.create(
563 eventRequestImpl, response, portletId,
564 stateAwareResponseImpl.getUser(), layout);
565
566 eventRequestImpl.defineObjects(portletConfig, eventResponseImpl);
567
568 try {
569 try {
570 InvokerPortletImpl.clearResponse(
571 session, layout.getPrimaryKey(), portletId,
572 LanguageUtil.getLanguageId(eventRequestImpl));
573
574 invokerPortlet.processEvent(
575 eventRequestImpl, eventResponseImpl);
576
577 if (eventResponseImpl.isCalledSetRenderParameter()) {
578 Map<String, String[]> renderParameterMap =
579 new HashMap<String, String[]>();
580
581 renderParameterMap.putAll(
582 eventResponseImpl.getRenderParameterMap());
583
584 RenderParametersPool.put(
585 request, layout.getPlid(), portletId,
586 renderParameterMap);
587 }
588 }
589 catch (UnavailableException ue) {
590 throw ue;
591 }
592
593 processEvents(
594 eventRequestImpl, eventResponseImpl, layoutTypePortlets);
595 }
596 finally {
597 eventRequestImpl.cleanUp();
598 }
599 }
600
601 protected void processEvents(
602 PortletRequestImpl portletRequestImpl,
603 StateAwareResponseImpl stateAwareResponseImpl,
604 List<LayoutTypePortlet> layoutTypePortlets)
605 throws Exception {
606
607 List<Event> events = stateAwareResponseImpl.getEvents();
608
609 if (events.size() == 0) {
610 return;
611 }
612
613 for (Event event : events) {
614 javax.xml.namespace.QName qName = event.getQName();
615
616 for (LayoutTypePortlet layoutTypePortlet : layoutTypePortlets) {
617 List<Portlet> portlets = layoutTypePortlet.getAllPortlets();
618
619 for (Portlet portlet : portlets) {
620 QName processingQName = portlet.getProcessingEvent(
621 qName.getNamespaceURI(), qName.getLocalPart());
622
623 if (processingQName != null) {
624 processEvent(
625 portletRequestImpl, stateAwareResponseImpl,
626 layoutTypePortlets, layoutTypePortlet, portlet,
627 event);
628 }
629 }
630 }
631 }
632 }
633
634 protected ActionForward processLayout(
635 ActionMapping mapping, HttpServletRequest request,
636 HttpServletResponse response, long plid)
637 throws Exception {
638
639 HttpSession session = request.getSession();
640
641 ThemeDisplay themeDisplay = (ThemeDisplay)request.getAttribute(
642 WebKeys.THEME_DISPLAY);
643
644 try {
645 Layout layout = themeDisplay.getLayout();
646
647 boolean resetLayout = ParamUtil.getBoolean(
648 request, "p_l_reset", PropsValues.LAYOUT_DEFAULT_P_L_RESET);
649
650 String portletId = ParamUtil.getString(request, "p_p_id");
651
652 Layout previousLayout = (Layout)session.getAttribute(
653 WebKeys.PREVIOUS_LAYOUT);
654
655 if ((previousLayout == null) ||
656 (layout.getPlid() != previousLayout.getPlid())) {
657
658 session.setAttribute(WebKeys.PREVIOUS_LAYOUT, layout);
659
660 if (themeDisplay.isSignedIn() &&
661 PropsValues.
662 AUDIT_MESSAGE_COM_LIFERAY_PORTAL_MODEL_LAYOUT_VIEW &&
663 MessageBusUtil.hasMessageListener(DestinationNames.AUDIT)) {
664
665 User user = themeDisplay.getUser();
666
667 AuditMessage auditMessage = new AuditMessage(
668 ActionKeys.VIEW, user.getCompanyId(), user.getUserId(),
669 user.getFullName(), Layout.class.getName(),
670 String.valueOf(layout.getPlid()));
671
672 AuditRouterUtil.route(auditMessage);
673 }
674 }
675
676 if (!PropsValues.TCK_URL && resetLayout &&
677 (Validator.isNull(portletId) ||
678 ((previousLayout != null) &&
679 (layout.getPlid() != previousLayout.getPlid())))) {
680
681
682
683
684 RenderParametersPool.clear(request, plid);
685 }
686
687 if (themeDisplay.isLifecycleAction()) {
688 Portlet portlet = processPortletRequest(
689 request, response, PortletRequest.ACTION_PHASE);
690
691 if (portlet != null) {
692 ActionResponseImpl actionResponseImpl =
693 (ActionResponseImpl)request.getAttribute(
694 JavaConstants.JAVAX_PORTLET_RESPONSE);
695
696 String redirectLocation =
697 actionResponseImpl.getRedirectLocation();
698
699 if (Validator.isNotNull(redirectLocation)) {
700 response.sendRedirect(redirectLocation);
701
702 return null;
703 }
704
705 if (portlet.isActionURLRedirect()) {
706 redirectActionURL(
707 request, response, actionResponseImpl, portlet);
708
709 return null;
710 }
711 }
712 }
713 else if (themeDisplay.isLifecycleRender()) {
714 processPortletRequest(
715 request, response, PortletRequest.RENDER_PHASE);
716 }
717
718 if (themeDisplay.isLifecycleResource()) {
719 processPortletRequest(
720 request, response, PortletRequest.RESOURCE_PHASE);
721
722 return null;
723 }
724 else {
725 if (response.isCommitted()) {
726 return null;
727 }
728
729 if (layout != null) {
730
731
732
733
734
735 includeLayoutContent(
736 request, response, themeDisplay, layout);
737
738 if (themeDisplay.isStateExclusive()) {
739 renderExclusive(request, response, themeDisplay);
740
741 return null;
742 }
743 }
744
745 return mapping.findForward("portal.layout");
746 }
747 }
748 catch (Exception e) {
749 PortalUtil.sendError(e, request, response);
750
751 return null;
752 }
753 finally {
754 if (!ServerDetector.isResin()) {
755 PortletRequest portletRequest =
756 (PortletRequest)request.getAttribute(
757 JavaConstants.JAVAX_PORTLET_REQUEST);
758
759 if (portletRequest != null) {
760 PortletRequestImpl portletRequestImpl =
761 (PortletRequestImpl)portletRequest;
762
763 portletRequestImpl.cleanUp();
764 }
765 }
766 }
767 }
768
769 protected Portlet processPortletRequest(
770 HttpServletRequest request, HttpServletResponse response,
771 String lifecycle)
772 throws Exception {
773
774 HttpSession session = request.getSession();
775
776 long companyId = PortalUtil.getCompanyId(request);
777 User user = PortalUtil.getUser(request);
778 Layout layout = (Layout)request.getAttribute(WebKeys.LAYOUT);
779
780 String portletId = ParamUtil.getString(request, "p_p_id");
781
782 if (Validator.isNull(portletId)) {
783 return null;
784 }
785
786 Portlet portlet = PortletLocalServiceUtil.getPortletById(
787 companyId, portletId);
788
789 if (portlet == null) {
790 return null;
791 }
792
793 ThemeDisplay themeDisplay = (ThemeDisplay)request.getAttribute(
794 WebKeys.THEME_DISPLAY);
795
796 long scopeGroupId = PortalUtil.getScopeGroupId(request, portletId);
797
798 themeDisplay.setScopeGroupId(scopeGroupId);
799
800 ServletContext servletContext = (ServletContext)request.getAttribute(
801 WebKeys.CTX);
802
803 if (user != null) {
804 InvokerPortletImpl.clearResponse(
805 session, layout.getPrimaryKey(), portletId,
806 LanguageUtil.getLanguageId(request));
807 }
808
809 PortletConfig portletConfig = PortletConfigFactoryUtil.create(
810 portlet, servletContext);
811 PortletContext portletContext = portletConfig.getPortletContext();
812
813 WindowState windowState = WindowStateFactory.getWindowState(
814 ParamUtil.getString(request, "p_p_state"));
815
816 if (layout.isTypeControlPanel() &&
817 ((windowState == null) || windowState.equals(WindowState.NORMAL) ||
818 Validator.isNull(windowState.toString()))) {
819
820 windowState = WindowState.MAXIMIZED;
821 }
822
823 PortletMode portletMode = PortletModeFactory.getPortletMode(
824 ParamUtil.getString(request, "p_p_mode"));
825
826 HttpServletRequest ownerLayoutRequest = getOwnerLayoutRequestWrapper(
827 request, portlet);
828
829 Layout ownerLayout = (Layout)ownerLayoutRequest.getAttribute(
830 WebKeys.LAYOUT);
831
832 boolean allowAddPortletDefaultResource =
833 PortalUtil.isAllowAddPortletDefaultResource(
834 ownerLayoutRequest, portlet);
835
836 PortletPreferencesIds portletPreferencesIds =
837 PortletPreferencesFactoryUtil.getPortletPreferencesIds(
838 request, portletId);
839
840 PortletPreferences portletPreferences = null;
841
842 if (allowAddPortletDefaultResource) {
843 portletPreferences =
844 PortletPreferencesLocalServiceUtil.getPreferences(
845 portletPreferencesIds);
846 }
847 else {
848 portletPreferences =
849 PortletPreferencesLocalServiceUtil.getStrictPreferences(
850 portletPreferencesIds);
851 }
852
853 processPublicRenderParameters(request, layout, portlet);
854
855 PermissionChecker permissionChecker =
856 PermissionThreadLocal.getPermissionChecker();
857
858 if (lifecycle.equals(PortletRequest.ACTION_PHASE)) {
859 if (!allowAddPortletDefaultResource) {
860 String url = null;
861
862 LastPath lastPath = (LastPath)request.getAttribute(
863 WebKeys.LAST_PATH);
864
865 if (lastPath != null) {
866 StringBundler sb = new StringBundler(3);
867
868 sb.append(PortalUtil.getPortalURL(request));
869 sb.append(lastPath.getContextPath());
870 sb.append(lastPath.getPath());
871
872 url = sb.toString();
873 }
874 else {
875 url = String.valueOf(request.getRequestURI());
876 }
877
878 _log.error(
879 "Reject processAction for " + url + " on " +
880 portlet.getPortletId());
881
882 return null;
883 }
884
885 InvokerPortlet invokerPortlet = PortletInstanceFactoryUtil.create(
886 portlet, servletContext);
887
888 String contentType = request.getHeader(HttpHeaders.CONTENT_TYPE);
889
890 if (_log.isDebugEnabled()) {
891 _log.debug("Content type " + contentType);
892 }
893
894 UploadServletRequest uploadServletRequest = null;
895
896 try {
897 if ((contentType != null) &&
898 contentType.startsWith(ContentTypes.MULTIPART_FORM_DATA)) {
899
900 PortletConfigImpl invokerPortletConfigImpl =
901 (PortletConfigImpl)invokerPortlet.getPortletConfig();
902
903 if (invokerPortlet.isStrutsPortlet() ||
904 ((invokerPortletConfigImpl != null) &&
905 !invokerPortletConfigImpl.isWARFile())) {
906
907 uploadServletRequest = new UploadServletRequestImpl(
908 request);
909
910 request = uploadServletRequest;
911 }
912 }
913
914 if (PropsValues.AUTH_TOKEN_CHECK_ENABLED &&
915 invokerPortlet.isCheckAuthToken()) {
916
917 AuthTokenUtil.check(request);
918 }
919
920 ActionRequestImpl actionRequestImpl =
921 ActionRequestFactory.create(
922 request, portlet, invokerPortlet, portletContext,
923 windowState, portletMode, portletPreferences,
924 layout.getPlid());
925
926 ActionResponseImpl actionResponseImpl =
927 ActionResponseFactory.create(
928 actionRequestImpl, response, portletId, user, layout,
929 windowState, portletMode);
930
931 actionRequestImpl.defineObjects(
932 portletConfig, actionResponseImpl);
933
934 ServiceContext serviceContext =
935 ServiceContextFactory.getInstance(actionRequestImpl);
936
937 ServiceContextThreadLocal.pushServiceContext(serviceContext);
938
939 boolean access = PortletPermissionUtil.hasAccessPermission(
940 permissionChecker, scopeGroupId, ownerLayout, portlet,
941 portletMode);
942
943 if (access) {
944 invokerPortlet.processAction(
945 actionRequestImpl, actionResponseImpl);
946
947 actionResponseImpl.transferHeaders(response);
948 }
949
950 RenderParametersPool.put(
951 request, layout.getPlid(), portletId,
952 actionResponseImpl.getRenderParameterMap());
953
954 List<LayoutTypePortlet> layoutTypePortlets = null;
955
956 if (!actionResponseImpl.getEvents().isEmpty()) {
957 if (PropsValues.PORTLET_EVENT_DISTRIBUTION_LAYOUT_SET) {
958 layoutTypePortlets = getLayoutTypePortlets(
959 layout.getGroupId(), layout.isPrivateLayout());
960 }
961 else {
962 if (layout.isTypePortlet()) {
963 LayoutTypePortlet layoutTypePortlet =
964 (LayoutTypePortlet)layout.getLayoutType();
965
966 layoutTypePortlets =
967 new ArrayList<LayoutTypePortlet>();
968
969 layoutTypePortlets.add(layoutTypePortlet);
970 }
971 }
972
973 processEvents(
974 actionRequestImpl, actionResponseImpl,
975 layoutTypePortlets);
976
977 actionRequestImpl.defineObjects(
978 portletConfig, actionResponseImpl);
979 }
980 }
981 finally {
982 if (uploadServletRequest != null) {
983 uploadServletRequest.cleanUp();
984 }
985
986 ServiceContextThreadLocal.popServiceContext();
987 }
988 }
989 else if (lifecycle.equals(PortletRequest.RENDER_PHASE) ||
990 lifecycle.equals(PortletRequest.RESOURCE_PHASE)) {
991
992 PortalUtil.updateWindowState(
993 portletId, user, layout, windowState, request);
994
995 PortalUtil.updatePortletMode(
996 portletId, user, layout, portletMode, request);
997 }
998
999 if (lifecycle.equals(PortletRequest.RESOURCE_PHASE)) {
1000 if (!allowAddPortletDefaultResource) {
1001 String url = null;
1002
1003 LastPath lastPath = (LastPath)request.getAttribute(
1004 WebKeys.LAST_PATH);
1005
1006 if (lastPath != null) {
1007 StringBundler sb = new StringBundler(3);
1008
1009 sb.append(PortalUtil.getPortalURL(request));
1010 sb.append(lastPath.getContextPath());
1011 sb.append(lastPath.getPath());
1012
1013 url = sb.toString();
1014 }
1015 else {
1016 url = String.valueOf(request.getRequestURI());
1017 }
1018
1019 _log.error(
1020 "Reject serveResource for " + url + " on " +
1021 portlet.getPortletId());
1022
1023 return null;
1024 }
1025
1026 InvokerPortlet invokerPortlet = PortletInstanceFactoryUtil.create(
1027 portlet, servletContext);
1028
1029 PortletDisplay portletDisplay = themeDisplay.getPortletDisplay();
1030
1031 String portletPrimaryKey = PortletPermissionUtil.getPrimaryKey(
1032 layout.getPlid(), portletId);
1033
1034 portletDisplay.setId(portletId);
1035 portletDisplay.setRootPortletId(portlet.getRootPortletId());
1036 portletDisplay.setInstanceId(portlet.getInstanceId());
1037 portletDisplay.setResourcePK(portletPrimaryKey);
1038 portletDisplay.setPortletName(portletConfig.getPortletName());
1039 portletDisplay.setNamespace(
1040 PortalUtil.getPortletNamespace(portletId));
1041
1042 WebDAVStorage webDAVStorage = portlet.getWebDAVStorageInstance();
1043
1044 if (webDAVStorage != null) {
1045 portletDisplay.setWebDAVEnabled(true);
1046 }
1047 else {
1048 portletDisplay.setWebDAVEnabled(false);
1049 }
1050
1051 ResourceRequestImpl resourceRequestImpl =
1052 ResourceRequestFactory.create(
1053 request, portlet, invokerPortlet, portletContext,
1054 windowState, portletMode, portletPreferences,
1055 layout.getPlid());
1056
1057 ResourceResponseImpl resourceResponseImpl =
1058 ResourceResponseFactory.create(
1059 resourceRequestImpl, response, portletId, companyId);
1060
1061 resourceRequestImpl.defineObjects(
1062 portletConfig, resourceResponseImpl);
1063
1064 try {
1065 ServiceContext serviceContext =
1066 ServiceContextFactory.getInstance(resourceRequestImpl);
1067
1068 ServiceContextThreadLocal.pushServiceContext(serviceContext);
1069
1070 boolean access = PortletPermissionUtil.hasAccessPermission(
1071 permissionChecker, scopeGroupId, ownerLayout, portlet,
1072 portletMode);
1073
1074 if (access) {
1075 invokerPortlet.serveResource(
1076 resourceRequestImpl, resourceResponseImpl);
1077
1078 resourceResponseImpl.transferHeaders(response);
1079 }
1080 }
1081 finally {
1082 ServiceContextThreadLocal.popServiceContext();
1083 }
1084 }
1085
1086 return portlet;
1087 }
1088
1089 protected void processPublicRenderParameters(
1090 HttpServletRequest request, Layout layout, Portlet portlet) {
1091
1092 ThemeDisplay themeDisplay = (ThemeDisplay)request.getAttribute(
1093 WebKeys.THEME_DISPLAY);
1094
1095 Map<String, String[]> publicRenderParameters =
1096 PublicRenderParametersPool.get(request, layout.getPlid());
1097
1098 Enumeration<String> enu = request.getParameterNames();
1099
1100 while (enu.hasMoreElements()) {
1101 String name = enu.nextElement();
1102
1103 String[] values = request.getParameterValues(name);
1104
1105 QName qName = PortletQNameUtil.getQName(name);
1106
1107 if (qName == null) {
1108 continue;
1109 }
1110
1111 PublicRenderParameter publicRenderParameter =
1112 portlet.getPublicRenderParameter(
1113 qName.getNamespaceURI(), qName.getLocalPart());
1114
1115 if (publicRenderParameter == null) {
1116 continue;
1117 }
1118
1119 String publicRenderParameterName =
1120 PortletQNameUtil.getPublicRenderParameterName(qName);
1121
1122 if (name.startsWith(
1123 PortletQName.PUBLIC_RENDER_PARAMETER_NAMESPACE)) {
1124
1125 if (themeDisplay.isLifecycleAction()) {
1126 String[] oldValues = publicRenderParameters.get(
1127 publicRenderParameterName);
1128
1129 if ((oldValues != null) && (oldValues.length != 0)) {
1130 values = ArrayUtil.append(values, oldValues);
1131 }
1132 }
1133
1134 publicRenderParameters.put(publicRenderParameterName, values);
1135 }
1136 else {
1137 publicRenderParameters.remove(publicRenderParameterName);
1138 }
1139 }
1140 }
1141
1142 protected void redirectActionURL(
1143 HttpServletRequest request, HttpServletResponse response,
1144 ActionResponseImpl actionResponseImpl, Portlet portlet)
1145 throws Exception {
1146
1147 ActionRequestImpl actionRequestImpl =
1148 (ActionRequestImpl)request.getAttribute(
1149 JavaConstants.JAVAX_PORTLET_REQUEST);
1150
1151 Layout layout = (Layout)request.getAttribute(WebKeys.LAYOUT);
1152
1153 PortletURL portletURL = new PortletURLImpl(
1154 actionRequestImpl, actionRequestImpl.getPortletName(),
1155 layout.getPlid(), PortletRequest.RENDER_PHASE);
1156
1157 Map<String, String[]> renderParameters =
1158 actionResponseImpl.getRenderParameterMap();
1159
1160 for (Map.Entry<String, String[]> entry : renderParameters.entrySet()) {
1161 String key = entry.getKey();
1162 String[] value = entry.getValue();
1163
1164 portletURL.setParameter(key, value);
1165 }
1166
1167 response.sendRedirect(portletURL.toString());
1168 }
1169
1170 protected void renderExclusive(
1171 HttpServletRequest request, HttpServletResponse response,
1172 ThemeDisplay themeDisplay)
1173 throws Exception {
1174
1175 RenderRequestImpl renderRequestImpl =
1176 (RenderRequestImpl)request.getAttribute(
1177 JavaConstants.JAVAX_PORTLET_REQUEST);
1178
1179 RenderResponseImpl renderResponseImpl =
1180 (RenderResponseImpl)request.getAttribute(
1181 JavaConstants.JAVAX_PORTLET_RESPONSE);
1182
1183 StringServletResponse stringResponse =
1184 (StringServletResponse)renderRequestImpl.getAttribute(
1185 WebKeys.STRING_SERVLET_RESPONSE);
1186
1187 if (stringResponse == null) {
1188 stringResponse = (StringServletResponse)
1189 renderResponseImpl.getHttpServletResponse();
1190
1191 ServletContext servletContext =
1192 (ServletContext)request.getAttribute(WebKeys.CTX);
1193
1194 Portlet portlet = processPortletRequest(
1195 request, response, PortletRequest.RENDER_PHASE);
1196
1197 RuntimePortletUtil.processPortlet(
1198 servletContext, request, stringResponse, renderRequestImpl,
1199 renderResponseImpl, portlet.getPortletId(), null, true);
1200
1201 if (Validator.isNull(stringResponse.getString())) {
1202 stringResponse.setString(null);
1203 }
1204 }
1205
1206 renderResponseImpl.transferHeaders(response);
1207
1208 if (stringResponse.isCalledGetOutputStream()) {
1209 UnsyncByteArrayOutputStream ubaos =
1210 stringResponse.getUnsyncByteArrayOutputStream();
1211
1212 InputStream is = new UnsyncByteArrayInputStream(
1213 ubaos.unsafeGetByteArray(), 0, ubaos.size());
1214
1215 ServletResponseUtil.sendFile(
1216 request, response, renderResponseImpl.getResourceName(), is,
1217 renderResponseImpl.getContentType());
1218 }
1219 else if (stringResponse.isCalledGetWriter()) {
1220 byte[] content = stringResponse.getString().getBytes(
1221 StringPool.UTF8);
1222
1223 ServletResponseUtil.sendFile(
1224 request, response, renderResponseImpl.getResourceName(),
1225 content, renderResponseImpl.getContentType());
1226 }
1227
1228 renderRequestImpl.cleanUp();
1229 }
1230
1231 protected Event serializeEvent(
1232 Event event, ClassLoader portletClassLoader) {
1233
1234 Serializable value = event.getValue();
1235
1236 if (value == null) {
1237 return event;
1238 }
1239
1240 Class<?> valueClass = value.getClass();
1241
1242 String valueClassName = valueClass.getName();
1243
1244 try {
1245 Class<?> loadedValueClass = portletClassLoader.loadClass(
1246 valueClassName);
1247
1248 if (loadedValueClass.equals(valueClass)) {
1249 return event;
1250 }
1251 }
1252 catch (ClassNotFoundException cnfe) {
1253 if (_log.isWarnEnabled()) {
1254 _log.warn(
1255 portletClassLoader.toString() + " does not contain " +
1256 valueClassName,
1257 cnfe);
1258 }
1259 }
1260
1261 EventImpl eventImpl = (EventImpl)event;
1262
1263 String base64Value = eventImpl.getBase64Value();
1264
1265 value = (Serializable)Base64.stringToObject(
1266 base64Value, portletClassLoader);
1267
1268 return new EventImpl(event.getName(), event.getQName(), value);
1269 }
1270
1271 private static Log _log = LogFactoryUtil.getLog(LayoutAction.class);
1272
1273 }