1 /**
2 *
3 * Copyright 2003-2004 The Apache Software Foundation
4 *
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 */
17
18 package org.apache.geronimo.kernel.basic;
19
20 import java.util.Collections;
21 import java.util.HashMap;
22 import java.util.HashSet;
23 import java.util.Iterator;
24 import java.util.Map;
25 import java.util.Set;
26
27 import org.apache.commons.logging.Log;
28 import org.apache.commons.logging.LogFactory;
29 import org.apache.geronimo.kernel.Kernel;
30 import org.apache.geronimo.kernel.GBeanNotFoundException;
31 import org.apache.geronimo.kernel.lifecycle.LifecycleMonitor;
32 import org.apache.geronimo.kernel.lifecycle.LifecycleListener;
33 import org.apache.geronimo.gbean.runtime.LifecycleBroadcaster;
34 import org.apache.geronimo.gbean.AbstractNameQuery;
35 import org.apache.geronimo.gbean.AbstractName;
36 import org.apache.geronimo.gbean.GBeanData;
37
38 /**
39 * @version $Rev: 430508 $ $Date: 2006-08-10 12:56:47 -0700 (Thu, 10 Aug 2006) $
40 */
41 public class BasicLifecycleMonitor implements LifecycleMonitor {
42 private static final Log log = LogFactory.getLog(BasicLifecycleMonitor.class);
43
44
45
46 /**
47 * Map of AbstractName to set of Listeners interested in this name.
48 */
49 private final Map boundListeners = new HashMap();
50
51 /**
52 * Map of listener to patterns they are interested in.
53 */
54 private final Map listenerPatterns = new HashMap();
55
56 public BasicLifecycleMonitor(Kernel kernel) {
57
58
59 Set names = kernel.listGBeans((AbstractNameQuery)null);
60 for (Iterator objectNameIterator = names.iterator(); objectNameIterator.hasNext();) {
61 AbstractName source = (AbstractName) objectNameIterator.next();
62 GBeanData gBeanData;
63 try {
64 gBeanData = kernel.getGBeanData(source);
65 } catch (GBeanNotFoundException e) {
66
67 throw new AssertionError(e);
68 }
69 addSource(source, gBeanData.getGBeanInfo().getInterfaces());
70 }
71 }
72
73 public synchronized void destroy() {
74 boundListeners.clear();
75 listenerPatterns.clear();
76 }
77
78 private synchronized void addSource(AbstractName source, Set interfaceTypes) {
79 if (boundListeners.containsKey(source)) {
80
81 return;
82 }
83
84
85 SourceInfo sourceInfo = new SourceInfo(interfaceTypes);
86 HashSet listeners = sourceInfo.getListeners();
87 for (Iterator listenerIterator = listenerPatterns.entrySet().iterator(); listenerIterator.hasNext();) {
88 Map.Entry entry = (Map.Entry) listenerIterator.next();
89 Set patterns = (Set) entry.getValue();
90 for (Iterator patternIterator = patterns.iterator(); patternIterator.hasNext();) {
91 AbstractNameQuery pattern = (AbstractNameQuery) patternIterator.next();
92 if (pattern.matches(source, interfaceTypes)) {
93 LifecycleListener listener = (LifecycleListener) entry.getKey();
94 listeners.add(listener);
95 }
96 }
97 }
98
99 boundListeners.put(source, sourceInfo);
100 }
101
102 private synchronized void removeSource(AbstractName source) {
103 boundListeners.remove(source);
104 }
105
106 public synchronized void addLifecycleListener(LifecycleListener listener, AbstractNameQuery pattern) {
107 addLifecycleListener(listener, Collections.singleton(pattern));
108 }
109
110 public synchronized void addLifecycleListener(LifecycleListener listener, Set patterns) {
111 for (Iterator patternIterator = patterns.iterator(); patternIterator.hasNext();) {
112 AbstractNameQuery pattern = (AbstractNameQuery) patternIterator.next();
113 for (Iterator iterator = boundListeners.entrySet().iterator(); iterator.hasNext();) {
114 Map.Entry entry = (Map.Entry) iterator.next();
115 AbstractName source = (AbstractName) entry.getKey();
116 SourceInfo sourceInfo = (SourceInfo) entry.getValue();
117 if (pattern.matches(source, sourceInfo.getInterfaceTypes())) {
118 Set listeners = sourceInfo.getListeners();
119 listeners.add(listener);
120 }
121 }
122 }
123 listenerPatterns.put(listener, patterns);
124 }
125
126 public synchronized void removeLifecycleListener(LifecycleListener listener) {
127 for (Iterator iterator = boundListeners.values().iterator(); iterator.hasNext();) {
128 SourceInfo sourceInfo = (SourceInfo) iterator.next();
129 sourceInfo.getListeners().remove(listener);
130 }
131 listenerPatterns.remove(listener);
132 }
133
134 private synchronized Set getTargets(AbstractName source) {
135 SourceInfo targets = (SourceInfo) boundListeners.get(source);
136 if (targets == null) {
137
138 return Collections.EMPTY_SET;
139 } else {
140 return new HashSet(targets.getListeners());
141 }
142 }
143
144 private void fireLoadedEvent(AbstractName refInfoName) {
145 Set targets = getTargets(refInfoName);
146 for (Iterator iterator = targets.iterator(); iterator.hasNext();) {
147 LifecycleListener listener = (LifecycleListener) iterator.next();
148 try {
149 listener.loaded(refInfoName);
150 } catch (Throwable e) {
151 log.warn("Exception occured while notifying listener", e);
152 }
153 }
154 }
155
156 private void fireStartingEvent(AbstractName source) {
157 Set targets = getTargets(source);
158 for (Iterator iterator = targets.iterator(); iterator.hasNext();) {
159 LifecycleListener listener = (LifecycleListener) iterator.next();
160 try {
161 listener.starting(source);
162 } catch (Throwable e) {
163 log.warn("Exception occured while notifying listener", e);
164 }
165 }
166 }
167
168 private void fireRunningEvent(AbstractName source) {
169 Set targets = getTargets(source);
170 for (Iterator iterator = targets.iterator(); iterator.hasNext();) {
171 LifecycleListener listener = (LifecycleListener) iterator.next();
172 try {
173 listener.running(source);
174 } catch (Throwable e) {
175 log.warn("Exception occured while notifying listener", e);
176 }
177 }
178 }
179
180 private void fireStoppingEvent(AbstractName source) {
181 Set targets = getTargets(source);
182 for (Iterator iterator = targets.iterator(); iterator.hasNext();) {
183 LifecycleListener listener = (LifecycleListener) iterator.next();
184 try {
185 listener.stopping(source);
186 } catch (Throwable e) {
187 log.warn("Exception occured while notifying listener", e);
188 }
189 }
190 }
191
192 private void fireStoppedEvent(AbstractName source) {
193 Set targets = getTargets(source);
194 for (Iterator iterator = targets.iterator(); iterator.hasNext();) {
195 LifecycleListener listener = (LifecycleListener) iterator.next();
196 try {
197 listener.stopped(source);
198 } catch (Throwable e) {
199 log.warn("Exception occured while notifying listener", e);
200 }
201 }
202 }
203
204 private void fireFailedEvent(AbstractName source) {
205 Set targets = getTargets(source);
206 for (Iterator iterator = targets.iterator(); iterator.hasNext();) {
207 LifecycleListener listener = (LifecycleListener) iterator.next();
208 try {
209 listener.failed(source);
210 } catch (Throwable e) {
211 log.warn("Exception occured while notifying listener", e);
212 }
213 }
214 }
215
216 private void fireUnloadedEvent(AbstractName source) {
217 Set targets = getTargets(source);
218 for (Iterator iterator = targets.iterator(); iterator.hasNext();) {
219 LifecycleListener listener = (LifecycleListener) iterator.next();
220 try {
221 listener.unloaded(source);
222 } catch (Throwable e) {
223 log.warn("Exception occured while notifying listener", e);
224 }
225 }
226 }
227
228 public LifecycleBroadcaster createLifecycleBroadcaster(AbstractName abstractName, Set interfaceTypes) {
229 return new RawLifecycleBroadcaster(abstractName, interfaceTypes);
230 }
231
232 private class RawLifecycleBroadcaster implements LifecycleBroadcaster {
233 private final AbstractName abstractName;
234 private final Set interfaceTypes;
235
236 public RawLifecycleBroadcaster(AbstractName abstractName, Set interfaceTypes) {
237 this.abstractName = abstractName;
238 this.interfaceTypes = interfaceTypes;
239 }
240
241 public void fireLoadedEvent() {
242 addSource(abstractName, interfaceTypes);
243 BasicLifecycleMonitor.this.fireLoadedEvent(abstractName);
244 }
245
246 public void fireStartingEvent() {
247 BasicLifecycleMonitor.this.fireStartingEvent(abstractName);
248 }
249
250 public void fireRunningEvent() {
251 BasicLifecycleMonitor.this.fireRunningEvent(abstractName);
252 }
253
254 public void fireStoppingEvent() {
255 BasicLifecycleMonitor.this.fireStoppingEvent(abstractName);
256 }
257
258 public void fireStoppedEvent() {
259 BasicLifecycleMonitor.this.fireStoppedEvent(abstractName);
260 }
261
262 public void fireFailedEvent() {
263 BasicLifecycleMonitor.this.fireFailedEvent(abstractName);
264 }
265
266 public void fireUnloadedEvent() {
267 BasicLifecycleMonitor.this.fireUnloadedEvent(abstractName);
268 removeSource(abstractName);
269 }
270 }
271
272 private final class SourceInfo {
273 private final Set interfaceTypes;
274 private final HashSet listeners = new HashSet();
275
276 public SourceInfo(Set interfaceTypes) {
277 this.interfaceTypes = interfaceTypes;
278 }
279
280 public Set getInterfaceTypes() {
281 return interfaceTypes;
282 }
283
284 public HashSet getListeners() {
285 return listeners;
286 }
287 }
288
289 }