/** * Copyright (c) 2000-present Liferay, Inc. All rights reserved. * * This library is free software; you can redistribute it and/or modify it under * the terms of the GNU Lesser General Public License as published by the Free * Software Foundation; either version 2.1 of the License, or (at your option) * any later version. * * This library is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more * details. */ package com.liferay.portal.layoutconfiguration.util.velocity; import com.liferay.portal.kernel.json.JSONFactoryUtil; import com.liferay.portal.kernel.json.JSONObject; import com.liferay.portal.kernel.model.LayoutTypePortlet; import com.liferay.portal.kernel.model.Portlet; import com.liferay.portal.kernel.portlet.PortletContainerUtil; import com.liferay.portal.kernel.portlet.PortletJSONUtil; import com.liferay.portal.kernel.portlet.PortletProvider; import com.liferay.portal.kernel.portlet.PortletProviderUtil; import com.liferay.portal.kernel.service.PortletLocalServiceUtil; import com.liferay.portal.kernel.servlet.BufferCacheServletResponse; import com.liferay.portal.kernel.settings.ModifiableSettings; import com.liferay.portal.kernel.settings.PortletInstanceSettingsLocator; import com.liferay.portal.kernel.settings.Settings; import com.liferay.portal.kernel.settings.SettingsFactoryUtil; import com.liferay.portal.kernel.theme.ThemeDisplay; import com.liferay.portal.kernel.util.ClassUtil; import com.liferay.portal.kernel.util.GetterUtil; import com.liferay.portal.kernel.util.StringBundler; import com.liferay.portal.kernel.util.StringPool; import com.liferay.portal.kernel.util.Validator; import com.liferay.portal.kernel.util.WebKeys; import com.liferay.portal.layoutconfiguration.util.PortletRenderer; import java.util.ArrayList; import java.util.Comparator; import java.util.List; import java.util.Map; import java.util.TreeMap; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; /** * @author Ivica Cardic * @author Brian Wing Shun Chan * @author Shuyang Zhou * @author Oliver Teichmann */ public class TemplateProcessor implements ColumnProcessor { public TemplateProcessor( HttpServletRequest request, HttpServletResponse response, String portletId) { _request = request; _response = response; if (Validator.isNotNull(portletId)) { ThemeDisplay themeDisplay = (ThemeDisplay)request.getAttribute( WebKeys.THEME_DISPLAY); _portlet = PortletLocalServiceUtil.getPortletById( themeDisplay.getCompanyId(), portletId); } else { _portlet = null; } _portletAjaxRender = GetterUtil.getBoolean( request.getAttribute(WebKeys.PORTLET_AJAX_RENDER)); _portletRenderers = new TreeMap<>(_renderWeightComparator); } public Map<Integer, List<PortletRenderer>> getPortletRenderers() { return _portletRenderers; } public boolean isPortletAjaxRender() { return _portletAjaxRender; } @Override public String processColumn(String columnId) throws Exception { return processColumn(columnId, StringPool.BLANK); } @Override public String processColumn(String columnId, String classNames) throws Exception { ThemeDisplay themeDisplay = (ThemeDisplay)_request.getAttribute( WebKeys.THEME_DISPLAY); LayoutTypePortlet layoutTypePortlet = themeDisplay.getLayoutTypePortlet(); List<Portlet> portlets = layoutTypePortlet.getAllPortlets(columnId); StringBundler sb = new StringBundler(portlets.size() * 3 + 10); sb.append("<div class=\"portlet-dropzone"); if (layoutTypePortlet.isCustomizable() && layoutTypePortlet.isColumnDisabled(columnId)) { sb.append(" portlet-dropzone-disabled"); } if (layoutTypePortlet.isColumnCustomizable(columnId)) { sb.append(" customizable"); } if (portlets.isEmpty()) { sb.append(" empty"); } if (Validator.isNotNull(classNames)) { sb.append(" "); sb.append(classNames); } sb.append("\" id=\"layout-column_"); sb.append(columnId); sb.append("\">"); for (int i = 0; i < portlets.size(); i++) { Portlet portlet = portlets.get(i); Integer columnCount = Integer.valueOf(portlets.size()); Integer columnPos = Integer.valueOf(i); PortletRenderer portletRenderer = new PortletRenderer( portlet, columnId, columnCount, columnPos); if (_portletAjaxRender && (portlet.getRenderWeight() < 1)) { StringBundler renderResult = portletRenderer.renderAjax( _request, _response); sb.append(renderResult); } else { Integer renderWeight = portlet.getRenderWeight(); List<PortletRenderer> portletRenderers = _portletRenderers.get( renderWeight); if (portletRenderers == null) { portletRenderers = new ArrayList<>(); _portletRenderers.put(renderWeight, portletRenderers); } portletRenderers.add(portletRenderer); sb.append("[$TEMPLATE_PORTLET_"); sb.append(portlet.getPortletId()); sb.append("$]"); } } sb.append("</div>"); return sb.toString(); } @Override public String processMax() throws Exception { BufferCacheServletResponse bufferCacheServletResponse = new BufferCacheServletResponse(_response); PortletContainerUtil.render( _request, bufferCacheServletResponse, _portlet); return bufferCacheServletResponse.getString(); } @Override public String processPortlet(String portletId) throws Exception { _request.setAttribute(WebKeys.RENDER_PORTLET_RESOURCE, Boolean.TRUE); BufferCacheServletResponse bufferCacheServletResponse = new BufferCacheServletResponse(_response); ThemeDisplay themeDisplay = (ThemeDisplay)_request.getAttribute( WebKeys.THEME_DISPLAY); Portlet portlet = PortletLocalServiceUtil.getPortletById( themeDisplay.getCompanyId(), portletId); JSONObject jsonObject = JSONFactoryUtil.createJSONObject(); PortletJSONUtil.populatePortletJSONObject( _request, StringPool.BLANK, portlet, jsonObject); try { PortletJSONUtil.writeHeaderPaths(_response, jsonObject); PortletContainerUtil.render( _request, bufferCacheServletResponse, portlet); PortletJSONUtil.writeFooterPaths(_response, jsonObject); return bufferCacheServletResponse.getString(); } finally { _request.removeAttribute(WebKeys.RENDER_PORTLET_RESOURCE); } } @Override public String processPortlet( String portletId, Map<String, ?> defaultSettingsMap) throws Exception { ThemeDisplay themeDisplay = (ThemeDisplay)_request.getAttribute( WebKeys.THEME_DISPLAY); Settings settings = SettingsFactoryUtil.getSettings( new PortletInstanceSettingsLocator( themeDisplay.getLayout(), portletId)); ModifiableSettings modifiableSettings = settings.getModifiableSettings(); for (Map.Entry<String, ?> entry : defaultSettingsMap.entrySet()) { String key = entry.getKey(); Object value = entry.getValue(); if (value instanceof String) { modifiableSettings.setValue(key, (String)value); } else if (value instanceof String[]) { modifiableSettings.setValues(key, (String[])value); } else { throw new IllegalArgumentException( "Key " + key + " has unsupported value of type " + ClassUtil.getClassName(value.getClass())); } } modifiableSettings.store(); return processPortlet(portletId); } @Override public String processPortlet( String portletProviderClassName, PortletProvider.Action portletProviderAction) throws Exception { String portletId = PortletProviderUtil.getPortletId( portletProviderClassName, portletProviderAction); return processPortlet(portletId); } private static final RenderWeightComparator _renderWeightComparator = new RenderWeightComparator(); private final Portlet _portlet; private final boolean _portletAjaxRender; private final Map<Integer, List<PortletRenderer>> _portletRenderers; private final HttpServletRequest _request; private final HttpServletResponse _response; private static class RenderWeightComparator implements Comparator<Integer> { @Override public int compare(Integer renderWeight1, Integer renderWeight2) { return renderWeight2.intValue() - renderWeight1.intValue(); } } }