1   /**
2    * Copyright (c) 2000-2009 Liferay, Inc. All rights reserved.
3    *
4    * The contents of this file are subject to the terms of the Liferay Enterprise
5    * Subscription License ("License"). You may not use this file except in
6    * compliance with the License. You can obtain a copy of the License by
7    * contacting Liferay, Inc. See the License for the specific language governing
8    * permissions and limitations under the License, including but not limited to
9    * distribution rights of the Software.
10   *
11   * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
12   * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
13   * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
14   * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
15   * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
16   * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
17   * SOFTWARE.
18   */
19  
20  package com.liferay.portal.kernel.deploy.hot;
21  
22  import com.liferay.portal.kernel.log.Log;
23  import com.liferay.portal.kernel.log.LogFactoryUtil;
24  
25  import java.util.ArrayList;
26  import java.util.HashSet;
27  import java.util.List;
28  import java.util.Set;
29  
30  /**
31   * <a href="HotDeployUtil.java.html"><b><i>View Source</i></b></a>
32   *
33   * @author Ivica Cardic
34   * @author Brian Wing Shun Chan
35   *
36   */
37  public class HotDeployUtil {
38  
39      public static void fireDeployEvent(HotDeployEvent event) {
40          _instance._fireDeployEvent(event);
41      }
42  
43      public static void fireUndeployEvent(HotDeployEvent event) {
44          _instance._fireUndeployEvent(event);
45      }
46  
47      public static void flushPrematureEvents() {
48          _instance._flushPrematureEvents();
49      }
50  
51      public static void registerListener(HotDeployListener listener) {
52          _instance._registerListener(listener);
53      }
54  
55      public static void unregisterListeners() {
56          _instance._unregisterListeners();
57      }
58  
59      private HotDeployUtil() {
60          if (_log.isInfoEnabled()) {
61              _log.info("Initializing hot deploy manager " + this.hashCode());
62          }
63  
64          _dependentEvents = new ArrayList<HotDeployEvent>();
65          _deployedServletContextNames = new HashSet<String>();
66          _listeners = new ArrayList<HotDeployListener>();
67          _prematureEvents = new ArrayList<HotDeployEvent>();
68      }
69  
70      private void _doFireDeployEvent(HotDeployEvent event) {
71          if (_deployedServletContextNames.contains(
72                  event.getServletContextName())) {
73  
74              return;
75          }
76  
77          boolean hasDependencies = true;
78  
79          Set<String> dependentServletContextNames =
80              event.getDependentServletContextNames();
81  
82          for (String dependentServletContextName :
83                  dependentServletContextNames) {
84  
85              if (!_deployedServletContextNames.contains(
86                      dependentServletContextName)) {
87  
88                  hasDependencies = false;
89  
90                  break;
91              }
92          }
93  
94          if (hasDependencies) {
95              if (_dependentEvents.contains(event)) {
96                  if (_log.isInfoEnabled()) {
97                      _log.info(
98                          "Deploy " + event.getServletContextName() +
99                              " from queue");
100                 }
101             }
102 
103             for (HotDeployListener listener : _listeners) {
104                 try {
105                     listener.invokeDeploy(event);
106                 }
107                 catch (HotDeployException hde) {
108                     _log.error(hde, hde);
109                 }
110             }
111 
112             _deployedServletContextNames.add(event.getServletContextName());
113 
114             _dependentEvents.remove(event);
115 
116             List<HotDeployEvent> dependentEvents =
117                 new ArrayList<HotDeployEvent>(_dependentEvents);
118 
119             for (HotDeployEvent dependentEvent : dependentEvents) {
120                 _doFireDeployEvent(dependentEvent);
121             }
122         }
123         else {
124             if (!_dependentEvents.contains(event)) {
125                 if (_log.isInfoEnabled()) {
126                     _log.info(
127                         "Queue " + event.getServletContextName() +
128                             " for deploy because its dependencies are not " +
129                                 "available");
130                 }
131 
132                 _dependentEvents.add(event);
133             }
134         }
135     }
136 
137     private void _fireDeployEvent(HotDeployEvent event) {
138 
139         // Capture events that are fired before the portal initialized. These
140         // events are later fired by flushPrematureEvents.
141 
142         if (_prematureEvents != null) {
143             _prematureEvents.add(event);
144 
145             return;
146         }
147 
148         // Fire current event
149 
150         _doFireDeployEvent(event);
151     }
152 
153     private void _fireUndeployEvent(HotDeployEvent event) {
154         for (HotDeployListener listener : _listeners) {
155             try {
156                 listener.invokeUndeploy(event);
157             }
158             catch (HotDeployException hde) {
159                 _log.error(hde, hde);
160             }
161         }
162 
163         _deployedServletContextNames.remove(event.getServletContextName());
164     }
165 
166     private void _flushPrematureEvents() {
167         for (HotDeployEvent event : _prematureEvents) {
168             _doFireDeployEvent(event);
169         }
170 
171         _prematureEvents = null;
172     }
173 
174     private void _registerListener(HotDeployListener listener) {
175         _listeners.add(listener);
176     }
177 
178     private void _unregisterListeners() {
179         _listeners.clear();
180     }
181 
182     private static Log _log = LogFactoryUtil.getLog(HotDeployUtil.class);
183 
184     private static HotDeployUtil _instance = new HotDeployUtil();
185 
186     private List<HotDeployEvent> _dependentEvents;
187     private Set<String> _deployedServletContextNames;
188     private List<HotDeployListener> _listeners;
189     private List<HotDeployEvent> _prematureEvents;
190 
191 }