com.liferay.portal.service.impl.ThemeLocalServiceImpl Maven / Gradle / Ivy
/**
* 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.petra.string.StringBundler;
import com.liferay.petra.string.StringPool;
import com.liferay.portal.kernel.bean.BeanReference;
import com.liferay.portal.kernel.log.Log;
import com.liferay.portal.kernel.log.LogFactoryUtil;
import com.liferay.portal.kernel.model.ColorScheme;
import com.liferay.portal.kernel.model.PluginSetting;
import com.liferay.portal.kernel.model.PortletConstants;
import com.liferay.portal.kernel.model.PortletDecorator;
import com.liferay.portal.kernel.model.Theme;
import com.liferay.portal.kernel.plugin.PluginPackage;
import com.liferay.portal.kernel.plugin.Version;
import com.liferay.portal.kernel.service.LayoutTemplateLocalService;
import com.liferay.portal.kernel.service.PluginSettingLocalService;
import com.liferay.portal.kernel.servlet.ServletContextUtil;
import com.liferay.portal.kernel.template.TemplateConstants;
import com.liferay.portal.kernel.theme.PortletDecoratorFactoryUtil;
import com.liferay.portal.kernel.theme.ThemeCompanyId;
import com.liferay.portal.kernel.theme.ThemeCompanyLimit;
import com.liferay.portal.kernel.theme.ThemeGroupId;
import com.liferay.portal.kernel.theme.ThemeGroupLimit;
import com.liferay.portal.kernel.transaction.Transactional;
import com.liferay.portal.kernel.util.ColorSchemeFactoryUtil;
import com.liferay.portal.kernel.util.GetterUtil;
import com.liferay.portal.kernel.util.ListUtil;
import com.liferay.portal.kernel.util.PortalUtil;
import com.liferay.portal.kernel.util.ReleaseInfo;
import com.liferay.portal.kernel.util.StringUtil;
import com.liferay.portal.kernel.util.ThemeFactoryUtil;
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.model.impl.ThemeImpl;
import com.liferay.portal.plugin.PluginUtil;
import com.liferay.portal.service.base.ThemeLocalServiceBaseImpl;
import com.liferay.util.ContextReplace;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import javax.servlet.ServletContext;
/**
* @author Brian Wing Shun Chan
* @author Jorge Ferrer
* @author Raymond Augé
*/
@Transactional(enabled = false)
public class ThemeLocalServiceImpl extends ThemeLocalServiceBaseImpl {
@Override
public ColorScheme fetchColorScheme(
long companyId, String themeId, String colorSchemeId) {
colorSchemeId = GetterUtil.getString(colorSchemeId);
Theme theme = fetchTheme(companyId, themeId);
if (theme == null) {
return null;
}
Map colorSchemesMap = theme.getColorSchemesMap();
return colorSchemesMap.get(colorSchemeId);
}
@Override
public PortletDecorator fetchPortletDecorator(
long companyId, String themeId, String colorSchemeId) {
colorSchemeId = GetterUtil.getString(colorSchemeId);
Theme theme = fetchTheme(companyId, themeId);
if (theme == null) {
return null;
}
Map portletDecoratorsMap =
theme.getPortletDecoratorsMap();
return portletDecoratorsMap.get(colorSchemeId);
}
@Override
public Theme fetchTheme(long companyId, String themeId) {
themeId = GetterUtil.getString(themeId);
Map themes = _getThemes(companyId);
return themes.get(themeId);
}
@Override
public ColorScheme getColorScheme(
long companyId, String themeId, String colorSchemeId) {
colorSchemeId = GetterUtil.getString(colorSchemeId);
Theme theme = getTheme(companyId, themeId);
Map colorSchemesMap = theme.getColorSchemesMap();
ColorScheme colorScheme = colorSchemesMap.get(colorSchemeId);
if (colorScheme != null) {
return colorScheme;
}
List colorSchemes = theme.getColorSchemes();
if (!colorSchemes.isEmpty()) {
for (int i = colorSchemes.size() - 1; i >= 0; i--) {
colorScheme = colorSchemes.get(i);
if (colorScheme.isDefaultCs()) {
return colorScheme;
}
}
}
if (colorScheme == null) {
colorScheme = ColorSchemeFactoryUtil.getDefaultRegularColorScheme();
}
return colorScheme;
}
@Override
public List getControlPanelThemes(long companyId, long userId) {
List themes = getThemes(companyId);
themes = PluginUtil.restrictPlugins(themes, companyId, userId);
Iterator iterator = themes.iterator();
while (iterator.hasNext()) {
Theme theme = iterator.next();
if (!theme.isControlPanelTheme()) {
iterator.remove();
}
}
return themes;
}
@Override
public List getPageThemes(
long companyId, long groupId, long userId) {
List themes = getThemes(companyId);
themes = PluginUtil.restrictPlugins(themes, companyId, groupId, userId);
Iterator iterator = themes.iterator();
while (iterator.hasNext()) {
Theme theme = iterator.next();
if (!theme.isPageTheme() || !theme.isGroupAvailable(groupId)) {
iterator.remove();
}
}
return themes;
}
@Override
public PortletDecorator getPortletDecorator(
long companyId, String themeId, String portletDecoratorId) {
Theme theme = fetchTheme(companyId, themeId);
Map portletDecoratorsMap =
theme.getPortletDecoratorsMap();
portletDecoratorId = GetterUtil.getString(portletDecoratorId);
PortletDecorator portletDecorator = portletDecoratorsMap.get(
portletDecoratorId);
if (portletDecorator != null) {
return portletDecorator;
}
ThemeImpl themeImpl = (ThemeImpl)theme;
return themeImpl.getDefaultPortletDecorator();
}
@Override
public Theme getTheme(long companyId, String themeId) {
themeId = GetterUtil.getString(themeId);
Map themes = _getThemes(companyId);
Theme theme = themes.get(themeId);
if (theme != null) {
return theme;
}
if (_log.isWarnEnabled()) {
_log.warn(
"No theme found for specified theme id " + themeId +
". Returning the default theme.");
}
themeId = ThemeFactoryUtil.getDefaultRegularThemeId(companyId);
theme = _themes.get(themeId);
if (theme != null) {
return theme;
}
if (_themes.isEmpty()) {
if (_log.isDebugEnabled()) {
_log.debug("No themes are installed");
}
return null;
}
if (!themeId.contains(PortletConstants.WAR_SEPARATOR)) {
_log.error(
"No theme found for default theme id " + themeId +
". Returning a random theme.");
}
for (Map.Entry entry : _themes.entrySet()) {
theme = entry.getValue();
if ((theme != null) && !theme.isControlPanelTheme()) {
return theme;
}
}
return null;
}
@Override
public List getThemes(long companyId) {
List themesList = ListUtil.fromMapValues(_getThemes(companyId));
return ListUtil.sort(themesList);
}
@Override
public List getWARThemes() {
List themes = ListUtil.fromMapValues(_themes);
Iterator iterator = themes.iterator();
while (iterator.hasNext()) {
Theme theme = iterator.next();
if (!theme.isWARFile()) {
iterator.remove();
}
}
return themes;
}
@Override
public List init(
ServletContext servletContext, String themesPath,
boolean loadFromServletContext, String[] xmls,
PluginPackage pluginPackage) {
return init(
null, servletContext, themesPath, loadFromServletContext, xmls,
pluginPackage);
}
@Override
public List init(
String servletContextName, ServletContext servletContext,
String themesPath, boolean loadFromServletContext, String[] xmls,
PluginPackage pluginPackage) {
Set themes = new LinkedHashSet<>();
try {
for (String xml : xmls) {
themes.addAll(
_readThemes(
servletContextName, servletContext, themesPath,
loadFromServletContext, xml, pluginPackage));
}
}
catch (Exception exception) {
_log.error(exception);
}
_themesPool.clear();
return new ArrayList<>(themes);
}
@Override
public void uninstallThemes(List themes) {
for (Theme theme : themes) {
String themeId = theme.getThemeId();
_themes.remove(themeId);
_layoutTemplateLocalService.uninstallLayoutTemplates(themeId);
}
_themesPool.clear();
}
private List _getCompanyLimitExcludes(Element element) {
List includes = new ArrayList<>();
if (element == null) {
return includes;
}
List companyIdsElements = element.elements("company-id");
for (Element companyIdElement : companyIdsElements) {
String name = companyIdElement.attributeValue("name");
String pattern = companyIdElement.attributeValue("pattern");
ThemeCompanyId themeCompanyId = null;
if (Validator.isNotNull(name)) {
themeCompanyId = new ThemeCompanyId(name, false);
}
else if (Validator.isNotNull(pattern)) {
themeCompanyId = new ThemeCompanyId(pattern, true);
}
if (themeCompanyId != null) {
includes.add(themeCompanyId);
}
}
return includes;
}
private List _getCompanyLimitIncludes(Element element) {
return _getCompanyLimitExcludes(element);
}
private List _getGroupLimitExcludes(Element element) {
List includes = new ArrayList<>();
if (element == null) {
return includes;
}
List groupIdsElements = element.elements("group-id");
for (Element groupIdElement : groupIdsElements) {
String name = groupIdElement.attributeValue("name");
String pattern = groupIdElement.attributeValue("pattern");
ThemeGroupId themeGroupId = null;
if (Validator.isNotNull(name)) {
themeGroupId = new ThemeGroupId(name, false);
}
else if (Validator.isNotNull(pattern)) {
themeGroupId = new ThemeGroupId(pattern, true);
}
if (themeGroupId != null) {
includes.add(themeGroupId);
}
}
return includes;
}
private List _getGroupLimitIncludes(Element element) {
return _getGroupLimitExcludes(element);
}
private Map _getThemes(long companyId) {
Map themes = _themesPool.get(companyId);
if (themes != null) {
return themes;
}
themes = new ConcurrentHashMap<>();
for (Map.Entry entry : _themes.entrySet()) {
Theme theme = entry.getValue();
if (theme.isCompanyAvailable(companyId)) {
themes.put(entry.getKey(), theme);
}
}
_themesPool.put(companyId, themes);
return themes;
}
private Version _getVersion(String version) {
if (version.equals("${current-version}")) {
version = ReleaseInfo.getVersion();
}
return Version.getInstance(version);
}
private void _readColorSchemes(
Element themeElement, Map colorSchemes,
ContextReplace themeContextReplace) {
List colorSchemeElements = themeElement.elements(
"color-scheme");
for (Element colorSchemeElement : colorSchemeElements) {
ContextReplace colorSchemeContextReplace =
(ContextReplace)themeContextReplace.clone();
String id = colorSchemeElement.attributeValue("id");
colorSchemeContextReplace.addValue("color-scheme-id", id);
ColorScheme colorSchemeModel = colorSchemes.get(id);
if (colorSchemeModel == null) {
colorSchemeModel = ColorSchemeFactoryUtil.getColorScheme(id);
}
String name = GetterUtil.getString(
colorSchemeElement.attributeValue("name"),
colorSchemeModel.getName());
name = colorSchemeContextReplace.replace(name);
boolean defaultCs = GetterUtil.getBoolean(
colorSchemeElement.elementText("default-cs"),
colorSchemeModel.isDefaultCs());
String cssClass = GetterUtil.getString(
colorSchemeElement.elementText("css-class"),
colorSchemeModel.getCssClass());
cssClass = colorSchemeContextReplace.replace(cssClass);
colorSchemeContextReplace.addValue("css-class", cssClass);
String colorSchemeImagesPath = GetterUtil.getString(
colorSchemeElement.elementText("color-scheme-images-path"),
colorSchemeModel.getColorSchemeImagesPath());
colorSchemeImagesPath = colorSchemeContextReplace.replace(
colorSchemeImagesPath);
colorSchemeContextReplace.addValue(
"color-scheme-images-path", colorSchemeImagesPath);
colorSchemeModel.setName(name);
colorSchemeModel.setDefaultCs(defaultCs);
colorSchemeModel.setCssClass(cssClass);
colorSchemeModel.setColorSchemeImagesPath(colorSchemeImagesPath);
colorSchemes.put(id, colorSchemeModel);
}
}
private void _readPortletDecorators(
Element themeElement, Map portletDecorators,
ContextReplace themeContextReplace) {
List portletDecoratorElements = themeElement.elements(
"portlet-decorator");
for (Element portletDecoratorElement : portletDecoratorElements) {
ContextReplace portletDecoratorContextReplace =
(ContextReplace)themeContextReplace.clone();
String id = portletDecoratorElement.attributeValue("id");
portletDecoratorContextReplace.addValue("portlet-decorator-id", id);
PortletDecorator portletDecoratorModel = portletDecorators.get(id);
if (portletDecoratorModel == null) {
portletDecoratorModel =
PortletDecoratorFactoryUtil.getPortletDecorator(id);
}
String name = GetterUtil.getString(
portletDecoratorElement.attributeValue("name"),
portletDecoratorModel.getName());
name = portletDecoratorContextReplace.replace(name);
boolean defaultPortletDecorator = GetterUtil.getBoolean(
portletDecoratorElement.elementText(
"default-portlet-decorator"),
portletDecoratorModel.isDefaultPortletDecorator());
String cssClass = GetterUtil.getString(
portletDecoratorElement.elementText(
"portlet-decorator-css-class"),
portletDecoratorModel.getCssClass());
cssClass = portletDecoratorContextReplace.replace(cssClass);
portletDecoratorContextReplace.addValue(
"portlet-decorator-css-class", cssClass);
String portletDecoratorThumbnailPath = GetterUtil.getString(
portletDecoratorElement.elementText(
"portlet-decorator-thumbnail-path"),
portletDecoratorModel.getPortletDecoratorThumbnailPath());
portletDecoratorThumbnailPath =
portletDecoratorContextReplace.replace(
portletDecoratorThumbnailPath);
portletDecoratorContextReplace.addValue(
"portlet-decorator-thumbnail-path",
portletDecoratorThumbnailPath);
portletDecoratorModel.setName(name);
portletDecoratorModel.setDefaultPortletDecorator(
defaultPortletDecorator);
portletDecoratorModel.setCssClass(cssClass);
portletDecoratorModel.setPortletDecoratorThumbnailPath(
portletDecoratorThumbnailPath);
portletDecorators.put(id, portletDecoratorModel);
}
}
private Set _readThemes(
String servletContextName, ServletContext servletContext,
String themesPath, boolean loadFromServletContext, String xml,
PluginPackage pluginPackage)
throws Exception {
Set themes = new HashSet<>();
if (xml == null) {
return themes;
}
Document document = UnsecureSAXReaderUtil.read(xml, true);
Element rootElement = document.getRootElement();
boolean compatible = false;
Element compatibilityElement = rootElement.element("compatibility");
if (compatibilityElement != null) {
Version portalVersion = _getVersion(ReleaseInfo.getVersion());
List versionElements = compatibilityElement.elements(
"version");
for (Element versionElement : versionElements) {
Version version = _getVersion(versionElement.getTextTrim());
if (version.includes(portalVersion)) {
compatible = true;
break;
}
}
}
if (!compatible) {
_log.error(
"Themes in this WAR are not compatible with " +
ReleaseInfo.getServerInfo());
return themes;
}
ThemeCompanyLimit companyLimit = null;
Element companyLimitElement = rootElement.element("company-limit");
if (companyLimitElement != null) {
companyLimit = new ThemeCompanyLimit();
Element companyIncludesElement = companyLimitElement.element(
"company-includes");
if (companyIncludesElement != null) {
companyLimit.setIncludes(
_getCompanyLimitIncludes(companyIncludesElement));
}
Element companyExcludesElement = companyLimitElement.element(
"company-excludes");
if (companyExcludesElement != null) {
companyLimit.setExcludes(
_getCompanyLimitExcludes(companyExcludesElement));
}
}
ThemeGroupLimit groupLimit = null;
Element groupLimitElement = rootElement.element("group-limit");
if (groupLimitElement != null) {
groupLimit = new ThemeGroupLimit();
Element groupIncludesElement = groupLimitElement.element(
"group-includes");
if (groupIncludesElement != null) {
groupLimit.setIncludes(
_getGroupLimitIncludes(groupIncludesElement));
}
Element groupExcludesElement = groupLimitElement.element(
"group-excludes");
if (groupExcludesElement != null) {
groupLimit.setExcludes(
_getGroupLimitExcludes(groupExcludesElement));
}
}
long timestamp = ServletContextUtil.getLastModified(servletContext);
List themeElements = rootElement.elements("theme");
for (Element themeElement : themeElements) {
ContextReplace themeContextReplace = new ContextReplace();
themeContextReplace.addValue("themes-path", themesPath);
String themeId = themeElement.attributeValue("id");
if (servletContextName != null) {
themeId =
themeId + PortletConstants.WAR_SEPARATOR +
servletContextName;
}
themeId = PortalUtil.getJsSafePortletId(themeId);
themeContextReplace.addValue("theme-id", themeId);
Theme theme = _themes.get(themeId);
if (theme == null) {
theme = ThemeFactoryUtil.getTheme(themeId);
}
String templateExtension = GetterUtil.getString(
themeElement.elementText("template-extension"),
theme.getTemplateExtension());
if (!templateExtension.equals(TemplateConstants.LANG_TYPE_FTL)) {
if (_log.isWarnEnabled()) {
_log.warn(
StringBundler.concat(
templateExtension, " is no longer supported for ",
"theme. Please Update theme ", themeId,
" to use FreeMarker for forward compatibility."));
}
continue;
}
theme.setTemplateExtension(templateExtension);
theme.setTimestamp(timestamp);
PluginSetting pluginSetting =
_pluginSettingLocalService.getDefaultPluginSetting();
theme.setPluginPackage(pluginPackage);
theme.setDefaultPluginSetting(pluginSetting);
theme.setThemeCompanyLimit(companyLimit);
theme.setThemeGroupLimit(groupLimit);
if (servletContextName != null) {
theme.setServletContextName(servletContextName);
}
theme.setLoadFromServletContext(loadFromServletContext);
String name = GetterUtil.getString(
themeElement.attributeValue("name"), theme.getName());
String rootPath = GetterUtil.getString(
themeElement.elementText("root-path"), theme.getRootPath());
rootPath = themeContextReplace.replace(rootPath);
themeContextReplace.addValue("root-path", rootPath);
String templatesPath = GetterUtil.getString(
themeElement.elementText("templates-path"),
theme.getTemplatesPath());
templatesPath = themeContextReplace.replace(templatesPath);
templatesPath = StringUtil.replace(
templatesPath, StringPool.DOUBLE_SLASH, StringPool.SLASH);
themeContextReplace.addValue("templates-path", templatesPath);
String cssPath = GetterUtil.getString(
themeElement.elementText("css-path"), theme.getCssPath());
cssPath = themeContextReplace.replace(cssPath);
cssPath = StringUtil.replace(
cssPath, StringPool.DOUBLE_SLASH, StringPool.SLASH);
themeContextReplace.addValue("css-path", cssPath);
String imagesPath = GetterUtil.getString(
themeElement.elementText("images-path"), theme.getImagesPath());
imagesPath = themeContextReplace.replace(imagesPath);
imagesPath = StringUtil.replace(
imagesPath, StringPool.DOUBLE_SLASH, StringPool.SLASH);
themeContextReplace.addValue("images-path", imagesPath);
String javaScriptPath = GetterUtil.getString(
themeElement.elementText("javascript-path"),
theme.getJavaScriptPath());
javaScriptPath = themeContextReplace.replace(javaScriptPath);
javaScriptPath = StringUtil.replace(
javaScriptPath, StringPool.DOUBLE_SLASH, StringPool.SLASH);
themeContextReplace.addValue("javascript-path", javaScriptPath);
String virtualPath = GetterUtil.getString(
themeElement.elementText("virtual-path"),
theme.getVirtualPath());
theme.setName(name);
theme.setRootPath(rootPath);
theme.setTemplatesPath(templatesPath);
theme.setCssPath(cssPath);
theme.setImagesPath(imagesPath);
theme.setJavaScriptPath(javaScriptPath);
theme.setVirtualPath(virtualPath);
Element settingsElement = themeElement.element("settings");
if (settingsElement != null) {
List settingElements = settingsElement.elements(
"setting");
for (Element settingElement : settingElements) {
boolean configurable = GetterUtil.getBoolean(
settingElement.attributeValue("configurable"));
String key = settingElement.attributeValue("key");
String[] options = StringUtil.split(
settingElement.attributeValue("options"));
String type = settingElement.attributeValue("type", "text");
String value = settingElement.attributeValue(
"value", StringPool.BLANK);
String script = settingElement.getTextTrim();
theme.addSetting(
key, value, configurable, type, options, script);
}
}
theme.setControlPanelTheme(
GetterUtil.getBoolean(
themeElement.elementText("control-panel-theme")));
theme.setPageTheme(
GetterUtil.getBoolean(
themeElement.elementText("page-theme"), true));
Element rolesElement = themeElement.element("roles");
if (rolesElement != null) {
List roleNameElements = rolesElement.elements(
"role-name");
for (Element roleNameElement : roleNameElements) {
pluginSetting.addRole(roleNameElement.getText());
}
}
_readColorSchemes(
themeElement, theme.getColorSchemesMap(), themeContextReplace);
_readColorSchemes(
themeElement, theme.getColorSchemesMap(), themeContextReplace);
Element layoutTemplatesElement = themeElement.element(
"layout-templates");
if (layoutTemplatesElement != null) {
Element standardElement = layoutTemplatesElement.element(
"standard");
if (standardElement != null) {
_layoutTemplateLocalService.readLayoutTemplate(
servletContextName, servletContext, null,
standardElement, true, themeId, pluginPackage);
}
Element customElement = layoutTemplatesElement.element(
"custom");
if (customElement != null) {
_layoutTemplateLocalService.readLayoutTemplate(
servletContextName, servletContext, null, customElement,
false, themeId, pluginPackage);
}
}
if (!_themes.containsKey(themeId)) {
_themes.put(themeId, theme);
}
_readPortletDecorators(
themeElement, theme.getPortletDecoratorsMap(),
themeContextReplace);
themes.add(theme);
}
return themes;
}
private static final Log _log = LogFactoryUtil.getLog(
ThemeLocalServiceImpl.class);
private static final Map _themes = new ConcurrentHashMap<>();
private static final Map> _themesPool =
new ConcurrentHashMap<>();
@BeanReference(type = LayoutTemplateLocalService.class)
private LayoutTemplateLocalService _layoutTemplateLocalService;
@BeanReference(type = PluginSettingLocalService.class)
private PluginSettingLocalService _pluginSettingLocalService;
} © 2015 - 2025 Weber Informatics LLC | Privacy Policy