001    /**
002     * Copyright (c) 2000-2013 Liferay, Inc. All rights reserved.
003     *
004     * This library is free software; you can redistribute it and/or modify it under
005     * the terms of the GNU Lesser General Public License as published by the Free
006     * Software Foundation; either version 2.1 of the License, or (at your option)
007     * any later version.
008     *
009     * This library is distributed in the hope that it will be useful, but WITHOUT
010     * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
011     * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
012     * details.
013     */
014    
015    package com.liferay.portlet;
016    
017    import com.liferay.portal.kernel.exception.PortalException;
018    import com.liferay.portal.kernel.exception.SystemException;
019    import com.liferay.portal.kernel.language.LanguageUtil;
020    import com.liferay.portal.kernel.log.Log;
021    import com.liferay.portal.kernel.log.LogFactoryUtil;
022    import com.liferay.portal.kernel.portlet.ActionResult;
023    import com.liferay.portal.kernel.portlet.LiferayPortletConfig;
024    import com.liferay.portal.kernel.portlet.LiferayPortletMode;
025    import com.liferay.portal.kernel.portlet.PortletContainer;
026    import com.liferay.portal.kernel.portlet.PortletContainerException;
027    import com.liferay.portal.kernel.portlet.PortletContainerUtil;
028    import com.liferay.portal.kernel.portlet.PortletModeFactory;
029    import com.liferay.portal.kernel.portlet.WindowStateFactory;
030    import com.liferay.portal.kernel.security.pacl.DoPrivileged;
031    import com.liferay.portal.kernel.servlet.BufferCacheServletResponse;
032    import com.liferay.portal.kernel.servlet.DirectRequestDispatcherFactoryUtil;
033    import com.liferay.portal.kernel.servlet.HttpHeaders;
034    import com.liferay.portal.kernel.servlet.TempAttributesServletRequest;
035    import com.liferay.portal.kernel.struts.LastPath;
036    import com.liferay.portal.kernel.upload.UploadServletRequest;
037    import com.liferay.portal.kernel.util.ArrayUtil;
038    import com.liferay.portal.kernel.util.ContentTypes;
039    import com.liferay.portal.kernel.util.JavaConstants;
040    import com.liferay.portal.kernel.util.ParamUtil;
041    import com.liferay.portal.kernel.util.StringBundler;
042    import com.liferay.portal.kernel.util.Validator;
043    import com.liferay.portal.kernel.util.WebKeys;
044    import com.liferay.portal.kernel.webdav.WebDAVStorage;
045    import com.liferay.portal.kernel.xml.QName;
046    import com.liferay.portal.model.Layout;
047    import com.liferay.portal.model.LayoutTypePortlet;
048    import com.liferay.portal.model.Portlet;
049    import com.liferay.portal.model.PortletPreferencesIds;
050    import com.liferay.portal.model.PublicRenderParameter;
051    import com.liferay.portal.model.User;
052    import com.liferay.portal.security.auth.AuthTokenUtil;
053    import com.liferay.portal.security.permission.ActionKeys;
054    import com.liferay.portal.security.permission.PermissionChecker;
055    import com.liferay.portal.security.permission.PermissionThreadLocal;
056    import com.liferay.portal.service.PortletPreferencesLocalServiceUtil;
057    import com.liferay.portal.service.ServiceContext;
058    import com.liferay.portal.service.ServiceContextFactory;
059    import com.liferay.portal.service.ServiceContextThreadLocal;
060    import com.liferay.portal.service.permission.LayoutPermissionUtil;
061    import com.liferay.portal.service.permission.PortletPermissionUtil;
062    import com.liferay.portal.theme.PortletDisplay;
063    import com.liferay.portal.theme.PortletDisplayFactory;
064    import com.liferay.portal.theme.ThemeDisplay;
065    import com.liferay.portal.upload.UploadServletRequestImpl;
066    import com.liferay.portal.util.PortalUtil;
067    import com.liferay.portal.util.PropsValues;
068    import com.liferay.util.SerializableUtil;
069    
070    import java.io.Serializable;
071    import java.io.Writer;
072    
073    import java.util.HashMap;
074    import java.util.List;
075    import java.util.Map;
076    
077    import javax.portlet.Event;
078    import javax.portlet.PortletConfig;
079    import javax.portlet.PortletContext;
080    import javax.portlet.PortletMode;
081    import javax.portlet.PortletPreferences;
082    import javax.portlet.PortletRequest;
083    import javax.portlet.PortletResponse;
084    import javax.portlet.PortletURL;
085    import javax.portlet.RenderRequest;
086    import javax.portlet.RenderResponse;
087    import javax.portlet.WindowState;
088    
089    import javax.servlet.RequestDispatcher;
090    import javax.servlet.ServletContext;
091    import javax.servlet.http.HttpServletRequest;
092    import javax.servlet.http.HttpServletResponse;
093    import javax.servlet.http.HttpSession;
094    
095    /**
096     * @author Shuyang Zhou
097     * @author Raymond Augé
098     */
099    @DoPrivileged
100    public class PortletContainerImpl implements PortletContainer {
101    
102            public void preparePortlet(HttpServletRequest request, Portlet portlet)
103                    throws PortletContainerException {
104    
105                    try {
106                            _doPreparePortlet(request, portlet);
107                    }
108                    catch (Exception e) {
109                            throw new PortletContainerException(e);
110                    }
111            }
112    
113            public ActionResult processAction(
114                            HttpServletRequest request, HttpServletResponse response,
115                            Portlet portlet)
116                    throws PortletContainerException {
117    
118                    try {
119                            return _doProcessAction(request, response, portlet);
120                    }
121                    catch (Exception e) {
122                            throw new PortletContainerException(e);
123                    }
124            }
125    
126            public List<Event> processEvent(
127                            HttpServletRequest request, HttpServletResponse response,
128                            Portlet portlet, Layout layout, Event event)
129                    throws PortletContainerException {
130    
131                    try {
132                            return _doProcessEvent(request, response, portlet, layout, event);
133                    }
134                    catch (Exception e) {
135                            throw new PortletContainerException(e);
136                    }
137            }
138    
139            public void render(
140                            HttpServletRequest request, HttpServletResponse response,
141                            Portlet portlet)
142                    throws PortletContainerException {
143    
144                    try {
145                            _doRender(request, response, portlet);
146                    }
147                    catch (Exception e) {
148                            throw new PortletContainerException(e);
149                    }
150            }
151    
152            public void serveResource(
153                            HttpServletRequest request, HttpServletResponse response,
154                            Portlet portlet)
155                    throws PortletContainerException {
156    
157                    try {
158                            _doServeResource(request, response, portlet);
159                    }
160                    catch (Exception e) {
161                            throw new PortletContainerException(e);
162                    }
163            }
164    
165            protected HttpServletRequest getOwnerLayoutRequestWrapper(
166                            HttpServletRequest request, Portlet portlet)
167                    throws Exception {
168    
169                    if (!PropsValues.PORTLET_EVENT_DISTRIBUTION_LAYOUT_SET) {
170                            return request;
171                    }
172    
173                    ThemeDisplay themeDisplay = (ThemeDisplay)request.getAttribute(
174                            WebKeys.THEME_DISPLAY);
175    
176                    Layout currentLayout = themeDisplay.getLayout();
177    
178                    Layout requestLayout = (Layout)request.getAttribute(WebKeys.LAYOUT);
179    
180                    List<LayoutTypePortlet> layoutTypePortlets =
181                            PortletContainerUtil.getLayoutTypePortlets(requestLayout);
182    
183                    Layout ownerLayout = null;
184                    LayoutTypePortlet ownerLayoutTypePortlet = null;
185    
186                    for (LayoutTypePortlet layoutTypePortlet : layoutTypePortlets) {
187                            if (layoutTypePortlet.hasPortletId(portlet.getPortletId())) {
188                                    ownerLayoutTypePortlet = layoutTypePortlet;
189    
190                                    ownerLayout = layoutTypePortlet.getLayout();
191    
192                                    break;
193                            }
194                    }
195    
196                    if ((ownerLayout != null) && !currentLayout.equals(ownerLayout)) {
197                            ThemeDisplay themeDisplayClone = (ThemeDisplay)themeDisplay.clone();
198    
199                            themeDisplayClone.setLayout(ownerLayout);
200                            themeDisplayClone.setLayoutTypePortlet(ownerLayoutTypePortlet);
201    
202                            TempAttributesServletRequest tempAttributesServletRequest =
203                                    new TempAttributesServletRequest(request);
204    
205                            tempAttributesServletRequest.setTempAttribute(
206                                    WebKeys.THEME_DISPLAY, themeDisplayClone);
207                            tempAttributesServletRequest.setTempAttribute(
208                                    WebKeys.LAYOUT, ownerLayout);
209    
210                            return tempAttributesServletRequest;
211                    }
212    
213                    return request;
214            }
215    
216            protected long getScopeGroupId(
217                            HttpServletRequest request, Layout layout, String portletId)
218                    throws PortalException, SystemException {
219    
220                    long scopeGroupId = 0;
221    
222                    Layout requestLayout = (Layout)request.getAttribute(WebKeys.LAYOUT);
223    
224                    try {
225                            request.setAttribute(WebKeys.LAYOUT, layout);
226    
227                            scopeGroupId = PortalUtil.getScopeGroupId(request, portletId);
228                    }
229                    finally {
230                            request.setAttribute(WebKeys.LAYOUT, requestLayout);
231                    }
232    
233                    if (scopeGroupId <= 0) {
234                            scopeGroupId = PortalUtil.getScopeGroupId(layout, portletId);
235                    }
236    
237                    return scopeGroupId;
238            }
239    
240            protected void processPublicRenderParameters(
241                    HttpServletRequest request, Layout layout, Portlet portlet) {
242    
243                    ThemeDisplay themeDisplay = (ThemeDisplay)request.getAttribute(
244                            WebKeys.THEME_DISPLAY);
245    
246                    Map<String, String[]> publicRenderParameters =
247                            PublicRenderParametersPool.get(request, layout.getPlid());
248    
249                    Map<String, String[]> parameters = request.getParameterMap();
250    
251                    for (Map.Entry<String, String[]> entry : parameters.entrySet()) {
252                            String name = entry.getKey();
253    
254                            QName qName = PortletQNameUtil.getQName(name);
255    
256                            if (qName == null) {
257                                    continue;
258                            }
259    
260                            PublicRenderParameter publicRenderParameter =
261                                    portlet.getPublicRenderParameter(
262                                            qName.getNamespaceURI(), qName.getLocalPart());
263    
264                            if (publicRenderParameter == null) {
265                                    continue;
266                            }
267    
268                            String publicRenderParameterName =
269                                    PortletQNameUtil.getPublicRenderParameterName(qName);
270    
271                            if (name.startsWith(
272                                            PortletQName.PUBLIC_RENDER_PARAMETER_NAMESPACE)) {
273    
274                                    String[] values = entry.getValue();
275    
276                                    if (themeDisplay.isLifecycleAction()) {
277                                            String[] oldValues = publicRenderParameters.get(
278                                                    publicRenderParameterName);
279    
280                                            if ((oldValues != null) && (oldValues.length != 0)) {
281                                                    values = ArrayUtil.append(values, oldValues);
282                                            }
283                                    }
284    
285                                    publicRenderParameters.put(publicRenderParameterName, values);
286                            }
287                            else {
288                                    publicRenderParameters.remove(publicRenderParameterName);
289                            }
290                    }
291            }
292    
293            protected Event serializeEvent(
294                    Event event, ClassLoader portletClassLoader) {
295    
296                    Serializable value = event.getValue();
297    
298                    if (value == null) {
299                            return event;
300                    }
301    
302                    Class<?> valueClass = value.getClass();
303    
304                    String valueClassName = valueClass.getName();
305    
306                    try {
307                            Class<?> loadedValueClass = portletClassLoader.loadClass(
308                                    valueClassName);
309    
310                            if (loadedValueClass.equals(valueClass)) {
311                                    return event;
312                            }
313                    }
314                    catch (ClassNotFoundException cnfe) {
315                            throw new RuntimeException(cnfe);
316                    }
317    
318                    byte[] serializedValue = SerializableUtil.serialize(value);
319    
320                    value = (Serializable)SerializableUtil.deserialize(
321                            serializedValue, portletClassLoader);
322    
323                    return new EventImpl(event.getName(), event.getQName(), value);
324            }
325    
326            private void _doPreparePortlet(HttpServletRequest request, Portlet portlet)
327                    throws Exception {
328    
329                    User user = PortalUtil.getUser(request);
330                    Layout layout = (Layout)request.getAttribute(WebKeys.LAYOUT);
331    
332                    ThemeDisplay themeDisplay = (ThemeDisplay)request.getAttribute(
333                            WebKeys.THEME_DISPLAY);
334    
335                    long scopeGroupId = PortalUtil.getScopeGroupId(
336                            request, portlet.getPortletId());
337                    long siteGroupId = PortalUtil.getSiteGroupId(scopeGroupId);
338    
339                    themeDisplay.setScopeGroupId(scopeGroupId);
340                    themeDisplay.setSiteGroupId(siteGroupId);
341    
342                    if (user != null) {
343                            HttpSession session = request.getSession();
344    
345                            InvokerPortletImpl.clearResponse(
346                                    session, layout.getPrimaryKey(), portlet.getPortletId(),
347                                    LanguageUtil.getLanguageId(request));
348                    }
349    
350                    processPublicRenderParameters(request, layout, portlet);
351    
352                    if (themeDisplay.isLifecycleRender() ||
353                            themeDisplay.isLifecycleResource()) {
354    
355                            WindowState windowState = WindowStateFactory.getWindowState(
356                                    ParamUtil.getString(request, "p_p_state"));
357    
358                            if (layout.isTypeControlPanel() &&
359                                    ((windowState == null) ||
360                                     windowState.equals(WindowState.NORMAL) ||
361                                     Validator.isNull(windowState.toString()))) {
362    
363                                    windowState = WindowState.MAXIMIZED;
364                            }
365    
366                            PortletMode portletMode = PortletModeFactory.getPortletMode(
367                                    ParamUtil.getString(request, "p_p_mode"));
368    
369                            PortalUtil.updateWindowState(
370                                    portlet.getPortletId(), user, layout, windowState, request);
371    
372                            PortalUtil.updatePortletMode(
373                                    portlet.getPortletId(), user, layout, portletMode, request);
374                    }
375            }
376    
377            private ActionResult _doProcessAction(
378                            HttpServletRequest request, HttpServletResponse response,
379                            Portlet portlet)
380                    throws Exception {
381    
382                    HttpServletRequest ownerLayoutRequest = getOwnerLayoutRequestWrapper(
383                            request, portlet);
384    
385                    Layout ownerLayout = (Layout)ownerLayoutRequest.getAttribute(
386                            WebKeys.LAYOUT);
387    
388                    boolean allowAddPortletDefaultResource =
389                            PortalUtil.isAllowAddPortletDefaultResource(
390                                    ownerLayoutRequest, portlet);
391    
392                    if (!allowAddPortletDefaultResource) {
393                            String url = null;
394    
395                            LastPath lastPath = (LastPath)request.getAttribute(
396                                    WebKeys.LAST_PATH);
397    
398                            if (lastPath != null) {
399                                    StringBundler sb = new StringBundler(3);
400    
401                                    sb.append(PortalUtil.getPortalURL(request));
402                                    sb.append(lastPath.getContextPath());
403                                    sb.append(lastPath.getPath());
404    
405                                    url = sb.toString();
406                            }
407                            else {
408                                    url = String.valueOf(request.getRequestURI());
409                            }
410    
411                            _log.error(
412                                    "Reject processAction for " + url + " on " +
413                                            portlet.getPortletId());
414    
415                            return ActionResult.EMPTY_ACTION_RESULT;
416                    }
417    
418                    Layout layout = (Layout)request.getAttribute(WebKeys.LAYOUT);
419    
420                    WindowState windowState = WindowStateFactory.getWindowState(
421                            ParamUtil.getString(request, "p_p_state"));
422    
423                    if (layout.isTypeControlPanel() &&
424                            ((windowState == null) || windowState.equals(WindowState.NORMAL) ||
425                             Validator.isNull(windowState.toString()))) {
426    
427                            windowState = WindowState.MAXIMIZED;
428                    }
429    
430                    PortletMode portletMode = PortletModeFactory.getPortletMode(
431                            ParamUtil.getString(request, "p_p_mode"));
432    
433                    PortletPreferencesIds portletPreferencesIds =
434                            PortletPreferencesFactoryUtil.getPortletPreferencesIds(
435                                    request, portlet.getPortletId());
436    
437                    PortletPreferences portletPreferences =
438                            PortletPreferencesLocalServiceUtil.getPreferences(
439                                    portletPreferencesIds);
440    
441                    ServletContext servletContext = (ServletContext)request.getAttribute(
442                            WebKeys.CTX);
443    
444                    InvokerPortlet invokerPortlet = PortletInstanceFactoryUtil.create(
445                            portlet, servletContext);
446    
447                    PortletConfig portletConfig = PortletConfigFactoryUtil.create(
448                            portlet, servletContext);
449                    PortletContext portletContext = portletConfig.getPortletContext();
450    
451                    String contentType = request.getHeader(HttpHeaders.CONTENT_TYPE);
452    
453                    if (_log.isDebugEnabled()) {
454                            _log.debug("Content type " + contentType);
455                    }
456    
457                    UploadServletRequest uploadServletRequest = null;
458    
459                    try {
460                            if ((contentType != null) &&
461                                    contentType.startsWith(ContentTypes.MULTIPART_FORM_DATA)) {
462    
463                                    LiferayPortletConfig liferayPortletConfig =
464                                            (LiferayPortletConfig)invokerPortlet.getPortletConfig();
465    
466                                    if (invokerPortlet.isStrutsPortlet() ||
467                                            liferayPortletConfig.isCopyRequestParameters() ||
468                                            !liferayPortletConfig.isWARFile()) {
469    
470                                            uploadServletRequest = new UploadServletRequestImpl(
471                                                    request);
472    
473                                            request = uploadServletRequest;
474                                    }
475                            }
476    
477                            if (PropsValues.AUTH_TOKEN_CHECK_ENABLED &&
478                                    invokerPortlet.isCheckAuthToken()) {
479    
480                                    AuthTokenUtil.check(request);
481                            }
482    
483                            ActionRequestImpl actionRequestImpl = ActionRequestFactory.create(
484                                    request, portlet, invokerPortlet, portletContext, windowState,
485                                    portletMode, portletPreferences, layout.getPlid());
486    
487                            User user = PortalUtil.getUser(request);
488    
489                            ActionResponseImpl actionResponseImpl =
490                                    ActionResponseFactory.create(
491                                            actionRequestImpl, response, portlet.getPortletId(), user,
492                                            layout, windowState, portletMode);
493    
494                            actionRequestImpl.defineObjects(portletConfig, actionResponseImpl);
495    
496                            ServiceContext serviceContext = ServiceContextFactory.getInstance(
497                                    actionRequestImpl);
498    
499                            ServiceContextThreadLocal.pushServiceContext(serviceContext);
500    
501                            PermissionChecker permissionChecker =
502                                    PermissionThreadLocal.getPermissionChecker();
503    
504                            ThemeDisplay themeDisplay = (ThemeDisplay)request.getAttribute(
505                                    WebKeys.THEME_DISPLAY);
506    
507                            long scopeGroupId = themeDisplay.getScopeGroupId();
508    
509                            boolean access = PortletPermissionUtil.hasAccessPermission(
510                                    permissionChecker, scopeGroupId, ownerLayout, portlet,
511                                    portletMode);
512    
513                            if (access) {
514                                    invokerPortlet.processAction(
515                                            actionRequestImpl, actionResponseImpl);
516    
517                                    actionResponseImpl.transferHeaders(response);
518                            }
519    
520                            RenderParametersPool.put(
521                                    request, layout.getPlid(), portlet.getPortletId(),
522                                    actionResponseImpl.getRenderParameterMap());
523    
524                            List<Event> events = actionResponseImpl.getEvents();
525    
526                            String redirectLocation = actionResponseImpl.getRedirectLocation();
527    
528                            if (Validator.isNull(redirectLocation) &&
529                                    portlet.isActionURLRedirect()) {
530    
531                                    PortletURL portletURL = new PortletURLImpl(
532                                            actionRequestImpl, actionRequestImpl.getPortletName(),
533                                            layout.getPlid(), PortletRequest.RENDER_PHASE);
534    
535                                    Map<String, String[]> renderParameters =
536                                            actionResponseImpl.getRenderParameterMap();
537    
538                                    for (Map.Entry<String, String[]> entry :
539                                                    renderParameters.entrySet()) {
540    
541                                            String key = entry.getKey();
542                                            String[] value = entry.getValue();
543    
544                                            portletURL.setParameter(key, value);
545                                    }
546    
547                                    redirectLocation = portletURL.toString();
548                            }
549    
550                            return new ActionResult(events, redirectLocation);
551                    }
552                    finally {
553                            if (uploadServletRequest != null) {
554                                    uploadServletRequest.cleanUp();
555                            }
556    
557                            ServiceContextThreadLocal.popServiceContext();
558                    }
559            }
560    
561            private List<Event> _doProcessEvent(
562                            HttpServletRequest request, HttpServletResponse response,
563                            Portlet portlet, Layout layout, Event event)
564                    throws Exception {
565    
566                    ServletContext servletContext = (ServletContext)request.getAttribute(
567                            WebKeys.CTX);
568    
569                    InvokerPortlet invokerPortlet = PortletInstanceFactoryUtil.create(
570                            portlet, servletContext);
571    
572                    PortletConfig portletConfig = PortletConfigFactoryUtil.create(
573                            portlet, servletContext);
574                    PortletContext portletContext = portletConfig.getPortletContext();
575    
576                    LayoutTypePortlet layoutTypePortlet =
577                            (LayoutTypePortlet)layout.getLayoutType();
578    
579                    WindowState windowState = null;
580    
581                    if (layoutTypePortlet.hasStateMaxPortletId(portlet.getPortletId())) {
582                            windowState = WindowState.MAXIMIZED;
583                    }
584                    else if (layoutTypePortlet.hasStateMinPortletId(
585                                            portlet.getPortletId())) {
586    
587                            windowState = WindowState.MINIMIZED;
588                    }
589                    else {
590                            windowState = WindowState.NORMAL;
591                    }
592    
593                    PortletMode portletMode = null;
594    
595                    if (layoutTypePortlet.hasModeAboutPortletId(portlet.getPortletId())) {
596                            portletMode = LiferayPortletMode.ABOUT;
597                    }
598                    else if (layoutTypePortlet.hasModeConfigPortletId(
599                                            portlet.getPortletId())) {
600    
601                            portletMode = LiferayPortletMode.CONFIG;
602                    }
603                    else if (layoutTypePortlet.hasModeEditPortletId(
604                                            portlet.getPortletId())) {
605    
606                            portletMode = PortletMode.EDIT;
607                    }
608                    else if (layoutTypePortlet.hasModeEditDefaultsPortletId(
609                                            portlet.getPortletId())) {
610    
611                            portletMode = LiferayPortletMode.EDIT_DEFAULTS;
612                    }
613                    else if (layoutTypePortlet.hasModeEditGuestPortletId(
614                                            portlet.getPortletId())) {
615    
616                            portletMode = LiferayPortletMode.EDIT_GUEST;
617                    }
618                    else if (layoutTypePortlet.hasModeHelpPortletId(
619                                            portlet.getPortletId())) {
620    
621                            portletMode = PortletMode.HELP;
622                    }
623                    else if (layoutTypePortlet.hasModePreviewPortletId(
624                                            portlet.getPortletId())) {
625    
626                            portletMode = LiferayPortletMode.PREVIEW;
627                    }
628                    else if (layoutTypePortlet.hasModePrintPortletId(
629                                            portlet.getPortletId())) {
630    
631                            portletMode = LiferayPortletMode.PRINT;
632                    }
633                    else {
634                            portletMode = PortletMode.VIEW;
635                    }
636    
637                    long scopeGroupId = getScopeGroupId(
638                            request, layout, portlet.getPortletId());
639    
640                    PortletPreferences portletPreferences =
641                            PortletPreferencesFactoryUtil.getPortletSetup(
642                                    scopeGroupId, layout, portlet.getPortletId(), null);
643    
644                    EventRequestImpl eventRequestImpl = EventRequestFactory.create(
645                            request, portlet, invokerPortlet, portletContext, windowState,
646                            portletMode, portletPreferences, layout.getPlid());
647    
648                    eventRequestImpl.setEvent(
649                            serializeEvent(event, invokerPortlet.getPortletClassLoader()));
650    
651                    User user = PortalUtil.getUser(request);
652                    Layout requestLayout = (Layout)request.getAttribute(WebKeys.LAYOUT);
653    
654                    EventResponseImpl eventResponseImpl = EventResponseFactory.create(
655                            eventRequestImpl, response, portlet.getPortletId(), user,
656                            requestLayout);
657    
658                    eventRequestImpl.defineObjects(portletConfig, eventResponseImpl);
659    
660                    try {
661                            invokerPortlet.processEvent(eventRequestImpl, eventResponseImpl);
662    
663                            if (eventResponseImpl.isCalledSetRenderParameter()) {
664                                    Map<String, String[]> renderParameterMap =
665                                            new HashMap<String, String[]>();
666    
667                                    renderParameterMap.putAll(
668                                            eventResponseImpl.getRenderParameterMap());
669    
670                                    RenderParametersPool.put(
671                                            request, requestLayout.getPlid(), portlet.getPortletId(),
672                                            renderParameterMap);
673                            }
674    
675                            return eventResponseImpl.getEvents();
676                    }
677                    finally {
678                            eventRequestImpl.cleanUp();
679                    }
680            }
681    
682            private void _doRender(
683                            HttpServletRequest request, HttpServletResponse response,
684                            Portlet portlet)
685                    throws Exception {
686    
687                    if ((portlet != null) && portlet.isInstanceable() &&
688                            !portlet.isAddDefaultResource()) {
689    
690                            String instanceId = portlet.getInstanceId();
691    
692                            if (!Validator.isPassword(instanceId)) {
693                                    if (_log.isDebugEnabled()) {
694                                            _log.debug(
695                                                    "Portlet " + portlet.getPortletId() +
696                                                            " is instanceable but does not have a valid " +
697                                                                    "instance id");
698                                    }
699    
700                                    portlet = null;
701                            }
702                    }
703    
704                    if (portlet == null) {
705                            return;
706                    }
707    
708                    // Capture the current portlet's settings to reset them once the child
709                    // portlet is rendered
710    
711                    ThemeDisplay themeDisplay = (ThemeDisplay)request.getAttribute(
712                            WebKeys.THEME_DISPLAY);
713    
714                    PortletDisplay portletDisplay = themeDisplay.getPortletDisplay();
715    
716                    PortletDisplay portletDisplayClone = PortletDisplayFactory.create();
717    
718                    portletDisplay.copyTo(portletDisplayClone);
719    
720                    PortletConfig portletConfig = (PortletConfig)request.getAttribute(
721                            JavaConstants.JAVAX_PORTLET_CONFIG);
722    
723                    PortletRequest portletRequest = (PortletRequest)request.getAttribute(
724                            JavaConstants.JAVAX_PORTLET_REQUEST);
725    
726                    if (!(portletRequest instanceof RenderRequest)) {
727                            portletRequest = null;
728                    }
729    
730                    PortletResponse portletResponse = (PortletResponse)request.getAttribute(
731                            JavaConstants.JAVAX_PORTLET_RESPONSE);
732    
733                    if (!(portletResponse instanceof RenderResponse)) {
734                            portletResponse = null;
735                    }
736    
737                    String lifecycle = (String)request.getAttribute(
738                            PortletRequest.LIFECYCLE_PHASE);
739    
740                    request.setAttribute(WebKeys.RENDER_PORTLET, portlet);
741    
742                    String path = (String)request.getAttribute(WebKeys.RENDER_PATH);
743    
744                    if (path == null) {
745                            path = "/html/portal/render_portlet.jsp";
746                    }
747    
748                    RequestDispatcher requestDispatcher =
749                            DirectRequestDispatcherFactoryUtil.getRequestDispatcher(
750                                    request, path);
751    
752                    BufferCacheServletResponse bufferCacheServletResponse = null;
753    
754                    boolean writeOutput = false;
755    
756                    if (response instanceof BufferCacheServletResponse) {
757                            bufferCacheServletResponse = (BufferCacheServletResponse)response;
758                    }
759                    else {
760                            writeOutput = true;
761                            bufferCacheServletResponse = new BufferCacheServletResponse(
762                                    response);
763                    }
764    
765                    try {
766                            requestDispatcher.include(request, bufferCacheServletResponse);
767    
768                            Boolean portletConfiguratorVisibility =
769                                    (Boolean)request.getAttribute(
770                                            WebKeys.PORTLET_CONFIGURATOR_VISIBILITY);
771    
772                            if (portletConfiguratorVisibility != null) {
773                                    request.removeAttribute(
774                                            WebKeys.PORTLET_CONFIGURATOR_VISIBILITY);
775    
776                                    Layout layout = themeDisplay.getLayout();
777    
778                                    if (!layout.isTypeControlPanel() &&
779                                            !LayoutPermissionUtil.contains(
780                                                    themeDisplay.getPermissionChecker(), layout,
781                                                    ActionKeys.UPDATE) &&
782                                            !PortletPermissionUtil.contains(
783                                                    themeDisplay.getPermissionChecker(), layout,
784                                                    portlet.getPortletId(), ActionKeys.CONFIGURATION)) {
785    
786                                            bufferCacheServletResponse.setCharBuffer(null);
787    
788                                            return;
789                                    }
790                            }
791    
792                            if (writeOutput) {
793                                    Writer writer = response.getWriter();
794    
795                                    writer.write(bufferCacheServletResponse.getString());
796                            }
797                    }
798                    finally {
799                            portletDisplay.copyFrom(portletDisplayClone);
800    
801                            portletDisplayClone.recycle();
802    
803                            if (portletConfig != null) {
804                                    request.setAttribute(
805                                            JavaConstants.JAVAX_PORTLET_CONFIG, portletConfig);
806                            }
807    
808                            if (portletRequest != null) {
809                                    request.setAttribute(
810                                            JavaConstants.JAVAX_PORTLET_REQUEST, portletRequest);
811                            }
812    
813                            if (portletResponse != null) {
814                                    request.setAttribute(
815                                            JavaConstants.JAVAX_PORTLET_RESPONSE, portletResponse);
816                            }
817    
818                            if (lifecycle != null) {
819                                    request.setAttribute(PortletRequest.LIFECYCLE_PHASE, lifecycle);
820                            }
821    
822                            request.removeAttribute(WebKeys.RENDER_PORTLET);
823                    }
824            }
825    
826            private void _doServeResource(
827                            HttpServletRequest request, HttpServletResponse response,
828                            Portlet portlet)
829                    throws Exception {
830    
831                    HttpServletRequest ownerLayoutRequest = getOwnerLayoutRequestWrapper(
832                            request, portlet);
833    
834                    Layout ownerLayout = (Layout)ownerLayoutRequest.getAttribute(
835                            WebKeys.LAYOUT);
836    
837                    boolean allowAddPortletDefaultResource =
838                            PortalUtil.isAllowAddPortletDefaultResource(
839                                    ownerLayoutRequest, portlet);
840    
841                    if (!allowAddPortletDefaultResource) {
842                            String url = null;
843    
844                            LastPath lastPath = (LastPath)request.getAttribute(
845                                    WebKeys.LAST_PATH);
846    
847                            if (lastPath != null) {
848                                    StringBundler sb = new StringBundler(3);
849    
850                                    sb.append(PortalUtil.getPortalURL(request));
851                                    sb.append(lastPath.getContextPath());
852                                    sb.append(lastPath.getPath());
853    
854                                    url = sb.toString();
855                            }
856                            else {
857                                    url = String.valueOf(request.getRequestURI());
858                            }
859    
860                            response.setHeader(
861                                    HttpHeaders.CACHE_CONTROL,
862                                    HttpHeaders.CACHE_CONTROL_NO_CACHE_VALUE);
863                            response.setStatus(HttpServletResponse.SC_BAD_REQUEST);
864    
865                            _log.error(
866                                    "Reject serveResource for " + url + " on " +
867                                            portlet.getPortletId());
868    
869                            return;
870                    }
871    
872                    WindowState windowState = (WindowState)request.getAttribute(
873                            WebKeys.WINDOW_STATE);
874    
875                    PortletMode portletMode = PortletModeFactory.getPortletMode(
876                            ParamUtil.getString(request, "p_p_mode"));
877    
878                    PortletPreferencesIds portletPreferencesIds =
879                            PortletPreferencesFactoryUtil.getPortletPreferencesIds(
880                                    request, portlet.getPortletId());
881    
882                    PortletPreferences portletPreferences =
883                            PortletPreferencesLocalServiceUtil.getPreferences(
884                                    portletPreferencesIds);
885    
886                    ServletContext servletContext = (ServletContext)request.getAttribute(
887                            WebKeys.CTX);
888    
889                    InvokerPortlet invokerPortlet = PortletInstanceFactoryUtil.create(
890                            portlet, servletContext);
891    
892                    PortletConfig portletConfig = PortletConfigFactoryUtil.create(
893                            portlet, servletContext);
894                    PortletContext portletContext = portletConfig.getPortletContext();
895    
896                    ThemeDisplay themeDisplay = (ThemeDisplay)request.getAttribute(
897                            WebKeys.THEME_DISPLAY);
898    
899                    PortletDisplay portletDisplay = themeDisplay.getPortletDisplay();
900    
901                    Layout layout = (Layout)request.getAttribute(WebKeys.LAYOUT);
902    
903                    String portletPrimaryKey = PortletPermissionUtil.getPrimaryKey(
904                            layout.getPlid(), portlet.getPortletId());
905    
906                    portletDisplay.setId(portlet.getPortletId());
907                    portletDisplay.setRootPortletId(portlet.getRootPortletId());
908                    portletDisplay.setInstanceId(portlet.getInstanceId());
909                    portletDisplay.setResourcePK(portletPrimaryKey);
910                    portletDisplay.setPortletName(portletConfig.getPortletName());
911                    portletDisplay.setNamespace(
912                            PortalUtil.getPortletNamespace(portlet.getPortletId()));
913    
914                    WebDAVStorage webDAVStorage = portlet.getWebDAVStorageInstance();
915    
916                    if (webDAVStorage != null) {
917                            portletDisplay.setWebDAVEnabled(true);
918                    }
919                    else {
920                            portletDisplay.setWebDAVEnabled(false);
921                    }
922    
923                    ResourceRequestImpl resourceRequestImpl = ResourceRequestFactory.create(
924                            request, portlet, invokerPortlet, portletContext, windowState,
925                            portletMode, portletPreferences, layout.getPlid());
926    
927                    long companyId = PortalUtil.getCompanyId(request);
928    
929                    ResourceResponseImpl resourceResponseImpl =
930                            ResourceResponseFactory.create(
931                                    resourceRequestImpl, response, portlet.getPortletId(),
932                                    companyId);
933    
934                    resourceRequestImpl.defineObjects(portletConfig, resourceResponseImpl);
935    
936                    try {
937                            ServiceContext serviceContext = ServiceContextFactory.getInstance(
938                                    resourceRequestImpl);
939    
940                            ServiceContextThreadLocal.pushServiceContext(serviceContext);
941    
942                            PermissionChecker permissionChecker =
943                                    PermissionThreadLocal.getPermissionChecker();
944    
945                            long scopeGroupId = themeDisplay.getScopeGroupId();
946    
947                            boolean access = PortletPermissionUtil.hasAccessPermission(
948                                    permissionChecker, scopeGroupId, ownerLayout, portlet,
949                                    portletMode);
950    
951                            if (access) {
952                                    invokerPortlet.serveResource(
953                                            resourceRequestImpl, resourceResponseImpl);
954    
955                                    resourceResponseImpl.transferHeaders(response);
956                            }
957                    }
958                    finally {
959                            ServiceContextThreadLocal.popServiceContext();
960                    }
961            }
962    
963            private static Log _log = LogFactoryUtil.getLog(PortletContainerImpl.class);
964    
965    }