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