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