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.cache.configurator.util.PortalCacheConfiguratorUtil;
018    import com.liferay.portal.kernel.configuration.Configuration;
019    import com.liferay.portal.kernel.configuration.ConfigurationFactoryUtil;
020    import com.liferay.portal.kernel.deploy.hot.BaseHotDeployListener;
021    import com.liferay.portal.kernel.deploy.hot.HotDeployEvent;
022    import com.liferay.portal.kernel.deploy.hot.HotDeployException;
023    import com.liferay.portal.kernel.log.Log;
024    import com.liferay.portal.kernel.log.LogFactoryUtil;
025    import com.liferay.portal.kernel.plugin.PluginPackage;
026    import com.liferay.portal.kernel.servlet.ServletContextPool;
027    import com.liferay.portal.kernel.util.GetterUtil;
028    import com.liferay.portal.kernel.util.PropsKeys;
029    import com.liferay.portal.kernel.util.Validator;
030    import com.liferay.portal.plugin.PluginPackageUtil;
031    import com.liferay.portal.service.ServiceComponentLocalServiceUtil;
032    import com.liferay.portal.service.configuration.ServiceComponentConfiguration;
033    import com.liferay.portal.service.configuration.servlet.ServletServiceContextComponentConfiguration;
034    import com.liferay.util.log4j.Log4JUtil;
035    import com.liferay.util.portlet.PortletProps;
036    
037    import java.lang.reflect.Method;
038    
039    import java.net.URL;
040    
041    import java.util.Properties;
042    
043    import javax.servlet.ServletContext;
044    
045    /**
046     * @author Jorge Ferrer
047     */
048    public class PluginPackageHotDeployListener extends BaseHotDeployListener {
049    
050            public static final String SERVICE_BUILDER_PROPERTIES =
051                    "SERVICE_BUILDER_PROPERTIES";
052    
053            @Override
054            public void invokeDeploy(HotDeployEvent hotDeployEvent)
055                    throws HotDeployException {
056    
057                    try {
058                            doInvokeDeploy(hotDeployEvent);
059                    }
060                    catch (Throwable t) {
061                            throwHotDeployException(
062                                    hotDeployEvent, "Error registering plugins for ", t);
063                    }
064            }
065    
066            @Override
067            public void invokeUndeploy(HotDeployEvent hotDeployEvent)
068                    throws HotDeployException {
069    
070                    try {
071                            doInvokeUndeploy(hotDeployEvent);
072                    }
073                    catch (Throwable t) {
074                            throwHotDeployException(
075                                    hotDeployEvent, "Error unregistering plugins for ", t);
076                    }
077            }
078    
079            protected void destroyServiceComponent(
080                            ServiceComponentConfiguration serviceComponentConfiguration,
081                            ClassLoader classLoader)
082                    throws Exception {
083    
084                    ServiceComponentLocalServiceUtil.destroyServiceComponent(
085                            serviceComponentConfiguration, classLoader);
086            }
087    
088            protected void doInvokeDeploy(HotDeployEvent hotDeployEvent)
089                    throws Exception {
090    
091                    ServletContext servletContext = hotDeployEvent.getServletContext();
092    
093                    String servletContextName = servletContext.getServletContextName();
094    
095                    if (_log.isDebugEnabled()) {
096                            _log.debug("Invoking deploy for " + servletContextName);
097                    }
098    
099                    PluginPackage pluginPackage =
100                            PluginPackageUtil.readPluginPackageServletContext(servletContext);
101    
102                    if (pluginPackage == null) {
103                            return;
104                    }
105    
106                    if (servletContext.getResource(
107                                    "/WEB-INF/liferay-theme-loader.xml") != null) {
108    
109                            PluginPackageUtil.registerInstalledPluginPackage(pluginPackage);
110    
111                            return;
112                    }
113    
114                    pluginPackage.setContext(servletContextName);
115    
116                    hotDeployEvent.setPluginPackage(pluginPackage);
117    
118                    PluginPackageUtil.registerInstalledPluginPackage(pluginPackage);
119    
120                    ClassLoader classLoader = hotDeployEvent.getContextClassLoader();
121    
122                    initLogger(classLoader);
123                    initPortletProps(classLoader);
124                    initServiceComponent(servletContext, classLoader);
125    
126                    registerClpMessageListeners(servletContext, classLoader);
127    
128                    reconfigureCaches(classLoader);
129    
130                    if (_log.isInfoEnabled()) {
131                            _log.info(
132                                    "Plugin package " + pluginPackage.getModuleId() +
133                                            " registered successfully. It's now ready to be used.");
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                    PluginPackage pluginPackage =
149                            PluginPackageUtil.readPluginPackageServletContext(servletContext);
150    
151                    if (pluginPackage == null) {
152                            return;
153                    }
154    
155                    hotDeployEvent.setPluginPackage(pluginPackage);
156    
157                    PluginPackageUtil.unregisterInstalledPluginPackage(pluginPackage);
158    
159                    ServletContextPool.remove(servletContextName);
160    
161                    destroyServiceComponent(
162                            new ServletServiceContextComponentConfiguration(servletContext),
163                            hotDeployEvent.getContextClassLoader());
164    
165                    unregisterClpMessageListeners(servletContext);
166    
167                    if (_log.isInfoEnabled()) {
168                            _log.info(
169                                    "Plugin package " + pluginPackage.getModuleId() +
170                                            " unregistered successfully");
171                    }
172            }
173    
174            protected URL getPortalCacheConfigurationURL(
175                    Configuration configuration, ClassLoader classLoader,
176                    String configLocation) {
177    
178                    String cacheConfigurationLocation = configuration.get(configLocation);
179    
180                    if (Validator.isNull(cacheConfigurationLocation)) {
181                            return null;
182                    }
183    
184                    return classLoader.getResource(cacheConfigurationLocation);
185            }
186    
187            protected void initLogger(ClassLoader classLoader) {
188                    Log4JUtil.configureLog4J(
189                            classLoader.getResource("META-INF/portal-log4j.xml"));
190            }
191    
192            protected void initPortletProps(ClassLoader classLoader) throws Exception {
193                    if (classLoader.getResourceAsStream("portlet.properties") == null) {
194                            return;
195                    }
196    
197                    Class<?> clazz = classLoader.loadClass(PortletProps.class.getName());
198    
199                    Method method = clazz.getMethod("get", String.class);
200    
201                    method.invoke(null, "init");
202            }
203    
204            protected void initServiceComponent(
205                            ServletContext servletContext, ClassLoader classLoader)
206                    throws Exception {
207    
208                    Configuration serviceBuilderPropertiesConfiguration = null;
209    
210                    try {
211                            serviceBuilderPropertiesConfiguration =
212                                    ConfigurationFactoryUtil.getConfiguration(
213                                            classLoader, "service");
214                    }
215                    catch (Exception e) {
216                            if (_log.isDebugEnabled()) {
217                                    _log.debug("Unable to read service.properties");
218                            }
219    
220                            return;
221                    }
222    
223                    Properties serviceBuilderProperties =
224                            serviceBuilderPropertiesConfiguration.getProperties();
225    
226                    if (serviceBuilderProperties.isEmpty()) {
227                            return;
228                    }
229    
230                    servletContext.setAttribute(
231                            SERVICE_BUILDER_PROPERTIES, serviceBuilderProperties);
232    
233                    String buildNamespace = GetterUtil.getString(
234                            serviceBuilderProperties.getProperty("build.namespace"));
235                    long buildNumber = GetterUtil.getLong(
236                            serviceBuilderProperties.getProperty("build.number"));
237                    long buildDate = GetterUtil.getLong(
238                            serviceBuilderProperties.getProperty("build.date"));
239                    boolean buildAutoUpgrade = GetterUtil.getBoolean(
240                            serviceBuilderProperties.getProperty("build.auto.upgrade"), true);
241    
242                    if (_log.isDebugEnabled()) {
243                            _log.debug("Build namespace " + buildNamespace);
244                            _log.debug("Build number " + buildNumber);
245                            _log.debug("Build date " + buildDate);
246                            _log.debug("Build auto upgrade " + buildAutoUpgrade);
247                    }
248    
249                    if (Validator.isNull(buildNamespace)) {
250                            return;
251                    }
252    
253                    ServiceComponentLocalServiceUtil.initServiceComponent(
254                            new ServletServiceContextComponentConfiguration(servletContext),
255                            classLoader, buildNamespace, buildNumber, buildDate,
256                            buildAutoUpgrade);
257            }
258    
259            protected void reconfigureCaches(ClassLoader classLoader) throws Exception {
260                    Configuration portletPropertiesConfiguration = null;
261    
262                    try {
263                            portletPropertiesConfiguration =
264                                    ConfigurationFactoryUtil.getConfiguration(
265                                            classLoader, "portlet");
266                    }
267                    catch (Exception e) {
268                            if (_log.isDebugEnabled()) {
269                                    _log.debug("Unable to read portlet.properties");
270                            }
271    
272                            return;
273                    }
274    
275                    PortalCacheConfiguratorUtil.reconfigureCaches(
276                            classLoader,
277                            getPortalCacheConfigurationURL(
278                                    portletPropertiesConfiguration, classLoader,
279                                    PropsKeys.EHCACHE_SINGLE_VM_CONFIG_LOCATION));
280    
281                    PortalCacheConfiguratorUtil.reconfigureCaches(
282                            classLoader,
283                            getPortalCacheConfigurationURL(
284                                    portletPropertiesConfiguration, classLoader,
285                                    PropsKeys.EHCACHE_MULTI_VM_CONFIG_LOCATION));
286    
287                    PortalCacheConfiguratorUtil.reconfigureHibernateCache(
288                            getPortalCacheConfigurationURL(
289                                    portletPropertiesConfiguration, classLoader,
290                                    PropsKeys.NET_SF_EHCACHE_CONFIGURATION_RESOURCE_NAME));
291            }
292    
293            private static final Log _log = LogFactoryUtil.getLog(
294                    PluginPackageHotDeployListener.class);
295    
296    }