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.portal.layoutconfiguration.util.velocity;
016    
017    import com.liferay.portal.kernel.exception.SystemException;
018    import com.liferay.portal.kernel.json.JSONFactoryUtil;
019    import com.liferay.portal.kernel.json.JSONObject;
020    import com.liferay.portal.kernel.portlet.PortletContainerUtil;
021    import com.liferay.portal.kernel.portlet.PortletJSONUtil;
022    import com.liferay.portal.kernel.servlet.BufferCacheServletResponse;
023    import com.liferay.portal.kernel.util.GetterUtil;
024    import com.liferay.portal.kernel.util.StringBundler;
025    import com.liferay.portal.kernel.util.StringPool;
026    import com.liferay.portal.kernel.util.Validator;
027    import com.liferay.portal.layoutconfiguration.util.PortletRenderer;
028    import com.liferay.portal.model.LayoutTypePortlet;
029    import com.liferay.portal.model.Portlet;
030    import com.liferay.portal.service.PortletLocalServiceUtil;
031    import com.liferay.portal.theme.ThemeDisplay;
032    import com.liferay.portal.util.WebKeys;
033    
034    import java.util.ArrayList;
035    import java.util.Comparator;
036    import java.util.List;
037    import java.util.Map;
038    import java.util.TreeMap;
039    
040    import javax.servlet.http.HttpServletRequest;
041    import javax.servlet.http.HttpServletResponse;
042    
043    /**
044     * @author Ivica Cardic
045     * @author Brian Wing Shun Chan
046     * @author Shuyang Zhou
047     */
048    public class TemplateProcessor implements ColumnProcessor {
049    
050            public TemplateProcessor(
051                            HttpServletRequest request, HttpServletResponse response,
052                            String portletId)
053                    throws SystemException {
054    
055                    _request = request;
056                    _response = response;
057    
058                    if (Validator.isNotNull(portletId)) {
059                            ThemeDisplay themeDisplay = (ThemeDisplay)request.getAttribute(
060                                    WebKeys.THEME_DISPLAY);
061    
062                            _portlet = PortletLocalServiceUtil.getPortletById(
063                                    themeDisplay.getCompanyId(), portletId);
064                    }
065    
066                    _portletAjaxRender = GetterUtil.getBoolean(
067                            request.getAttribute(WebKeys.PORTLET_AJAX_RENDER));
068    
069                    _portletRenderers = new TreeMap<Integer, List<PortletRenderer>>(
070                            _renderWeightComparator);
071            }
072    
073            public Map<Integer, List<PortletRenderer>> getPortletRenderers() {
074                    return _portletRenderers;
075            }
076    
077            public boolean isPortletAjaxRender() {
078                    return _portletAjaxRender;
079            }
080    
081            @Override
082            public String processColumn(String columnId) throws Exception {
083                    return processColumn(columnId, StringPool.BLANK);
084            }
085    
086            @Override
087            public String processColumn(String columnId, String classNames)
088                    throws Exception {
089    
090                    ThemeDisplay themeDisplay = (ThemeDisplay)_request.getAttribute(
091                            WebKeys.THEME_DISPLAY);
092    
093                    LayoutTypePortlet layoutTypePortlet =
094                            themeDisplay.getLayoutTypePortlet();
095    
096                    List<Portlet> portlets = layoutTypePortlet.getAllPortlets(columnId);
097    
098                    StringBundler sb = new StringBundler(portlets.size() + 11);
099    
100                    sb.append("<div class=\"");
101                    sb.append("portlet-dropzone");
102    
103                    if (layoutTypePortlet.isCustomizable() &&
104                            layoutTypePortlet.isColumnDisabled(columnId)) {
105    
106                            sb.append(" portlet-dropzone-disabled");
107                    }
108    
109                    if (layoutTypePortlet.isColumnCustomizable(columnId)) {
110                            sb.append(" customizable");
111                    }
112    
113                    if (portlets.isEmpty()) {
114                            sb.append(" empty");
115                    }
116    
117                    if (Validator.isNotNull(classNames)) {
118                            sb.append(" ");
119                            sb.append(classNames);
120                    }
121    
122                    sb.append("\" id=\"layout-column_");
123                    sb.append(columnId);
124                    sb.append("\">");
125    
126                    for (int i = 0; i < portlets.size(); i++) {
127                            Portlet portlet = portlets.get(i);
128    
129                            Integer columnCount = new Integer(portlets.size());
130                            Integer columnPos = new Integer(i);
131    
132                            PortletRenderer portletRenderer = new PortletRenderer(
133                                    portlet, columnId, columnCount, columnPos);
134    
135                            if (_portletAjaxRender && (portlet.getRenderWeight() < 1)) {
136                                    StringBundler renderResult = portletRenderer.renderAjax(
137                                            _request, _response);
138    
139                                    sb.append(renderResult);
140                            }
141                            else {
142                                    Integer renderWeight = portlet.getRenderWeight();
143    
144                                    List<PortletRenderer> portletRenderers = _portletRenderers.get(
145                                            renderWeight);
146    
147                                    if (portletRenderers == null) {
148                                            portletRenderers = new ArrayList<PortletRenderer>();
149    
150                                            _portletRenderers.put(renderWeight, portletRenderers);
151                                    }
152    
153                                    portletRenderers.add(portletRenderer);
154    
155                                    sb.append("[$TEMPLATE_PORTLET_");
156                                    sb.append(portlet.getPortletId());
157                                    sb.append("$]");
158                            }
159                    }
160    
161                    sb.append("</div>");
162    
163                    return sb.toString();
164            }
165    
166            @Override
167            public String processMax() throws Exception {
168                    BufferCacheServletResponse bufferCacheServletResponse =
169                            new BufferCacheServletResponse(_response);
170    
171                    PortletContainerUtil.render(
172                            _request, bufferCacheServletResponse, _portlet);
173    
174                    return bufferCacheServletResponse.getString();
175            }
176    
177            /**
178             * @deprecated As of 6.2.0, replaced by {@link #processMax()}
179             */
180            @Override
181            public String processMax(String classNames) throws Exception {
182                    return processMax();
183            }
184    
185            @Override
186            public String processPortlet(String portletId) throws Exception {
187                    _request.setAttribute(WebKeys.RENDER_PORTLET_RESOURCE, Boolean.TRUE);
188    
189                    BufferCacheServletResponse bufferCacheServletResponse =
190                            new BufferCacheServletResponse(_response);
191    
192                    ThemeDisplay themeDisplay = (ThemeDisplay)_request.getAttribute(
193                            WebKeys.THEME_DISPLAY);
194    
195                    Portlet portlet = PortletLocalServiceUtil.getPortletById(
196                            themeDisplay.getCompanyId(), portletId);
197    
198                    JSONObject jsonObject = JSONFactoryUtil.createJSONObject();
199    
200                    PortletJSONUtil.populatePortletJSONObject(
201                            _request, StringPool.BLANK, portlet, jsonObject);
202    
203                    try {
204                            PortletJSONUtil.writeHeaderPaths(_response, jsonObject);
205    
206                            PortletContainerUtil.render(
207                                    _request, bufferCacheServletResponse, portlet);
208    
209                            PortletJSONUtil.writeFooterPaths(_response, jsonObject);
210    
211                            return bufferCacheServletResponse.getString();
212                    }
213                    finally {
214                            _request.removeAttribute(WebKeys.RENDER_PORTLET_RESOURCE);
215                    }
216            }
217    
218            private static RenderWeightComparator _renderWeightComparator =
219                    new RenderWeightComparator();
220    
221            private Portlet _portlet;
222            private boolean _portletAjaxRender;
223            private Map<Integer, List<PortletRenderer>> _portletRenderers;
224            private HttpServletRequest _request;
225            private HttpServletResponse _response;
226    
227            private static class RenderWeightComparator implements Comparator<Integer> {
228    
229                    @Override
230                    public int compare(Integer renderWeight1, Integer renderWeight2) {
231                            return renderWeight2.intValue() - renderWeight1.intValue();
232                    }
233    
234            }
235    
236    }