001    /**
002     * Copyright (c) 2000-present 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.portal.kernel.portlet;
016    
017    import com.liferay.portal.kernel.exception.SystemException;
018    import com.liferay.portal.kernel.security.pacl.permission.PortalRuntimePermission;
019    import com.liferay.portal.kernel.servlet.TempAttributesServletRequest;
020    import com.liferay.portal.kernel.util.GetterUtil;
021    import com.liferay.portal.kernel.util.PropsKeys;
022    import com.liferay.portal.kernel.util.PropsUtil;
023    import com.liferay.portal.kernel.util.ServerDetector;
024    import com.liferay.portal.kernel.util.StringUtil;
025    import com.liferay.portal.kernel.util.Validator;
026    import com.liferay.portal.kernel.util.WebKeys;
027    import com.liferay.portal.kernel.xml.QName;
028    import com.liferay.portal.model.Layout;
029    import com.liferay.portal.model.LayoutConstants;
030    import com.liferay.portal.model.LayoutTypePortlet;
031    import com.liferay.portal.model.Portlet;
032    import com.liferay.portal.service.LayoutLocalServiceUtil;
033    
034    import java.io.IOException;
035    
036    import java.util.ArrayList;
037    import java.util.Collections;
038    import java.util.List;
039    
040    import javax.portlet.Event;
041    
042    import javax.servlet.http.HttpServletRequest;
043    import javax.servlet.http.HttpServletResponse;
044    
045    /**
046     * @author Shuyang Zhou
047     * @author Raymond Aug??
048     */
049    public class PortletContainerUtil {
050    
051            public static List<LayoutTypePortlet> getLayoutTypePortlets(Layout layout)
052                    throws PortletContainerException {
053    
054                    if (_PORTLET_EVENT_DISTRIBUTION_LAYOUT_SET) {
055                            List<Layout> layouts = null;
056    
057                            try {
058                                    layouts = LayoutLocalServiceUtil.getLayouts(
059                                            layout.getGroupId(), layout.isPrivateLayout(),
060                                            LayoutConstants.TYPE_PORTLET);
061                            }
062                            catch (SystemException se) {
063                                    throw new PortletContainerException(se);
064                            }
065    
066                            List<LayoutTypePortlet> layoutTypePortlets =
067                                    new ArrayList<LayoutTypePortlet>(layouts.size());
068    
069                            for (Layout curLayout : layouts) {
070                                    LayoutTypePortlet layoutTypePortlet =
071                                            (LayoutTypePortlet)curLayout.getLayoutType();
072    
073                                    layoutTypePortlets.add(layoutTypePortlet);
074                            }
075    
076                            return layoutTypePortlets;
077                    }
078    
079                    if (layout.isTypePortlet()) {
080                            List<LayoutTypePortlet> layoutTypePortlets =
081                                    new ArrayList<LayoutTypePortlet>(1);
082    
083                            LayoutTypePortlet layoutTypePortlet =
084                                    (LayoutTypePortlet)layout.getLayoutType();
085    
086                            layoutTypePortlets.add(layoutTypePortlet);
087    
088                            return layoutTypePortlets;
089                    }
090    
091                    return Collections.emptyList();
092            }
093    
094            public static PortletContainer getPortletContainer() {
095                    PortalRuntimePermission.checkGetBeanProperty(
096                            PortletContainerUtil.class);
097    
098                    return _portletContainer;
099            }
100    
101            public static void preparePortlet(
102                            HttpServletRequest request, Portlet portlet)
103                    throws PortletContainerException {
104    
105                    getPortletContainer().preparePortlet(request, portlet);
106            }
107    
108            public static void processAction(
109                            HttpServletRequest request, HttpServletResponse response,
110                            Portlet portlet)
111                    throws PortletContainerException {
112    
113                    PortletContainer portletContainer = getPortletContainer();
114    
115                    ActionResult actionResult = portletContainer.processAction(
116                            request, response, portlet);
117    
118                    List<Event> events = actionResult.getEvents();
119    
120                    if (!events.isEmpty()) {
121                            _processEvents(request, response, events);
122                    }
123    
124                    String location = actionResult.getLocation();
125    
126                    if (Validator.isNotNull(location)) {
127                            try {
128                                    response.sendRedirect(location);
129                            }
130                            catch (IOException ioe) {
131                                    throw new PortletContainerException(ioe);
132                            }
133                    }
134            }
135    
136            public static void processEvent(
137                            HttpServletRequest request, HttpServletResponse response,
138                            Portlet portlet, Layout layout, Event event)
139                    throws PortletContainerException {
140    
141                    PortletContainer portletContainer = getPortletContainer();
142    
143                    List<Event> events = portletContainer.processEvent(
144                            request, response, portlet, layout, event);
145    
146                    if (!events.isEmpty()) {
147                            _processEvents(request, response, events);
148                    }
149            }
150    
151            public static void render(
152                            HttpServletRequest request, HttpServletResponse response,
153                            Portlet portlet)
154                    throws PortletContainerException {
155    
156                    getPortletContainer().render(request, response, portlet);
157            }
158    
159            public static void serveResource(
160                            HttpServletRequest request, HttpServletResponse response,
161                            Portlet portlet)
162                    throws PortletContainerException {
163    
164                    getPortletContainer().serveResource(request, response, portlet);
165            }
166    
167            public static HttpServletRequest setupOptionalRenderParameters(
168                    HttpServletRequest request, String renderPath, String columnId,
169                    Integer columnPos, Integer columnCount) {
170    
171                    return setupOptionalRenderParameters(
172                            request, renderPath, columnId, columnPos, columnCount, null, null);
173            }
174    
175            public static HttpServletRequest setupOptionalRenderParameters(
176                    HttpServletRequest request, String renderPath, String columnId,
177                    Integer columnPos, Integer columnCount, Boolean boundary,
178                    Boolean decorate) {
179    
180                    if ((_LAYOUT_PARALLEL_RENDER_ENABLE && ServerDetector.isTomcat()) ||
181                            _PORTLET_CONTAINER_RESTRICT) {
182    
183                            RestrictPortletServletRequest restrictPortletServletRequest =
184                                    new RestrictPortletServletRequest(request);
185    
186                            if (renderPath != null) {
187                                    restrictPortletServletRequest.setAttribute(
188                                            WebKeys.RENDER_PATH, renderPath);
189                            }
190    
191                            if (columnId != null) {
192                                    restrictPortletServletRequest.setAttribute(
193                                            WebKeys.RENDER_PORTLET_COLUMN_ID, columnId);
194                            }
195    
196                            if (columnPos != null) {
197                                    restrictPortletServletRequest.setAttribute(
198                                            WebKeys.RENDER_PORTLET_COLUMN_POS, columnPos);
199                            }
200    
201                            if (columnCount != null) {
202                                    restrictPortletServletRequest.setAttribute(
203                                            WebKeys.RENDER_PORTLET_COLUMN_COUNT, columnCount);
204                            }
205    
206                            if (boundary != null) {
207                                    restrictPortletServletRequest.setAttribute(
208                                            WebKeys.RENDER_PORTLET_BOUNDARY, boundary);
209                            }
210    
211                            if (decorate != null) {
212                                    restrictPortletServletRequest.setAttribute(
213                                            WebKeys.PORTLET_DECORATE, decorate);
214                            }
215    
216                            return restrictPortletServletRequest;
217                    }
218    
219                    TempAttributesServletRequest tempAttributesServletRequest =
220                            new TempAttributesServletRequest(request);
221    
222                    if (renderPath != null) {
223                            tempAttributesServletRequest.setTempAttribute(
224                                    WebKeys.RENDER_PATH, renderPath);
225                    }
226    
227                    if (columnId != null) {
228                            tempAttributesServletRequest.setTempAttribute(
229                                    WebKeys.RENDER_PORTLET_COLUMN_ID, columnId);
230                    }
231    
232                    if (columnPos != null) {
233                            tempAttributesServletRequest.setTempAttribute(
234                                    WebKeys.RENDER_PORTLET_COLUMN_POS, columnPos);
235                    }
236    
237                    if (columnCount != null) {
238                            tempAttributesServletRequest.setTempAttribute(
239                                    WebKeys.RENDER_PORTLET_COLUMN_COUNT, columnCount);
240                    }
241    
242                    return tempAttributesServletRequest;
243            }
244    
245            public void setPortletContainer(PortletContainer portletContainer) {
246                    PortalRuntimePermission.checkSetBeanProperty(getClass());
247    
248                    _portletContainer = portletContainer;
249            }
250    
251            private static void _processEvents(
252                            HttpServletRequest request, HttpServletResponse response,
253                            List<Event> events)
254                    throws PortletContainerException {
255    
256                    Layout layout = (Layout)request.getAttribute(WebKeys.LAYOUT);
257    
258                    List<LayoutTypePortlet> layoutTypePortlets = getLayoutTypePortlets(
259                            layout);
260    
261                    for (LayoutTypePortlet layoutTypePortlet : layoutTypePortlets) {
262                            List<Portlet> portlets = null;
263    
264                            try {
265                                    portlets = layoutTypePortlet.getAllPortlets();
266                            }
267                            catch (Exception e) {
268                                    throw new PortletContainerException(e);
269                            }
270    
271                            for (Portlet portlet : portlets) {
272                                    for (Event event : events) {
273                                            javax.xml.namespace.QName qName = event.getQName();
274    
275                                            QName processingQName = portlet.getProcessingEvent(
276                                                    qName.getNamespaceURI(), qName.getLocalPart());
277    
278                                            if (processingQName == null) {
279                                                    continue;
280                                            }
281    
282                                            processEvent(
283                                                    request, response, portlet,
284                                                    layoutTypePortlet.getLayout(), event);
285                                    }
286                            }
287                    }
288            }
289    
290            private static final boolean _LAYOUT_PARALLEL_RENDER_ENABLE =
291                    GetterUtil.getBoolean(
292                            PropsUtil.get(PropsKeys.LAYOUT_PARALLEL_RENDER_ENABLE));
293    
294            private static final boolean _PORTLET_CONTAINER_RESTRICT =
295                    GetterUtil.getBoolean(
296                            PropsUtil.get(PropsKeys.PORTLET_CONTAINER_RESTRICT));
297    
298            private static final boolean _PORTLET_EVENT_DISTRIBUTION_LAYOUT_SET =
299                    !StringUtil.equalsIgnoreCase(
300                            PropsUtil.get(PropsKeys.PORTLET_EVENT_DISTRIBUTION), "layout");
301    
302            private static PortletContainer _portletContainer;
303    
304    }