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.deploy.hot;
016    
017    import com.liferay.portal.kernel.deploy.hot.BaseHotDeployListener;
018    import com.liferay.portal.kernel.deploy.hot.HotDeployEvent;
019    import com.liferay.portal.kernel.deploy.hot.HotDeployException;
020    import com.liferay.portal.kernel.log.Log;
021    import com.liferay.portal.kernel.log.LogFactoryUtil;
022    import com.liferay.portal.kernel.model.Theme;
023    import com.liferay.portal.kernel.service.ThemeLocalServiceUtil;
024    import com.liferay.portal.kernel.servlet.FileTimestampUtil;
025    import com.liferay.portal.kernel.template.TemplateConstants;
026    import com.liferay.portal.kernel.template.TemplateResourceLoaderUtil;
027    import com.liferay.portal.kernel.util.ClassLoaderUtil;
028    import com.liferay.portal.kernel.util.HttpUtil;
029    import com.liferay.portal.kernel.util.ThemeHelper;
030    import com.liferay.portal.kernel.util.WebKeys;
031    
032    import java.util.HashMap;
033    import java.util.List;
034    import java.util.Map;
035    import java.util.Objects;
036    
037    import javax.servlet.ServletContext;
038    
039    /**
040     * @author Brian Wing Shun Chan
041     * @author Brian Myunghun Kim
042     * @author Ivica Cardic
043     */
044    public class ThemeHotDeployListener extends BaseHotDeployListener {
045    
046            @Override
047            public void invokeDeploy(HotDeployEvent hotDeployEvent)
048                    throws HotDeployException {
049    
050                    try {
051                            doInvokeDeploy(hotDeployEvent);
052                    }
053                    catch (Throwable t) {
054                            throwHotDeployException(
055                                    hotDeployEvent, "Error registering themes for ", t);
056                    }
057            }
058    
059            @Override
060            public void invokeUndeploy(HotDeployEvent hotDeployEvent)
061                    throws HotDeployException {
062    
063                    try {
064                            doInvokeUndeploy(hotDeployEvent);
065                    }
066                    catch (Throwable t) {
067                            throwHotDeployException(
068                                    hotDeployEvent, "Error unregistering themes for ", t);
069                    }
070            }
071    
072            protected void doInvokeDeploy(HotDeployEvent hotDeployEvent)
073                    throws Exception {
074    
075                    ServletContext servletContext = hotDeployEvent.getServletContext();
076    
077                    String servletContextName = servletContext.getServletContextName();
078    
079                    if (_log.isDebugEnabled()) {
080                            _log.debug("Invoking deploy for " + servletContextName);
081                    }
082    
083                    String[] xmls = new String[] {
084                            HttpUtil.URLtoString(
085                                    servletContext.getResource(
086                                            "/WEB-INF/liferay-look-and-feel.xml"))
087                    };
088    
089                    if (xmls[0] == null) {
090                            return;
091                    }
092    
093                    if (_log.isInfoEnabled()) {
094                            _log.info("Registering themes for " + servletContextName);
095                    }
096    
097                    FileTimestampUtil.reset();
098    
099                    List<Theme> themes = ThemeLocalServiceUtil.init(
100                            servletContextName, servletContext, null, true, xmls,
101                            hotDeployEvent.getPluginPackage());
102    
103                    _themes.put(servletContextName, themes);
104    
105                    servletContext.setAttribute(WebKeys.PLUGIN_THEMES, themes);
106    
107                    if (_log.isInfoEnabled()) {
108                            if (themes.size() == 1) {
109                                    _log.info(
110                                            "1 theme for " + servletContextName +
111                                                    " is available for use");
112                            }
113                            else {
114                                    _log.info(
115                                            themes.size() + " themes for " + servletContextName +
116                                                    " are available for use");
117                            }
118                    }
119    
120                    if (_log.isWarnEnabled()) {
121                            for (Theme theme : themes) {
122                                    if (!Objects.equals(
123                                                    theme.getTemplateExtension(),
124                                                    ThemeHelper.TEMPLATE_EXTENSION_VM)) {
125    
126                                            continue;
127                                    }
128    
129                                    _log.warn(
130                                            "Support of Velocity is deprecated. Update theme " +
131                                                    theme.getName() +
132                                                            " to use FreeMarker for forward compatibility.");
133                            }
134                    }
135            }
136    
137            protected void doInvokeUndeploy(HotDeployEvent hotDeployEvent)
138                    throws Exception {
139    
140                    ServletContext servletContext = hotDeployEvent.getServletContext();
141    
142                    String servletContextName = servletContext.getServletContextName();
143    
144                    if (_log.isDebugEnabled()) {
145                            _log.debug("Invoking undeploy for " + servletContextName);
146                    }
147    
148                    List<Theme> themes = _themes.remove(servletContextName);
149    
150                    if (themes != null) {
151                            if (_log.isInfoEnabled()) {
152                                    _log.info("Unregistering themes for " + servletContextName);
153                            }
154    
155                            try {
156                                    ThemeLocalServiceUtil.uninstallThemes(themes);
157                            }
158                            catch (Exception e) {
159                                    _log.error(e, e);
160                            }
161                    }
162                    else {
163                            return;
164                    }
165    
166                    // LEP-2057
167    
168                    ClassLoader contextClassLoader =
169                            ClassLoaderUtil.getContextClassLoader();
170    
171                    try {
172                            ClassLoaderUtil.setContextClassLoader(
173                                    ClassLoaderUtil.getPortalClassLoader());
174    
175                            TemplateResourceLoaderUtil.clearCache(
176                                    TemplateConstants.LANG_TYPE_VM);
177                    }
178                    finally {
179                            ClassLoaderUtil.setContextClassLoader(contextClassLoader);
180                    }
181    
182                    if (_log.isInfoEnabled()) {
183                            if (themes.size() == 1) {
184                                    _log.info(
185                                            "1 theme for " + servletContextName + " was unregistered");
186                            }
187                            else {
188                                    _log.info(
189                                            themes.size() + " themes for " + servletContextName +
190                                                    " were unregistered");
191                            }
192                    }
193            }
194    
195            private static final Log _log = LogFactoryUtil.getLog(
196                    ThemeHotDeployListener.class);
197    
198            private static final Map<String, List<Theme>> _themes = new HashMap<>();
199    
200    }