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