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.JSONArray;
018    import com.liferay.portal.kernel.json.JSONFactoryUtil;
019    import com.liferay.portal.kernel.json.JSONObject;
020    import com.liferay.portal.kernel.log.Log;
021    import com.liferay.portal.kernel.log.LogFactoryUtil;
022    import com.liferay.portal.kernel.portlet.PortletContainerUtil;
023    import com.liferay.portal.kernel.portlet.PortletJSONUtil;
024    import com.liferay.portal.kernel.portlet.PortletLayoutListener;
025    import com.liferay.portal.kernel.portlet.PortletParameterUtil;
026    import com.liferay.portal.kernel.portlet.RestrictPortletServletRequest;
027    import com.liferay.portal.kernel.servlet.DynamicServletRequest;
028    import com.liferay.portal.kernel.servlet.PipingServletResponse;
029    import com.liferay.portal.kernel.util.HtmlUtil;
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.io.IOException;
042    import java.io.PrintWriter;
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                    request = DynamicServletRequest.addQueryString(
090                            restrictPortletServletRequest, queryString);
091    
092                    try {
093                            request.setAttribute(WebKeys.RENDER_PORTLET_RESOURCE, Boolean.TRUE);
094    
095                            ThemeDisplay themeDisplay = (ThemeDisplay)request.getAttribute(
096                                    WebKeys.THEME_DISPLAY);
097    
098                            if (themeDisplay.isStateMaximized()) {
099                                    LayoutTypePortlet layoutTypePortlet =
100                                            themeDisplay.getLayoutTypePortlet();
101    
102                                    if (layoutTypePortlet.hasStateMaxPortletId(portletId)) {
103    
104                                            // A portlet in the maximized state has already been
105                                            // processed
106    
107                                            return;
108                                    }
109                            }
110    
111                            Layout layout = themeDisplay.getLayout();
112    
113                            Portlet portlet = getPortlet(
114                                    themeDisplay.getCompanyId(), portletId);
115    
116                            JSONObject jsonObject = null;
117    
118                            if ((PortletPreferencesLocalServiceUtil.getPortletPreferencesCount(
119                                            PortletKeys.PREFS_OWNER_TYPE_LAYOUT, themeDisplay.getPlid(),
120                                            portletId) < 1) ||
121                                    layout.isTypeControlPanel() ||
122                                    layout.isTypePanel()) {
123    
124                                    PortletPreferencesFactoryUtil.getPortletSetup(
125                                            request, portletId, defaultPreferences);
126    
127                                    PortletLayoutListener portletLayoutListener =
128                                            portlet.getPortletLayoutListenerInstance();
129    
130                                    if (portletLayoutListener != null) {
131                                            portletLayoutListener.onAddToLayout(
132                                                    portletId, themeDisplay.getPlid());
133                                    }
134    
135                                    jsonObject = JSONFactoryUtil.createJSONObject();
136    
137                                    PortletJSONUtil.populatePortletJSONObject(
138                                            request, StringPool.BLANK, portlet, jsonObject);
139                            }
140    
141                            if (jsonObject != null) {
142                                    writeHeaderPaths(response, jsonObject);
143                            }
144    
145                            PortletContainerUtil.render(request, response, portlet);
146    
147                            if (jsonObject != null) {
148                                    writeFooterPaths(response, jsonObject);
149                            }
150                    }
151                    finally {
152                            restrictPortletServletRequest.mergeSharedAttributes();
153                    }
154            }
155    
156            @Override
157            public int doEndTag() throws JspException {
158                    try {
159                            HttpServletRequest request =
160                                    (HttpServletRequest)pageContext.getRequest();
161    
162                            Layout layout = (Layout)request.getAttribute(WebKeys.LAYOUT);
163    
164                            if (layout == null) {
165                                    return EVAL_PAGE;
166                            }
167    
168                            HttpServletResponse response =
169                                    (HttpServletResponse)pageContext.getResponse();
170    
171                            doTag(
172                                    _portletName, _queryString, _defaultPreferences, pageContext,
173                                    request, response);
174    
175                            return EVAL_PAGE;
176                    }
177                    catch (Exception e) {
178                            _log.error(e, e);
179    
180                            throw new JspException(e);
181                    }
182            }
183    
184            public void setDefaultPreferences(String defaultPreferences) {
185                    _defaultPreferences = defaultPreferences;
186            }
187    
188            public void setPortletName(String portletName) {
189                    _portletName = portletName;
190            }
191    
192            public void setQueryString(String queryString) {
193                    _queryString = queryString;
194            }
195    
196            /**
197             * @see com.liferay.portal.model.impl.LayoutTypePortletImpl#getStaticPortlets(
198             *      String)
199             */
200            protected static Portlet getPortlet(long companyId, String portletId)
201                    throws Exception {
202    
203                    Portlet portlet = PortletLocalServiceUtil.getPortletById(
204                            companyId, portletId);
205    
206                    // See LayoutTypePortletImpl#getStaticPortlets for why we only clone
207                    // non-instanceable portlets
208    
209                    if (!portlet.isInstanceable()) {
210                            portlet = (Portlet)portlet.clone();
211                    }
212    
213                    portlet.setStatic(true);
214    
215                    return portlet;
216            }
217    
218            protected static void writeFooterPaths(
219                            HttpServletResponse response, JSONObject jsonObject)
220                    throws IOException {
221    
222                    JSONArray footerCssPathsJSONArray = jsonObject.getJSONArray(
223                            "footerCssPaths");
224                    JSONArray footerJavaScriptPathsJSONArray = jsonObject.getJSONArray(
225                            "footerJavaScriptPaths");
226    
227                    if ((footerCssPathsJSONArray.length() == 0) &&
228                            (footerJavaScriptPathsJSONArray.length() == 0)) {
229    
230                            return;
231                    }
232    
233                    PrintWriter printWriter = response.getWriter();
234    
235                    for (int i = 0; i < footerCssPathsJSONArray.length(); i++) {
236                            String value = footerCssPathsJSONArray.getString(i);
237    
238                            printWriter.print("<link href=\"");
239                            printWriter.print(HtmlUtil.escape(value));
240                            printWriter.println("\" rel=\"stylesheet\" type=\"text/css\" />");
241                    }
242    
243                    for (int i = 0; i < footerJavaScriptPathsJSONArray.length(); i++) {
244                            String value = footerJavaScriptPathsJSONArray.getString(i);
245    
246                            printWriter.print("<script src=\"");
247                            printWriter.print(HtmlUtil.escape(value));
248                            printWriter.println("\" type=\"text/javascript\"></script>");
249                    }
250            }
251    
252            protected static void writeHeaderPaths(
253                            HttpServletResponse response, JSONObject jsonObject)
254                    throws IOException {
255    
256                    JSONArray headerCssPathsJSONArray = jsonObject.getJSONArray(
257                            "headerCssPaths");
258                    JSONArray headerJavaScriptPathsJSONArray = jsonObject.getJSONArray(
259                            "headerJavaScriptPaths");
260    
261                    if ((headerCssPathsJSONArray.length() == 0) &&
262                            (headerJavaScriptPathsJSONArray.length() == 0)) {
263    
264                            return;
265                    }
266    
267                    PrintWriter printWriter = response.getWriter();
268    
269                    for (int i = 0; i < headerCssPathsJSONArray.length(); i++) {
270                            String value = headerCssPathsJSONArray.getString(i);
271    
272                            printWriter.print("<link href=\"");
273                            printWriter.print(HtmlUtil.escape(value));
274                            printWriter.println("\" rel=\"stylesheet\" type=\"text/css\" />");
275                    }
276    
277                    for (int i = 0; i < headerJavaScriptPathsJSONArray.length(); i++) {
278                            String value = headerJavaScriptPathsJSONArray.getString(i);
279    
280                            printWriter.print("<script src=\"");
281                            printWriter.print(HtmlUtil.escape(value));
282                            printWriter.println("\" type=\"text/javascript\"></script>");
283                    }
284            }
285    
286            private static Log _log = LogFactoryUtil.getLog(RuntimeTag.class);
287    
288            private String _defaultPreferences;
289            private String _portletName;
290            private String _queryString;
291    
292    }