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