001
014
015 package com.liferay.portal.kernel.deploy.hot;
016
017 import com.liferay.portal.kernel.concurrent.LockRegistry;
018 import com.liferay.portal.kernel.log.Log;
019 import com.liferay.portal.kernel.log.LogFactoryUtil;
020 import com.liferay.portal.kernel.spring.context.PortletContextLoaderListener;
021 import com.liferay.portal.kernel.util.BasePortalLifecycle;
022 import com.liferay.portal.kernel.util.PortalLifecycle;
023 import com.liferay.portal.kernel.util.PortalLifecycleUtil;
024 import com.liferay.portal.kernel.util.StringUtil;
025
026 import java.util.ArrayList;
027 import java.util.Collections;
028 import java.util.HashSet;
029 import java.util.List;
030 import java.util.Set;
031 import java.util.concurrent.CopyOnWriteArrayList;
032
033
037 public class HotDeployUtil {
038
039 public static void fireDeployEvent(HotDeployEvent event) {
040 _instance._fireDeployEvent(event);
041 }
042
043 public static void fireUndeployEvent(HotDeployEvent event) {
044 _instance._fireUndeployEvent(event);
045 }
046
047 public static void registerListener(HotDeployListener listener) {
048 _instance._registerListener(listener);
049 }
050
051 public static void reset() {
052 _instance._reset();
053 }
054
055 public static void setCapturePrematureEvents(
056 boolean capturePrematureEvents) {
057
058 _instance._setCapturePrematureEvents(capturePrematureEvents);
059 }
060
061 public static void unregisterListener(HotDeployListener listener) {
062 _instance._unregisterListener(listener);
063 }
064
065 public static void unregisterListeners() {
066 _instance._unregisterListeners();
067 }
068
069 private HotDeployUtil() {
070 if (_log.isInfoEnabled()) {
071 _log.info("Initializing hot deploy manager " + this.hashCode());
072 }
073
074 _dependentEvents = new ArrayList<HotDeployEvent>();
075 _deployedServletContextNames = new HashSet<String>();
076 _listeners = new CopyOnWriteArrayList<HotDeployListener>();
077 }
078
079 private void _doFireDeployEvent(HotDeployEvent event) {
080 if (_deployedServletContextNames.contains(
081 event.getServletContextName())) {
082
083 return;
084 }
085
086 boolean hasDependencies = true;
087
088 for (String dependentServletContextName :
089 event.getDependentServletContextNames()) {
090
091 if (!_deployedServletContextNames.contains(
092 dependentServletContextName)) {
093
094 hasDependencies = false;
095
096 break;
097 }
098 }
099
100 if (hasDependencies) {
101 if (_dependentEvents.contains(event)) {
102 if (_log.isInfoEnabled()) {
103 _log.info(
104 "Deploying " + event.getServletContextName() +
105 " from queue");
106 }
107 }
108
109 for (HotDeployListener listener : _listeners) {
110 try {
111 listener.invokeDeploy(event);
112 }
113 catch (HotDeployException hde) {
114 _log.error(hde, hde);
115 }
116 }
117
118 _deployedServletContextNames.add(event.getServletContextName());
119
120 _dependentEvents.remove(event);
121
122 List<HotDeployEvent> dependentEvents =
123 new ArrayList<HotDeployEvent>(_dependentEvents);
124
125 for (HotDeployEvent dependentEvent : dependentEvents) {
126 _doFireDeployEvent(dependentEvent);
127 }
128 }
129 else {
130 if (!_dependentEvents.contains(event)) {
131 if (_log.isInfoEnabled()) {
132 StringBuilder sb = new StringBuilder();
133
134 sb.append("Queueing ");
135 sb.append(event.getServletContextName());
136 sb.append(" for deploy because it is missing ");
137 sb.append(_getRequiredServletContextNames(event));
138
139 _log.info(sb.toString());
140 }
141
142 _dependentEvents.add(event);
143 }
144 else {
145 if (_log.isInfoEnabled()) {
146 for (HotDeployEvent dependentEvent : _dependentEvents) {
147
148 StringBuilder sb = new StringBuilder();
149
150 sb.append(dependentEvent.getServletContextName());
151 sb.append(" is still in queue because it is missing ");
152 sb.append(
153 _getRequiredServletContextNames(dependentEvent));
154
155 _log.info(sb.toString());
156 }
157 }
158 }
159 }
160 }
161
162 private void _fireDeployEvent(final HotDeployEvent event) {
163 if (_capturePrematureEvents) {
164
165
166
167 PortalLifecycle portalLifecycle = new BasePortalLifecycle() {
168
169 @Override
170 protected void doPortalDestroy() {
171 }
172
173 @Override
174 protected void doPortalInit() {
175 HotDeployUtil.fireDeployEvent(event);
176 }
177
178 };
179
180 PortalLifecycleUtil.register(
181 portalLifecycle, PortalLifecycle.METHOD_INIT);
182 }
183 else {
184
185
186
187 try {
188 _doFireDeployEvent(event);
189 }
190 finally {
191 String lockKey = PortletContextLoaderListener.getLockKey(
192 event.getServletContext());
193
194 LockRegistry.finallyFreeLock(lockKey, lockKey, true);
195 }
196 }
197 }
198
199 private void _fireUndeployEvent(HotDeployEvent event) {
200 for (HotDeployListener listener : _listeners) {
201 try {
202 listener.invokeUndeploy(event);
203 }
204 catch (HotDeployException hde) {
205 _log.error(hde, hde);
206 }
207 }
208
209 _deployedServletContextNames.remove(event.getServletContextName());
210 }
211
212 private String _getRequiredServletContextNames(HotDeployEvent event) {
213 List<String> requiredServletContextNames = new ArrayList<String>();
214
215 for (String dependentServletContextName :
216 event.getDependentServletContextNames()) {
217
218 if (!_deployedServletContextNames.contains(
219 dependentServletContextName)) {
220
221 requiredServletContextNames.add(dependentServletContextName);
222 }
223 }
224
225 Collections.sort(requiredServletContextNames);
226
227 return StringUtil.merge(requiredServletContextNames, ", ");
228 }
229
230 private void _registerListener(HotDeployListener listener) {
231 _listeners.add(listener);
232 }
233
234 private void _reset() {
235 _capturePrematureEvents = true;
236 _dependentEvents.clear();
237 _deployedServletContextNames.clear();
238 _listeners.clear();
239 }
240
241 private void _setCapturePrematureEvents(boolean capturePrematureEvents) {
242 _capturePrematureEvents = capturePrematureEvents;
243 }
244
245 private void _unregisterListener(HotDeployListener listener) {
246 _listeners.remove(listener);
247 }
248
249 private void _unregisterListeners() {
250 _listeners.clear();
251 }
252
253 private static Log _log = LogFactoryUtil.getLog(HotDeployUtil.class);
254
255 private static HotDeployUtil _instance = new HotDeployUtil();
256
257 private boolean _capturePrematureEvents = true;
258 private List<HotDeployEvent> _dependentEvents;
259 private Set<String> _deployedServletContextNames;
260 private List<HotDeployListener> _listeners;
261
262 }