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.taglib.portletext;
016    
017    import com.liferay.portal.kernel.json.JSONFactoryUtil;
018    import com.liferay.portal.kernel.json.JSONObject;
019    import com.liferay.portal.kernel.log.Log;
020    import com.liferay.portal.kernel.log.LogFactoryUtil;
021    import com.liferay.portal.kernel.portlet.PortletContainerUtil;
022    import com.liferay.portal.kernel.portlet.PortletJSONUtil;
023    import com.liferay.portal.kernel.portlet.PortletLayoutListener;
024    import com.liferay.portal.kernel.portlet.PortletParameterUtil;
025    import com.liferay.portal.kernel.portlet.RestrictPortletServletRequest;
026    import com.liferay.portal.kernel.servlet.DynamicServletRequest;
027    import com.liferay.portal.kernel.servlet.PipingServletResponse;
028    import com.liferay.portal.kernel.util.MapUtil;
029    import com.liferay.portal.kernel.util.PrefixPredicateFilter;
030    import com.liferay.portal.kernel.util.StringPool;
031    import com.liferay.portal.kernel.util.WebKeys;
032    import com.liferay.portal.model.Layout;
033    import com.liferay.portal.model.LayoutTypePortlet;
034    import com.liferay.portal.model.Portlet;
035    import com.liferay.portal.service.PortletLocalServiceUtil;
036    import com.liferay.portal.service.PortletPreferencesLocalServiceUtil;
037    import com.liferay.portal.theme.ThemeDisplay;
038    import com.liferay.portal.util.PortletKeys;
039    import com.liferay.portlet.PortletPreferencesFactoryUtil;
040    
041    import java.util.HashMap;
042    import java.util.Map;
043    
044    import javax.servlet.http.HttpServletRequest;
045    import javax.servlet.http.HttpServletResponse;
046    import javax.servlet.jsp.JspException;
047    import javax.servlet.jsp.PageContext;
048    import javax.servlet.jsp.tagext.TagSupport;
049    
050    /**
051     * @author Brian Wing Shun Chan
052     */
053    public class RuntimeTag extends TagSupport {
054    
055            public static void doTag(
056                            String portletName, PageContext pageContext,
057                            HttpServletRequest request, HttpServletResponse response)
058                    throws Exception {
059    
060                    doTag(portletName, null, pageContext, request, response);
061            }
062    
063            public static void doTag(
064                            String portletName, String queryString, PageContext pageContext,
065                            HttpServletRequest request, HttpServletResponse response)
066                    throws Exception {
067    
068                    doTag(portletName, queryString, null, pageContext, request, response);
069            }
070    
071            public static void doTag(
072                            String portletName, String queryString, String defaultPreferences,
073                            PageContext pageContext, HttpServletRequest request,
074                            HttpServletResponse response)
075                    throws Exception {
076    
077                    if (pageContext != null) {
078                            response = new PipingServletResponse(
079                                    response, pageContext.getOut());
080                    }
081    
082                    String portletId = portletName;
083    
084                    RestrictPortletServletRequest restrictPortletServletRequest =
085                            new RestrictPortletServletRequest(request);
086    
087                    queryString = PortletParameterUtil.addNamespace(portletId, queryString);
088    
089                    Map<String, String[]> parameterMap = request.getParameterMap();
090    
091                    if (!portletId.equals(request.getParameter("p_p_id"))) {
092                            parameterMap = MapUtil.filter(
093                                    parameterMap, new HashMap<String, String[]>(),
094                                    new PrefixPredicateFilter("p_p_"));
095                    }
096    
097                    request = DynamicServletRequest.addQueryString(
098                            restrictPortletServletRequest, parameterMap, queryString, false);
099    
100                    try {
101                            request.setAttribute(WebKeys.RENDER_PORTLET_RESOURCE, Boolean.TRUE);
102    
103                            ThemeDisplay themeDisplay = (ThemeDisplay)request.getAttribute(
104                                    WebKeys.THEME_DISPLAY);
105    
106                            if (themeDisplay.isStateMaximized()) {
107                                    LayoutTypePortlet layoutTypePortlet =
108                                            themeDisplay.getLayoutTypePortlet();
109    
110                                    if (layoutTypePortlet.hasStateMaxPortletId(portletId)) {
111    
112                                            // A portlet in the maximized state has already been
113                                            // processed
114    
115                                            return;
116                                    }
117                            }
118    
119                            Layout layout = themeDisplay.getLayout();
120    
121                            Portlet portlet = getPortlet(
122                                    themeDisplay.getCompanyId(), portletId);
123    
124                            JSONObject jsonObject = null;
125    
126                            if ((PortletPreferencesLocalServiceUtil.getPortletPreferencesCount(
127                                            PortletKeys.PREFS_OWNER_TYPE_LAYOUT, themeDisplay.getPlid(),
128                                            portletId) < 1) ||
129                                    layout.isTypeControlPanel() ||
130                                    layout.isTypePanel()) {
131    
132                                    PortletPreferencesFactoryUtil.getPortletSetup(
133                                            request, portletId, defaultPreferences);
134    
135                                    PortletLayoutListener portletLayoutListener =
136                                            portlet.getPortletLayoutListenerInstance();
137    
138                                    if (portletLayoutListener != null) {
139                                            portletLayoutListener.onAddToLayout(
140                                                    portletId, themeDisplay.getPlid());
141                                    }
142    
143                                    jsonObject = JSONFactoryUtil.createJSONObject();
144    
145                                    PortletJSONUtil.populatePortletJSONObject(
146                                            request, StringPool.BLANK, portlet, jsonObject);
147                            }
148    
149                            if (jsonObject != null) {
150                                    PortletJSONUtil.writeHeaderPaths(response, jsonObject);
151                            }
152    
153                            PortletContainerUtil.render(request, response, portlet);
154    
155                            if (jsonObject != null) {
156                                    PortletJSONUtil.writeFooterPaths(response, jsonObject);
157                            }
158                    }
159                    finally {
160                            restrictPortletServletRequest.mergeSharedAttributes();
161                    }
162            }
163    
164            @Override
165            public int doEndTag() throws JspException {
166                    try {
167                            HttpServletRequest request =
168                                    (HttpServletRequest)pageContext.getRequest();
169    
170                            Layout layout = (Layout)request.getAttribute(WebKeys.LAYOUT);
171    
172                            if (layout == null) {
173                                    return EVAL_PAGE;
174                            }
175    
176                            HttpServletResponse response =
177                                    (HttpServletResponse)pageContext.getResponse();
178    
179                            doTag(
180                                    _portletName, _queryString, _defaultPreferences, pageContext,
181                                    request, response);
182    
183                            return EVAL_PAGE;
184                    }
185                    catch (Exception e) {
186                            _log.error(e, e);
187    
188                            throw new JspException(e);
189                    }
190            }
191    
192            public void setDefaultPreferences(String defaultPreferences) {
193                    _defaultPreferences = defaultPreferences;
194            }
195    
196            public void setPortletName(String portletName) {
197                    _portletName = portletName;
198            }
199    
200            public void setQueryString(String queryString) {
201                    _queryString = queryString;
202            }
203    
204            /**
205             * @see com.liferay.portal.model.impl.LayoutTypePortletImpl#getStaticPortlets(
206             *      String)
207             */
208            protected static Portlet getPortlet(long companyId, String portletId)
209                    throws Exception {
210    
211                    Portlet portlet = PortletLocalServiceUtil.getPortletById(
212                            companyId, portletId);
213    
214                    // See LayoutTypePortletImpl#getStaticPortlets for why we only clone
215                    // non-instanceable portlets
216    
217                    if (!portlet.isInstanceable()) {
218                            portlet = (Portlet)portlet.clone();
219                    }
220    
221                    portlet.setStatic(true);
222    
223                    return portlet;
224            }
225    
226            private static Log _log = LogFactoryUtil.getLog(RuntimeTag.class);
227    
228            private String _defaultPreferences;
229            private String _portletName;
230            private String _queryString;
231    
232    }