001    /**
002     * Copyright (c) 2000-2012 Liferay, Inc. All rights reserved.
003     *
004     * The contents of this file are subject to the terms of the Liferay Enterprise
005     * Subscription License ("License"). You may not use this file except in
006     * compliance with the License. You can obtain a copy of the License by
007     * contacting Liferay, Inc. See the License for the specific language governing
008     * permissions and limitations under the License, including but not limited to
009     * distribution rights of the Software.
010     *
011     *
012     *
013     */
014    
015    package com.liferay.portal.deploy.hot;
016    
017    import com.liferay.portal.dao.orm.hibernate.region.LiferayEhcacheRegionFactory;
018    import com.liferay.portal.dao.orm.hibernate.region.SingletonLiferayEhcacheRegionFactory;
019    import com.liferay.portal.kernel.bean.PortalBeanLocatorUtil;
020    import com.liferay.portal.kernel.cache.PortalCacheManager;
021    import com.liferay.portal.kernel.configuration.Configuration;
022    import com.liferay.portal.kernel.configuration.ConfigurationFactoryUtil;
023    import com.liferay.portal.kernel.deploy.hot.BaseHotDeployListener;
024    import com.liferay.portal.kernel.deploy.hot.HotDeployEvent;
025    import com.liferay.portal.kernel.deploy.hot.HotDeployException;
026    import com.liferay.portal.kernel.log.Log;
027    import com.liferay.portal.kernel.log.LogFactoryUtil;
028    import com.liferay.portal.kernel.plugin.PluginPackage;
029    import com.liferay.portal.kernel.servlet.ServletContextPool;
030    import com.liferay.portal.kernel.util.AggregateClassLoader;
031    import com.liferay.portal.kernel.util.GetterUtil;
032    import com.liferay.portal.kernel.util.PropsKeys;
033    import com.liferay.portal.kernel.util.Validator;
034    import com.liferay.portal.plugin.PluginPackageUtil;
035    import com.liferay.portal.security.pacl.PACLClassLoaderUtil;
036    import com.liferay.portal.service.ServiceComponentLocalServiceUtil;
037    import com.liferay.util.portlet.PortletProps;
038    
039    import java.lang.reflect.Method;
040    
041    import java.net.URL;
042    
043    import java.util.Properties;
044    
045    import javax.servlet.ServletContext;
046    
047    /**
048     * @author Jorge Ferrer
049     */
050    public class PluginPackageHotDeployListener extends BaseHotDeployListener {
051    
052            public static final String SERVICE_BUILDER_PROPERTIES =
053                    "SERVICE_BUILDER_PROPERTIES";
054    
055            public void invokeDeploy(HotDeployEvent hotDeployEvent)
056                    throws HotDeployException {
057    
058                    try {
059                            doInvokeDeploy(hotDeployEvent);
060                    }
061                    catch (Throwable t) {
062                            throwHotDeployException(
063                                    hotDeployEvent, "Error registering plugins for ", t);
064                    }
065            }
066    
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                            ServletContext servletContext, ClassLoader classLoader)
081                    throws Exception {
082    
083                    ServiceComponentLocalServiceUtil.destroyServiceComponent(
084                            servletContext, classLoader);
085            }
086    
087            protected void doInvokeDeploy(HotDeployEvent hotDeployEvent)
088                    throws Exception {
089    
090                    ServletContext servletContext = hotDeployEvent.getServletContext();
091    
092                    String servletContextName = servletContext.getServletContextName();
093    
094                    if (_log.isDebugEnabled()) {
095                            _log.debug("Invoking deploy for " + servletContextName);
096                    }
097    
098                    PluginPackage pluginPackage =
099                            PluginPackageUtil.readPluginPackageServletContext(servletContext);
100    
101                    if (pluginPackage == null) {
102                            return;
103                    }
104    
105                    if (servletContext.getResource(
106                                    "/WEB-INF/liferay-theme-loader.xml") != null) {
107    
108                            PluginPackageUtil.registerInstalledPluginPackage(pluginPackage);
109    
110                            return;
111                    }
112    
113                    pluginPackage.setContext(servletContextName);
114    
115                    hotDeployEvent.setPluginPackage(pluginPackage);
116    
117                    PluginPackageUtil.registerInstalledPluginPackage(pluginPackage);
118    
119                    ClassLoader classLoader = hotDeployEvent.getContextClassLoader();
120    
121                    initPortletProps(classLoader);
122    
123                    initServiceComponent(servletContext, classLoader);
124    
125                    registerClpMessageListeners(servletContext, classLoader);
126    
127                    reconfigureCaches(classLoader);
128    
129                    if (_log.isInfoEnabled()) {
130                            _log.info(
131                                    "Plugin package " + pluginPackage.getModuleId() +
132                                            " registered successfully. It's now ready to be used.");
133                    }
134            }
135    
136            protected void doInvokeUndeploy(HotDeployEvent hotDeployEvent)
137                    throws Exception {
138    
139                    ServletContext servletContext = hotDeployEvent.getServletContext();
140    
141                    String servletContextName = servletContext.getServletContextName();
142    
143                    if (_log.isDebugEnabled()) {
144                            _log.debug("Invoking deploy for " + servletContextName);
145                    }
146    
147                    PluginPackage pluginPackage =
148                            PluginPackageUtil.readPluginPackageServletContext(servletContext);
149    
150                    if (pluginPackage == null) {
151                            return;
152                    }
153    
154                    hotDeployEvent.setPluginPackage(pluginPackage);
155    
156                    PluginPackageUtil.unregisterInstalledPluginPackage(pluginPackage);
157    
158                    ServletContextPool.remove(servletContextName);
159    
160                    destroyServiceComponent(
161                            servletContext, hotDeployEvent.getContextClassLoader());
162    
163                    unregisterClpMessageListeners(servletContext);
164    
165                    if (_log.isInfoEnabled()) {
166                            _log.info(
167                                    "Plugin package " + pluginPackage.getModuleId() +
168                                            " unregistered successfully");
169                    }
170            }
171    
172            protected void initPortletProps(ClassLoader classLoader) throws Exception {
173                    if (classLoader.getResourceAsStream("portlet.properties") == null) {
174                            return;
175                    }
176    
177                    Class<?> clazz = classLoader.loadClass(PortletProps.class.getName());
178    
179                    Method method = clazz.getMethod("get", String.class);
180    
181                    method.invoke(null, "init");
182            }
183    
184            protected void initServiceComponent(
185                            ServletContext servletContext, ClassLoader classLoader)
186                    throws Exception {
187    
188                    Configuration serviceBuilderPropertiesConfiguration = null;
189    
190                    try {
191                            serviceBuilderPropertiesConfiguration =
192                                    ConfigurationFactoryUtil.getConfiguration(
193                                            classLoader, "service");
194                    }
195                    catch (Exception e) {
196                            if (_log.isDebugEnabled()) {
197                                    _log.debug("Unable to read service.properties");
198                            }
199    
200                            return;
201                    }
202    
203                    Properties serviceBuilderProperties =
204                            serviceBuilderPropertiesConfiguration.getProperties();
205    
206                    if (serviceBuilderProperties.size() == 0) {
207                            return;
208                    }
209    
210                    servletContext.setAttribute(
211                            SERVICE_BUILDER_PROPERTIES, serviceBuilderProperties);
212    
213                    String buildNamespace = GetterUtil.getString(
214                            serviceBuilderProperties.getProperty("build.namespace"));
215                    long buildNumber = GetterUtil.getLong(
216                            serviceBuilderProperties.getProperty("build.number"));
217                    long buildDate = GetterUtil.getLong(
218                            serviceBuilderProperties.getProperty("build.date"));
219                    boolean buildAutoUpgrade = GetterUtil.getBoolean(
220                            serviceBuilderProperties.getProperty("build.auto.upgrade"), true);
221    
222                    if (_log.isDebugEnabled()) {
223                            _log.debug("Build namespace " + buildNamespace);
224                            _log.debug("Build number " + buildNumber);
225                            _log.debug("Build date " + buildDate);
226                            _log.debug("Build auto upgrade " + buildAutoUpgrade);
227                    }
228    
229                    if (Validator.isNull(buildNamespace)) {
230                            return;
231                    }
232    
233                    ServiceComponentLocalServiceUtil.initServiceComponent(
234                            servletContext, classLoader, buildNamespace, buildNumber, buildDate,
235                            buildAutoUpgrade);
236            }
237    
238            protected void reconfigureCaches(ClassLoader classLoader) throws Exception {
239                    Configuration portletPropertiesConfiguration = null;
240    
241                    try {
242                            portletPropertiesConfiguration =
243                                    ConfigurationFactoryUtil.getConfiguration(
244                                            classLoader, "portlet");
245                    }
246                    catch (Exception e) {
247                            if (_log.isDebugEnabled()) {
248                                    _log.debug("Unable to read portlet.properties");
249                            }
250    
251                            return;
252                    }
253    
254                    String cacheConfigurationLocation = portletPropertiesConfiguration.get(
255                            PropsKeys.EHCACHE_SINGLE_VM_CONFIG_LOCATION);
256    
257                    reconfigureCaches(
258                            classLoader, cacheConfigurationLocation,
259                            _SINGLE_VM_PORTAL_CACHE_MANAGER_BEAN_NAME);
260    
261                    String clusterCacheConfigurationLocation =
262                            portletPropertiesConfiguration.get(
263                                    PropsKeys.EHCACHE_MULTI_VM_CONFIG_LOCATION);
264    
265                    reconfigureCaches(
266                            classLoader, clusterCacheConfigurationLocation,
267                            _MULTI_VM_PORTAL_CACHE_MANAGER_BEAN_NAME);
268    
269                    String hibernateCacheConfigurationPath =
270                            portletPropertiesConfiguration.get(
271                                    PropsKeys.NET_SF_EHCACHE_CONFIGURATION_RESOURCE_NAME);
272    
273                    reconfigureHibernateCache(classLoader, hibernateCacheConfigurationPath);
274            }
275    
276            protected void reconfigureCaches(
277                            ClassLoader classLoader, String cacheConfigurationPath,
278                            String portalCacheManagerBeanId)
279                    throws Exception {
280    
281                    if (Validator.isNull(cacheConfigurationPath)) {
282                            return;
283                    }
284    
285                    URL cacheConfigurationURL = classLoader.getResource(
286                            cacheConfigurationPath);
287    
288                    if (cacheConfigurationURL == null) {
289                            return;
290                    }
291    
292                    ClassLoader aggregateClassLoader =
293                            AggregateClassLoader.getAggregateClassLoader(
294                                    new ClassLoader[] {
295                                            PACLClassLoaderUtil.getPortalClassLoader(), classLoader
296                                    });
297    
298                    ClassLoader contextClassLoader =
299                            PACLClassLoaderUtil.getContextClassLoader();
300    
301                    try {
302                            PACLClassLoaderUtil.setContextClassLoader(aggregateClassLoader);
303    
304                            PortalCacheManager portalCacheManager =
305                                    (PortalCacheManager)PortalBeanLocatorUtil.locate(
306                                            portalCacheManagerBeanId);
307    
308                            if (_log.isInfoEnabled()) {
309                                    _log.info(
310                                            "Reconfiguring caches in cache manager " +
311                                                    portalCacheManagerBeanId + " using " +
312                                                            cacheConfigurationURL);
313                            }
314    
315                            portalCacheManager.reconfigureCaches(cacheConfigurationURL);
316                    }
317                    finally {
318                            PACLClassLoaderUtil.setContextClassLoader(contextClassLoader);
319                    }
320            }
321    
322            protected void reconfigureHibernateCache(
323                    ClassLoader classLoader, String hibernateCacheConfigurationPath) {
324    
325                    if (Validator.isNull(hibernateCacheConfigurationPath)) {
326                            return;
327                    }
328    
329                    LiferayEhcacheRegionFactory liferayEhcacheRegionFactory =
330                            SingletonLiferayEhcacheRegionFactory.getInstance();
331    
332                    URL configurationFile = classLoader.getResource(
333                            hibernateCacheConfigurationPath);
334    
335                    if (Validator.isNotNull(configurationFile)) {
336                            if (_log.isInfoEnabled()) {
337                                    _log.info(
338                                            "Reconfiguring Hibernate caches using " +
339                                                    configurationFile);
340                            }
341    
342                            liferayEhcacheRegionFactory.reconfigureCaches(configurationFile);
343                    }
344            }
345    
346            private static final String _MULTI_VM_PORTAL_CACHE_MANAGER_BEAN_NAME =
347                    "com.liferay.portal.kernel.cache.MultiVMPortalCacheManager";
348    
349            private static final String _SINGLE_VM_PORTAL_CACHE_MANAGER_BEAN_NAME =
350                    "com.liferay.portal.kernel.cache.SingleVMPortalCacheManager";
351    
352            private static Log _log = LogFactoryUtil.getLog(
353                    PluginPackageHotDeployListener.class);
354    
355    }