1 package org.eclipse.jetty.util.component;
2
3
4
5
6
7
8
9
10
11
12
13
14
15 import java.io.IOException;
16 import java.util.ArrayList;
17 import java.util.Collection;
18 import java.util.Collections;
19 import java.util.Iterator;
20 import java.util.List;
21 import java.util.concurrent.CopyOnWriteArrayList;
22
23 import org.eclipse.jetty.util.log.Log;
24 import org.eclipse.jetty.util.log.Logger;
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40 public class AggregateLifeCycle extends AbstractLifeCycle implements Destroyable, Dumpable
41 {
42 private static final Logger LOG = Log.getLogger(AggregateLifeCycle.class);
43 private final List<Bean> _beans=new CopyOnWriteArrayList<Bean>();
44 private boolean _started=false;
45
46 private class Bean
47 {
48 Bean(Object b)
49 {
50 _bean=b;
51 }
52 final Object _bean;
53 volatile boolean _managed=true;
54
55 public String toString()
56 {
57 return "{"+_bean+","+_managed+"}";
58 }
59 }
60
61
62
63
64
65
66 @Override
67 protected void doStart() throws Exception
68 {
69 for (Bean b:_beans)
70 {
71 if (b._managed && b._bean instanceof LifeCycle)
72 {
73 LifeCycle l=(LifeCycle)b._bean;
74 if (!l.isRunning())
75 l.start();
76 }
77 }
78
79 _started=true;
80 super.doStart();
81 }
82
83
84
85
86
87
88 @Override
89 protected void doStop() throws Exception
90 {
91 _started=false;
92 super.doStop();
93 List<Bean> reverse = new ArrayList<Bean>(_beans);
94 Collections.reverse(reverse);
95 for (Bean b:reverse)
96 {
97 if (b._managed && b._bean instanceof LifeCycle)
98 {
99 LifeCycle l=(LifeCycle)b._bean;
100 if (l.isRunning())
101 l.stop();
102 }
103 }
104 }
105
106
107
108
109
110
111
112 public void destroy()
113 {
114 List<Bean> reverse = new ArrayList<Bean>(_beans);
115 Collections.reverse(reverse);
116 for (Bean b:reverse)
117 {
118 if (b._bean instanceof Destroyable && b._managed)
119 {
120 Destroyable d=(Destroyable)b._bean;
121 d.destroy();
122 }
123 }
124 _beans.clear();
125 }
126
127
128
129
130
131
132
133 public boolean contains(Object bean)
134 {
135 for (Bean b:_beans)
136 if (b._bean==bean)
137 return true;
138 return false;
139 }
140
141
142
143
144
145
146 public boolean isManaged(Object bean)
147 {
148 for (Bean b:_beans)
149 if (b._bean==bean)
150 return b._managed;
151 return false;
152 }
153
154
155
156
157
158
159
160
161
162
163
164 public boolean addBean(Object o)
165 {
166
167 return addBean(o,!((o instanceof LifeCycle)&&((LifeCycle)o).isStarted()));
168 }
169
170
171
172
173
174
175
176 public boolean addBean(Object o, boolean managed)
177 {
178 if (contains(o))
179 return false;
180
181 Bean b = new Bean(o);
182 b._managed=managed;
183 _beans.add(b);
184
185 if (o instanceof LifeCycle)
186 {
187 LifeCycle l=(LifeCycle)o;
188
189
190 if (managed && _started)
191 {
192 try
193 {
194 l.start();
195 }
196 catch(Exception e)
197 {
198 throw new RuntimeException (e);
199 }
200 }
201 }
202 return true;
203 }
204
205
206
207
208
209
210
211 public void manage(Object bean)
212 {
213 for (Bean b :_beans)
214 {
215 if (b._bean==bean)
216 {
217 b._managed=true;
218 return;
219 }
220 }
221 throw new IllegalArgumentException();
222 }
223
224
225
226
227
228
229
230 public void unmanage(Object bean)
231 {
232 for (Bean b :_beans)
233 {
234 if (b._bean==bean)
235 {
236 b._managed=false;
237 return;
238 }
239 }
240 throw new IllegalArgumentException();
241 }
242
243
244
245
246
247 public Collection<Object> getBeans()
248 {
249 return getBeans(Object.class);
250 }
251
252
253
254
255
256
257
258 public <T> List<T> getBeans(Class<T> clazz)
259 {
260 ArrayList<T> beans = new ArrayList<T>();
261 for (Bean b:_beans)
262 {
263 if (clazz.isInstance(b._bean))
264 beans.add((T)(b._bean));
265 }
266 return beans;
267 }
268
269
270
271
272
273
274
275
276
277 public <T> T getBean(Class<T> clazz)
278 {
279 for (Bean b:_beans)
280 {
281 if (clazz.isInstance(b._bean))
282 return (T)b._bean;
283 }
284
285 return null;
286 }
287
288
289
290
291
292 public void removeBeans ()
293 {
294 _beans.clear();
295 }
296
297
298
299
300
301 public boolean removeBean (Object o)
302 {
303 Iterator<Bean> i = _beans.iterator();
304 while(i.hasNext())
305 {
306 Bean b=i.next();
307 if (b._bean==o)
308 {
309 _beans.remove(b);
310 return true;
311 }
312 }
313 return false;
314 }
315
316
317 public void dumpStdErr()
318 {
319 try
320 {
321 dump(System.err,"");
322 }
323 catch (IOException e)
324 {
325 LOG.warn(e);
326 }
327 }
328
329
330 public String dump()
331 {
332 return dump(this);
333 }
334
335
336 public static String dump(Dumpable dumpable)
337 {
338 StringBuilder b = new StringBuilder();
339 try
340 {
341 dumpable.dump(b,"");
342 }
343 catch (IOException e)
344 {
345 LOG.warn(e);
346 }
347 return b.toString();
348 }
349
350
351 public void dump(Appendable out) throws IOException
352 {
353 dump(out,"");
354 }
355
356
357 protected void dumpThis(Appendable out) throws IOException
358 {
359 out.append(String.valueOf(this)).append(" - ").append(getState()).append("\n");
360 }
361
362
363 public static void dumpObject(Appendable out,Object o) throws IOException
364 {
365 try
366 {
367 if (o instanceof LifeCycle)
368 out.append(String.valueOf(o)).append(" - ").append((AbstractLifeCycle.getState((LifeCycle)o))).append("\n");
369 else
370 out.append(String.valueOf(o)).append("\n");
371 }
372 catch(Throwable th)
373 {
374 out.append(" => ").append(th.toString()).append('\n');
375 }
376 }
377
378
379 public void dump(Appendable out,String indent) throws IOException
380 {
381 dumpThis(out);
382 int size=_beans.size();
383 if (size==0)
384 return;
385 int i=0;
386 for (Bean b : _beans)
387 {
388 i++;
389
390 out.append(indent).append(" +- ");
391 if (b._managed)
392 {
393 if (b._bean instanceof Dumpable)
394 ((Dumpable)b._bean).dump(out,indent+(i==size?" ":" | "));
395 else
396 dumpObject(out,b._bean);
397 }
398 else
399 dumpObject(out,b._bean);
400 }
401
402 if (i!=size)
403 out.append(indent).append(" |\n");
404 }
405
406
407 public static void dump(Appendable out,String indent,Collection<?>... collections) throws IOException
408 {
409 if (collections.length==0)
410 return;
411 int size=0;
412 for (Collection<?> c : collections)
413 size+=c.size();
414 if (size==0)
415 return;
416
417 int i=0;
418 for (Collection<?> c : collections)
419 {
420 for (Object o : c)
421 {
422 i++;
423 out.append(indent).append(" +- ");
424
425 if (o instanceof Dumpable)
426 ((Dumpable)o).dump(out,indent+(i==size?" ":" | "));
427 else
428 dumpObject(out,o);
429 }
430
431 if (i!=size)
432 out.append(indent).append(" |\n");
433 }
434 }
435 }