/**
* 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.service.impl;
import com.liferay.portal.kernel.exception.SystemException;
import com.liferay.portal.kernel.io.DummyWriter;
import com.liferay.portal.kernel.log.Log;
import com.liferay.portal.kernel.log.LogFactoryUtil;
import com.liferay.portal.kernel.model.LayoutTemplate;
import com.liferay.portal.kernel.model.LayoutTemplateConstants;
import com.liferay.portal.kernel.model.PluginSetting;
import com.liferay.portal.kernel.plugin.PluginPackage;
import com.liferay.portal.kernel.spring.aop.Skip;
import com.liferay.portal.kernel.template.StringTemplateResource;
import com.liferay.portal.kernel.template.Template;
import com.liferay.portal.kernel.template.TemplateConstants;
import com.liferay.portal.kernel.template.TemplateManagerUtil;
import com.liferay.portal.kernel.template.TemplateResourceLoaderUtil;
import com.liferay.portal.kernel.util.GetterUtil;
import com.liferay.portal.kernel.util.HttpUtil;
import com.liferay.portal.kernel.util.ListUtil;
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.xml.Document;
import com.liferay.portal.kernel.xml.Element;
import com.liferay.portal.kernel.xml.UnsecureSAXReaderUtil;
import com.liferay.portal.layoutconfiguration.util.velocity.InitColumnProcessor;
import com.liferay.portal.model.impl.LayoutTemplateImpl;
import com.liferay.portal.service.base.LayoutTemplateLocalServiceBaseImpl;
import com.liferay.portal.util.PropsValues;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedHashMap;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import javax.servlet.ServletContext;
/**
* @author Ivica Cardic
* @author Jorge Ferrer
* @author Brian Wing Shun Chan
* @author Raymond Augé
*/
@Skip
public class LayoutTemplateLocalServiceImpl
extends LayoutTemplateLocalServiceBaseImpl {
@Override
public String getContent(
String layoutTemplateId, boolean standard, String themeId) {
LayoutTemplate layoutTemplate = getLayoutTemplate(
layoutTemplateId, standard, themeId);
if (layoutTemplate == null) {
if (_log.isWarnEnabled()) {
_log.warn(
"Layout template " + layoutTemplateId + " does not exist");
}
layoutTemplate = getLayoutTemplate(
PropsValues.DEFAULT_LAYOUT_TEMPLATE_ID, standard, themeId);
if (layoutTemplate == null) {
StringBundler sb = new StringBundler(5);
sb.append("Layout template ");
sb.append(layoutTemplateId);
sb.append(" and default layout template ");
sb.append(PropsValues.DEFAULT_LAYOUT_TEMPLATE_ID);
sb.append(" do not exist");
_log.error(sb.toString());
return StringPool.BLANK;
}
}
if (PropsValues.LAYOUT_TEMPLATE_CACHE_ENABLED) {
return layoutTemplate.getContent();
}
try {
return layoutTemplate.getUncachedContent();
}
catch (IOException ioe) {
throw new SystemException(ioe);
}
}
@Override
public LayoutTemplate getLayoutTemplate(
String layoutTemplateId, boolean standard, String themeId) {
if (Validator.isNull(layoutTemplateId)) {
return null;
}
LayoutTemplate layoutTemplate = null;
if (themeId != null) {
if (standard) {
layoutTemplate = _getThemesStandard(themeId).get(
layoutTemplateId);
}
else {
layoutTemplate = _getThemesCustom(themeId).get(
layoutTemplateId);
}
if (layoutTemplate != null) {
return layoutTemplate;
}
}
if (standard) {
layoutTemplate = _warStandard.get(layoutTemplateId);
if (layoutTemplate == null) {
layoutTemplate = _portalStandard.get(layoutTemplateId);
}
}
else {
layoutTemplate = _warCustom.get(layoutTemplateId);
if (layoutTemplate == null) {
layoutTemplate = _portalCustom.get(layoutTemplateId);
}
}
return layoutTemplate;
}
@Override
public List<LayoutTemplate> getLayoutTemplates() {
List<LayoutTemplate> customLayoutTemplates = new ArrayList<>(
_portalCustom.size() + _warCustom.size());
customLayoutTemplates.addAll(_portalCustom.values());
customLayoutTemplates.addAll(_warCustom.values());
return customLayoutTemplates;
}
@Override
public List<LayoutTemplate> getLayoutTemplates(String themeId) {
Map<String, LayoutTemplate> themesCustom = _getThemesCustom(themeId);
List<LayoutTemplate> customLayoutTemplates = new ArrayList<>(
_portalCustom.size() + _warCustom.size() + themesCustom.size());
for (Map.Entry<String, LayoutTemplate> entry :
_portalCustom.entrySet()) {
String layoutTemplateId = entry.getKey();
LayoutTemplate layoutTemplate = entry.getValue();
LayoutTemplate themeCustomLayoutTemplate = themesCustom.get(
layoutTemplateId);
if (themeCustomLayoutTemplate != null) {
customLayoutTemplates.add(themeCustomLayoutTemplate);
}
else {
LayoutTemplate warCustomLayoutTemplate = _warCustom.get(
layoutTemplateId);
if (warCustomLayoutTemplate != null) {
customLayoutTemplates.add(warCustomLayoutTemplate);
}
else {
customLayoutTemplates.add(layoutTemplate);
}
}
}
for (Map.Entry<String, LayoutTemplate> entry : _warCustom.entrySet()) {
String layoutTemplateId = entry.getKey();
if (!_portalCustom.containsKey(layoutTemplateId) &&
!themesCustom.containsKey(layoutTemplateId)) {
customLayoutTemplates.add(_warCustom.get(layoutTemplateId));
}
}
for (Map.Entry<String, LayoutTemplate> entry :
themesCustom.entrySet()) {
String layoutTemplateId = entry.getKey();
if (!_portalCustom.containsKey(layoutTemplateId) &&
!_warCustom.containsKey(layoutTemplateId)) {
customLayoutTemplates.add(themesCustom.get(layoutTemplateId));
}
}
return customLayoutTemplates;
}
@Override
public List<LayoutTemplate> init(
ServletContext servletContext, String[] xmls,
PluginPackage pluginPackage) {
return init(null, servletContext, xmls, pluginPackage);
}
@Override
public List<LayoutTemplate> init(
String servletContextName, ServletContext servletContext, String[] xmls,
PluginPackage pluginPackage) {
Set<LayoutTemplate> layoutTemplates = new LinkedHashSet<>();
try {
for (String xml : xmls) {
layoutTemplates.addAll(
_readLayoutTemplates(
servletContextName, servletContext, xml,
pluginPackage));
}
}
catch (Exception e) {
_log.error(e, e);
}
return new ArrayList<>(layoutTemplates);
}
@Override
public void readLayoutTemplate(
String servletContextName, ServletContext servletContext,
Set<LayoutTemplate> layoutTemplates, Element element, boolean standard,
String themeId, PluginPackage pluginPackage) {
Map<String, LayoutTemplate> installedLayoutTemplates = null;
if (themeId != null) {
if (standard) {
installedLayoutTemplates = _getThemesStandard(themeId);
}
else {
installedLayoutTemplates = _getThemesCustom(themeId);
}
}
else if (servletContextName != null) {
if (standard) {
installedLayoutTemplates = _warStandard;
}
else {
installedLayoutTemplates = _warCustom;
}
}
else {
if (standard) {
installedLayoutTemplates = _portalStandard;
}
else {
installedLayoutTemplates = _portalCustom;
}
}
List<Element> layoutTemplateElements = element.elements(
"layout-template");
for (Element layoutTemplateElement : layoutTemplateElements) {
String layoutTemplateId = layoutTemplateElement.attributeValue(
"id");
LayoutTemplate layoutTemplateModel = installedLayoutTemplates.get(
layoutTemplateId);
if (layoutTemplateModel == null) {
layoutTemplateModel = new LayoutTemplateImpl(layoutTemplateId);
installedLayoutTemplates.put(
layoutTemplateId, layoutTemplateModel);
}
PluginSetting pluginSetting =
pluginSettingLocalService.getDefaultPluginSetting();
layoutTemplateModel.setPluginPackage(pluginPackage);
layoutTemplateModel.setServletContext(servletContext);
if (servletContextName != null) {
layoutTemplateModel.setServletContextName(servletContextName);
}
layoutTemplateModel.setStandard(standard);
layoutTemplateModel.setThemeId(themeId);
String templateName = GetterUtil.getString(
layoutTemplateElement.attributeValue("name"));
if (Validator.isNotNull(templateName)) {
layoutTemplateModel.setName(templateName);
}
layoutTemplateModel.setTemplatePath(
GetterUtil.getString(
layoutTemplateElement.elementText("template-path"),
layoutTemplateModel.getTemplatePath()));
layoutTemplateModel.setThumbnailPath(
GetterUtil.getString(
layoutTemplateElement.elementText("thumbnail-path"),
layoutTemplateModel.getThumbnailPath()));
String content = null;
try {
content = HttpUtil.URLtoString(
servletContext.getResource(
layoutTemplateModel.getTemplatePath()));
}
catch (Exception e) {
_log.error(
"Unable to get content at template path " +
layoutTemplateModel.getTemplatePath() + ": " +
e.getMessage());
}
if (Validator.isNull(content)) {
_log.error(
"No content found at template path " +
layoutTemplateModel.getTemplatePath());
}
else {
StringBundler sb = new StringBundler(3);
sb.append(themeId);
if (standard) {
sb.append(LayoutTemplateConstants.STANDARD_SEPARATOR);
}
else {
sb.append(LayoutTemplateConstants.CUSTOM_SEPARATOR);
}
sb.append(layoutTemplateId);
String velocityTemplateId = sb.toString();
layoutTemplateModel.setContent(content);
layoutTemplateModel.setColumns(
_getColumns(velocityTemplateId, content));
}
Element rolesElement = layoutTemplateElement.element("roles");
if (rolesElement != null) {
List<Element> roleNameElements = rolesElement.elements(
"role-name");
for (Element roleNameElement : roleNameElements) {
pluginSetting.addRole(roleNameElement.getText());
}
}
layoutTemplateModel.setDefaultPluginSetting(pluginSetting);
if (layoutTemplates != null) {
layoutTemplates.add(layoutTemplateModel);
}
}
}
@Override
public void uninstallLayoutTemplate(
String layoutTemplateId, boolean standard) {
String templateId = null;
try {
if (standard) {
templateId =
"null" + LayoutTemplateConstants.STANDARD_SEPARATOR +
layoutTemplateId;
TemplateResourceLoaderUtil.clearCache(
TemplateConstants.LANG_TYPE_VM, templateId);
_warStandard.remove(layoutTemplateId);
}
else {
templateId =
"null" + LayoutTemplateConstants.CUSTOM_SEPARATOR +
layoutTemplateId;
TemplateResourceLoaderUtil.clearCache(
TemplateConstants.LANG_TYPE_VM, templateId);
_warCustom.remove(layoutTemplateId);
}
}
catch (Exception e) {
_log.error(
"Unable to uninstall layout template " + layoutTemplateId, e);
}
}
@Override
public void uninstallLayoutTemplates(String themeId) {
Map<String, LayoutTemplate> themesStandard = _getThemesStandard(
themeId);
for (Map.Entry<String, LayoutTemplate> entry :
themesStandard.entrySet()) {
LayoutTemplate layoutTemplate = entry.getValue();
String templateId =
themeId + LayoutTemplateConstants.STANDARD_SEPARATOR +
layoutTemplate.getLayoutTemplateId();
try {
TemplateResourceLoaderUtil.clearCache(
TemplateConstants.LANG_TYPE_VM, templateId);
}
catch (Exception e) {
_log.error(
"Unable to uninstall layout template " +
layoutTemplate.getLayoutTemplateId(),
e);
}
}
themesStandard.clear();
Map<String, LayoutTemplate> themesCustom = _getThemesCustom(themeId);
for (Map.Entry<String, LayoutTemplate> entry :
themesCustom.entrySet()) {
LayoutTemplate layoutTemplate = entry.getValue();
String templateId =
themeId + LayoutTemplateConstants.CUSTOM_SEPARATOR +
layoutTemplate.getLayoutTemplateId();
try {
TemplateResourceLoaderUtil.clearCache(
TemplateConstants.LANG_TYPE_VM, templateId);
}
catch (Exception e) {
_log.error(
"Unable to uninstall layout template " +
layoutTemplate.getLayoutTemplateId(),
e);
}
}
themesCustom.clear();
}
private List<String> _getColumns(
String velocityTemplateId, String velocityTemplateContent) {
try {
InitColumnProcessor processor = new InitColumnProcessor();
Template template = TemplateManagerUtil.getTemplate(
TemplateConstants.LANG_TYPE_VM,
new StringTemplateResource(
velocityTemplateId, velocityTemplateContent),
false);
template.put("processor", processor);
template.processTemplate(new DummyWriter());
return ListUtil.sort(processor.getColumns());
}
catch (Exception e) {
_log.error(e);
return new ArrayList<>();
}
}
private Map<String, LayoutTemplate> _getThemesCustom(String themeId) {
Map<String, LayoutTemplate> layoutTemplates = _customThemes.get(
themeId);
if (layoutTemplates == null) {
layoutTemplates = new LinkedHashMap<>();
_customThemes.put(themeId, layoutTemplates);
}
return layoutTemplates;
}
private Map<String, LayoutTemplate> _getThemesStandard(String themeId) {
Map<String, LayoutTemplate> layoutTemplates = _standardThemes.get(
themeId);
if (layoutTemplates == null) {
layoutTemplates = new LinkedHashMap<>();
_standardThemes.put(themeId, layoutTemplates);
}
return layoutTemplates;
}
private Set<LayoutTemplate> _readLayoutTemplates(
String servletContextName, ServletContext servletContext,
String xml, PluginPackage pluginPackage)
throws Exception {
Set<LayoutTemplate> layoutTemplates = new HashSet<>();
if (xml == null) {
return layoutTemplates;
}
Document document = UnsecureSAXReaderUtil.read(xml, true);
Element rootElement = document.getRootElement();
Element standardElement = rootElement.element("standard");
if (standardElement != null) {
readLayoutTemplate(
servletContextName, servletContext, layoutTemplates,
standardElement, true, null, pluginPackage);
}
Element customElement = rootElement.element("custom");
if (customElement != null) {
readLayoutTemplate(
servletContextName, servletContext, layoutTemplates,
customElement, false, null, pluginPackage);
}
return layoutTemplates;
}
private static final Log _log = LogFactoryUtil.getLog(
LayoutTemplateLocalServiceImpl.class);
private static final Map<String, Map<String, LayoutTemplate>>
_customThemes = new HashMap<>();
private static final Map<String, LayoutTemplate> _portalCustom =
new LinkedHashMap<>();
private static final Map<String, LayoutTemplate> _portalStandard =
new HashMap<>();
private static final Map<String, Map<String, LayoutTemplate>>
_standardThemes = new HashMap<>();
private static final Map<String, LayoutTemplate> _warCustom =
new LinkedHashMap<>();
private static final Map<String, LayoutTemplate> _warStandard =
new HashMap<>();
}