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