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.kernel.deploy.hot;
016    
017    import com.liferay.portal.kernel.deploy.DeployManagerUtil;
018    import com.liferay.portal.kernel.log.Log;
019    import com.liferay.portal.kernel.log.LogFactoryUtil;
020    import com.liferay.portal.kernel.plugin.PluginPackage;
021    import com.liferay.portal.kernel.util.ArrayUtil;
022    import com.liferay.portal.kernel.util.PortalLifecycle;
023    import com.liferay.portal.kernel.util.PropertiesUtil;
024    import com.liferay.portal.kernel.util.ReleaseInfo;
025    import com.liferay.portal.kernel.util.StringUtil;
026    
027    import java.io.IOException;
028    import java.io.InputStream;
029    
030    import java.util.List;
031    import java.util.Properties;
032    import java.util.Queue;
033    import java.util.Set;
034    import java.util.TreeSet;
035    import java.util.concurrent.ConcurrentLinkedQueue;
036    
037    import javax.servlet.ServletContext;
038    
039    /**
040     * @author Ivica Cardic
041     * @author Brian Wing Shun Chan
042     * @author Raymond Aug??
043     * @author Miguel Pastor
044     */
045    public class HotDeployEvent {
046    
047            public HotDeployEvent(
048                    ServletContext servletContext, ClassLoader contextClassLoader) {
049    
050                    _servletContext = servletContext;
051                    _contextClassLoader = contextClassLoader;
052    
053                    try {
054                            initDependentServletContextNames();
055                    }
056                    catch (IOException ioe) {
057                            _log.error(ioe, ioe);
058                    }
059            }
060    
061            public void addPortalLifecycle(PortalLifecycle portalLifecycle) {
062                    _portalLifecycles.add(portalLifecycle);
063            }
064    
065            public void flushInits() {
066                    for (PortalLifecycle portalLifecycle : _portalLifecycles) {
067                            portalLifecycle.portalInit();
068                    }
069    
070                    _portalLifecycles.clear();
071            }
072    
073            public ClassLoader getContextClassLoader() {
074                    return _contextClassLoader;
075            }
076    
077            public Set<String> getDependentServletContextNames() {
078                    return _dependentServletContextNames;
079            }
080    
081            public PluginPackage getPluginPackage() {
082                    return _pluginPackage;
083            }
084    
085            public ServletContext getServletContext() {
086                    return _servletContext;
087            }
088    
089            public String getServletContextName() {
090                    return _servletContext.getServletContextName();
091            }
092    
093            public void setPluginPackage(PluginPackage pluginPackage) {
094                    _pluginPackage = pluginPackage;
095            }
096    
097            protected void initDependentServletContextNames() throws IOException {
098                    if (!DependencyManagementThreadLocal.isEnabled() || isWAB()) {
099                            return;
100                    }
101    
102                    List<String[]> levelsRequiredDeploymentContexts =
103                            DeployManagerUtil.getLevelsRequiredDeploymentContexts();
104    
105                    for (String[] levelRequiredDeploymentContexts :
106                                    levelsRequiredDeploymentContexts) {
107    
108                            if (ArrayUtil.contains(
109                                            levelRequiredDeploymentContexts,
110                                            _servletContext.getServletContextName())) {
111    
112                                    break;
113                            }
114    
115                            for (String levelRequiredDeploymentContext :
116                                            levelRequiredDeploymentContexts) {
117    
118                                    _dependentServletContextNames.add(
119                                            levelRequiredDeploymentContext);
120                            }
121                    }
122    
123                    InputStream inputStream = _servletContext.getResourceAsStream(
124                            "/WEB-INF/liferay-plugin-package.properties");
125    
126                    if (inputStream != null) {
127                            String propertiesString = StringUtil.read(inputStream);
128    
129                            Properties properties = PropertiesUtil.load(propertiesString);
130    
131                            String[] pluginPackgeRequiredDeploymentContexts = StringUtil.split(
132                                    properties.getProperty("required-deployment-contexts"));
133    
134                            for (String pluginPackageRequiredDeploymentContext :
135                                            pluginPackgeRequiredDeploymentContexts) {
136    
137                                    _dependentServletContextNames.add(
138                                            pluginPackageRequiredDeploymentContext.trim());
139                            }
140                    }
141    
142                    if (!_dependentServletContextNames.isEmpty() && _log.isInfoEnabled()) {
143                            String servletContextName = _servletContext.getServletContextName();
144    
145                            _log.info(
146                                    "Plugin " + servletContextName + " requires " +
147                                            StringUtil.merge(_dependentServletContextNames, ", "));
148                    }
149            }
150    
151            protected boolean isWAB() {
152    
153                    // Never enable plugin dependency management when the servlet context is
154                    // from a Liferay WAB since dependency is handled by the OSGi runtime
155    
156                    Object osgiBundleContext = _servletContext.getAttribute(
157                            "osgi-bundlecontext");
158                    Object osgiRuntimeVendor = _servletContext.getAttribute(
159                            "osgi-runtime-vendor");
160    
161                    if ((osgiBundleContext != null) && (osgiRuntimeVendor != null) &&
162                            osgiRuntimeVendor.equals(ReleaseInfo.getVendor())) {
163    
164                            return true;
165                    }
166    
167                    return false;
168            }
169    
170            private static final Log _log = LogFactoryUtil.getLog(HotDeployEvent.class);
171    
172            private final ClassLoader _contextClassLoader;
173            private final Set<String> _dependentServletContextNames = new TreeSet<>();
174            private PluginPackage _pluginPackage;
175            private final Queue<PortalLifecycle> _portalLifecycles =
176                    new ConcurrentLinkedQueue<>();
177            private final ServletContext _servletContext;
178    
179    }