1   /**
2    * Copyright (c) 2000-2010 Liferay, Inc. All rights reserved.
3    *
4    * This library is free software; you can redistribute it and/or modify it under
5    * the terms of the GNU Lesser General Public License as published by the Free
6    * Software Foundation; either version 2.1 of the License, or (at your option)
7    * any later version.
8    *
9    * This library is distributed in the hope that it will be useful, but WITHOUT
10   * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
11   * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
12   * details.
13   */
14  
15  package com.liferay.portal.kernel.deploy.hot;
16  
17  import com.liferay.portal.kernel.log.Log;
18  import com.liferay.portal.kernel.log.LogFactoryUtil;
19  
20  import java.util.ArrayList;
21  import java.util.HashSet;
22  import java.util.List;
23  import java.util.Set;
24  import java.util.concurrent.CopyOnWriteArrayList;
25  
26  /**
27   * <a href="HotDeployUtil.java.html"><b><i>View Source</i></b></a>
28   *
29   * @author Ivica Cardic
30   * @author Brian Wing Shun Chan
31   */
32  public class HotDeployUtil {
33  
34      public static void fireDeployEvent(HotDeployEvent event) {
35          _instance._fireDeployEvent(event);
36      }
37  
38      public static void fireUndeployEvent(HotDeployEvent event) {
39          _instance._fireUndeployEvent(event);
40      }
41  
42      public static void flushPrematureEvents() {
43          _instance._flushPrematureEvents();
44      }
45  
46      public static void registerListener(HotDeployListener listener) {
47          _instance._registerListener(listener);
48      }
49  
50      public static void unregisterListener(HotDeployListener listener) {
51          _instance._unregisterListener(listener);
52      }
53  
54      public static void unregisterListeners() {
55          _instance._unregisterListeners();
56      }
57  
58      private HotDeployUtil() {
59          if (_log.isInfoEnabled()) {
60              _log.info("Initializing hot deploy manager " + this.hashCode());
61          }
62  
63          _dependentEvents = new ArrayList<HotDeployEvent>();
64          _deployedServletContextNames = new HashSet<String>();
65          _listeners = new CopyOnWriteArrayList<HotDeployListener>();
66          _prematureEvents = new ArrayList<HotDeployEvent>();
67      }
68  
69      private void _doFireDeployEvent(HotDeployEvent event) {
70          if (_deployedServletContextNames.contains(
71                  event.getServletContextName())) {
72  
73              return;
74          }
75  
76          boolean hasDependencies = true;
77  
78          Set<String> dependentServletContextNames =
79              event.getDependentServletContextNames();
80  
81          for (String dependentServletContextName :
82                  dependentServletContextNames) {
83  
84              if (!_deployedServletContextNames.contains(
85                      dependentServletContextName)) {
86  
87                  hasDependencies = false;
88  
89                  break;
90              }
91          }
92  
93          if (hasDependencies) {
94              if (_dependentEvents.contains(event)) {
95                  if (_log.isInfoEnabled()) {
96                      _log.info(
97                          "Deploy " + event.getServletContextName() +
98                              " from queue");
99                  }
100             }
101 
102             for (HotDeployListener listener : _listeners) {
103                 try {
104                     listener.invokeDeploy(event);
105                 }
106                 catch (HotDeployException hde) {
107                     _log.error(hde, hde);
108                 }
109             }
110 
111             _deployedServletContextNames.add(event.getServletContextName());
112 
113             _dependentEvents.remove(event);
114 
115             List<HotDeployEvent> dependentEvents =
116                 new ArrayList<HotDeployEvent>(_dependentEvents);
117 
118             for (HotDeployEvent dependentEvent : dependentEvents) {
119                 _doFireDeployEvent(dependentEvent);
120             }
121         }
122         else {
123             if (!_dependentEvents.contains(event)) {
124                 if (_log.isInfoEnabled()) {
125                     _log.info(
126                         "Queue " + event.getServletContextName() +
127                             " for deploy because its dependencies are not " +
128                                 "available");
129                 }
130 
131                 _dependentEvents.add(event);
132             }
133         }
134     }
135 
136     private void _fireDeployEvent(HotDeployEvent event) {
137 
138         // Capture events that are fired before the portal initialized. These
139         // events are later fired by flushPrematureEvents.
140 
141         if (_prematureEvents != null) {
142             _prematureEvents.add(event);
143 
144             return;
145         }
146 
147         // Fire current event
148 
149         _doFireDeployEvent(event);
150     }
151 
152     private void _fireUndeployEvent(HotDeployEvent event) {
153         for (HotDeployListener listener : _listeners) {
154             try {
155                 listener.invokeUndeploy(event);
156             }
157             catch (HotDeployException hde) {
158                 _log.error(hde, hde);
159             }
160         }
161 
162         _deployedServletContextNames.remove(event.getServletContextName());
163     }
164 
165     private void _flushPrematureEvents() {
166         for (HotDeployEvent event : _prematureEvents) {
167             _doFireDeployEvent(event);
168         }
169 
170         _prematureEvents = null;
171     }
172 
173     private void _registerListener(HotDeployListener listener) {
174         _listeners.add(listener);
175     }
176 
177     private void _unregisterListener(HotDeployListener listener) {
178         _listeners.remove(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 }