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