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.portlet.ActionResult;
018    import com.liferay.portal.kernel.portlet.PortletContainer;
019    import com.liferay.portal.kernel.portlet.PortletContainerException;
020    import com.liferay.portal.kernel.portlet.RestrictPortletServletRequest;
021    import com.liferay.portal.kernel.util.ServerDetector;
022    import com.liferay.portal.kernel.util.WebKeys;
023    import com.liferay.portal.model.Layout;
024    import com.liferay.portal.model.Portlet;
025    import com.liferay.portal.util.PropsValues;
026    
027    import java.util.List;
028    import java.util.Map;
029    
030    import javax.portlet.Event;
031    
032    import javax.servlet.http.HttpServletRequest;
033    import javax.servlet.http.HttpServletResponse;
034    
035    /**
036     * @author Shuyang Zhou
037     */
038    public class RestrictPortletContainerWrapper implements PortletContainer {
039    
040            public static PortletContainer createRestrictPortletContainerWrapper(
041                    PortletContainer portletContainer) {
042    
043                    if ((PropsValues.LAYOUT_PARALLEL_RENDER_ENABLE &&
044                             ServerDetector.isTomcat()) ||
045                            PropsValues.PORTLET_CONTAINER_RESTRICT) {
046    
047                            portletContainer = new RestrictPortletContainerWrapper(
048                                    portletContainer);
049                    }
050    
051                    return portletContainer;
052            }
053    
054            public RestrictPortletContainerWrapper(PortletContainer portletContainer) {
055                    _portletContainer = portletContainer;
056            }
057    
058            @Override
059            public void preparePortlet(HttpServletRequest request, Portlet portlet)
060                    throws PortletContainerException {
061    
062                    _portletContainer.preparePortlet(request, portlet);
063            }
064    
065            @Override
066            public ActionResult processAction(
067                            HttpServletRequest request, HttpServletResponse response,
068                            Portlet portlet)
069                    throws PortletContainerException {
070    
071                    RestrictPortletServletRequest restrictPortletServletRequest =
072                            new RestrictPortletServletRequest(request);
073    
074                    try {
075                            return _portletContainer.processAction(request, response, portlet);
076                    }
077                    finally {
078                            restrictPortletServletRequest.mergeSharedAttributes();
079                    }
080            }
081    
082            @Override
083            public List<Event> processEvent(
084                            HttpServletRequest request, HttpServletResponse response,
085                            Portlet portlet, Layout layout, Event event)
086                    throws PortletContainerException {
087    
088                    RestrictPortletServletRequest restrictPortletServletRequest =
089                            new RestrictPortletServletRequest(request);
090    
091                    try {
092                            return _portletContainer.processEvent(
093                                    request, response, portlet, layout, event);
094                    }
095                    finally {
096                            restrictPortletServletRequest.mergeSharedAttributes();
097                    }
098            }
099    
100            @Override
101            public void render(
102                            HttpServletRequest request, HttpServletResponse response,
103                            Portlet portlet)
104                    throws PortletContainerException {
105    
106                    RestrictPortletServletRequest restrictPortletServletRequest = null;
107    
108                    if (request instanceof RestrictPortletServletRequest) {
109                            restrictPortletServletRequest =
110                                    (RestrictPortletServletRequest)request;
111    
112                            Map<String, Object> attributes =
113                                    restrictPortletServletRequest.getAttributes();
114    
115                            if (attributes.containsKey(WebKeys.RENDER_PORTLET)) {
116                                    restrictPortletServletRequest =
117                                            new RestrictPortletServletRequest(request);
118                            }
119                    }
120                    else {
121                            restrictPortletServletRequest = new RestrictPortletServletRequest(
122                                    request);
123                    }
124    
125                    try {
126                            _portletContainer.render(request, response, portlet);
127                    }
128                    catch (Exception e) {
129                            throw new PortletContainerException(e);
130                    }
131                    finally {
132                            restrictPortletServletRequest.removeAttribute(WebKeys.RENDER_PATH);
133                            restrictPortletServletRequest.removeAttribute(
134                                    WebKeys.RENDER_PORTLET_COLUMN_COUNT);
135                            restrictPortletServletRequest.removeAttribute(
136                                    WebKeys.RENDER_PORTLET_COLUMN_ID);
137                            restrictPortletServletRequest.removeAttribute(
138                                    WebKeys.RENDER_PORTLET_COLUMN_POS);
139    
140                            // Don't merge when parallel rendering a portlet. The caller (worker
141                            // thread) should decide whether or not to merge shared attributes.
142                            // If we did merge here and the caller cancelled the parallel
143                            // rendering, then we would have corrupted the set of shared
144                            // attributes. The only safe way to merge shared attributes is for
145                            // the caller to merge after it has the render result.
146    
147                            Object lock = request.getAttribute(
148                                    WebKeys.PARALLEL_RENDERING_MERGE_LOCK);
149    
150                            if (lock == null) {
151                                    restrictPortletServletRequest.mergeSharedAttributes();
152                            }
153                    }
154            }
155    
156            @Override
157            public void serveResource(
158                            HttpServletRequest request, HttpServletResponse response,
159                            Portlet portlet)
160                    throws PortletContainerException {
161    
162                    RestrictPortletServletRequest restrictPortletServletRequest =
163                            new RestrictPortletServletRequest(request);
164    
165                    try {
166                            _portletContainer.serveResource(request, response, portlet);
167                    }
168                    catch (Exception e) {
169                            throw new PortletContainerException(e);
170                    }
171                    finally {
172                            restrictPortletServletRequest.mergeSharedAttributes();
173                    }
174            }
175    
176            private PortletContainer _portletContainer;
177    
178    }