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