View Javadoc

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.Iterator;
7   import java.util.List;
8   import java.util.Queue;
9   import java.util.concurrent.ConcurrentLinkedQueue;
10  
11  
12  import org.eclipse.jetty.util.log.Log;
13  
14  /**
15   * An AggregateLifeCycle is an AbstractLifeCycle with a collection of dependent beans.
16   * <p>
17   * Dependent beans are started and stopped with the {@link LifeCycle} and if they are destroyed if they are also {@link Destroyable}.
18   *
19   */
20  public class AggregateLifeCycle extends AbstractLifeCycle implements Destroyable, Dumpable
21  {
22      private final Queue<Object> _dependentBeans=new ConcurrentLinkedQueue<Object>();
23  
24      public void destroy()
25      {
26          for (Object o : _dependentBeans)
27          {
28              if (o instanceof Destroyable)
29              {
30                  ((Destroyable)o).destroy();
31              }
32          }
33          _dependentBeans.clear();
34      }
35  
36      @Override
37      protected void doStart() throws Exception
38      {
39          for (Object o:_dependentBeans)
40          {
41              if (o instanceof LifeCycle)
42                  ((LifeCycle)o).start();
43          }
44          super.doStart();
45      }
46  
47      @Override
48      protected void doStop() throws Exception
49      {
50          super.doStop();
51          for (Object o:_dependentBeans)
52          {
53              if (o instanceof LifeCycle)
54                  ((LifeCycle)o).stop();
55          }
56      }
57  
58  
59      /* ------------------------------------------------------------ */
60      /**
61       * Add an associated bean.
62       * The bean will be added to this LifeCycle and if it is also a 
63       * {@link LifeCycle} instance, it will be 
64       * started/stopped. Any beans that are also 
65       * {@link Destroyable}, will be destroyed with the server.
66       * @param o the bean object to add
67       */
68      public boolean addBean(Object o)
69      {
70          if (o == null)
71              return false;
72          boolean added=false;
73          if (!_dependentBeans.contains(o)) 
74          {
75              _dependentBeans.add(o);
76              added=true;
77          }
78          
79          try
80          {
81              if (isStarted() && o instanceof LifeCycle)
82                  ((LifeCycle)o).start();
83          }
84          catch (Exception e)
85          {
86              throw new RuntimeException (e);
87          }
88          return added;
89      }
90  
91      /* ------------------------------------------------------------ */
92      /** Get dependent beans 
93       * @return List of beans.
94       */
95      public Collection<Object> getBeans()
96      {
97          return _dependentBeans;
98      }
99      
100     /* ------------------------------------------------------------ */
101     /** Get dependent beans of a specific class
102      * @see #addBean(Object)
103      * @param clazz
104      * @return List of beans.
105      */
106     public <T> List<T> getBeans(Class<T> clazz)
107     {
108         ArrayList<T> beans = new ArrayList<T>();
109         Iterator<?> iter = _dependentBeans.iterator();
110         while (iter.hasNext())
111         {
112             Object o = iter.next();
113             if (clazz.isInstance(o))
114                 beans.add((T)o);
115         }
116         return beans;
117     }
118 
119     
120     /* ------------------------------------------------------------ */
121     /** Get dependent bean of a specific class.
122      * If more than one bean of the type exist, the first is returned.
123      * @see #addBean(Object)
124      * @param clazz
125      * @return bean or null
126      */
127     public <T> T getBean(Class<T> clazz)
128     {
129         Iterator<?> iter = _dependentBeans.iterator();
130         T t=null;
131         int count=0;
132         while (iter.hasNext())
133         {
134             Object o = iter.next();
135             if (clazz.isInstance(o))
136             {
137                 count++;
138                 if (t==null)
139                     t=(T)o;
140             }
141         }
142         if (count>1)
143             Log.debug("getBean({}) 1 of {}",clazz.getName(),count);
144         
145         return t;
146     }
147     
148     /* ------------------------------------------------------------ */
149     /**
150      * Remove all associated bean.
151      */
152     public void removeBeans ()
153     {
154         _dependentBeans.clear();
155     }
156 
157     /* ------------------------------------------------------------ */
158     /**
159      * Remove an associated bean.
160      */
161     public boolean removeBean (Object o)
162     {
163         if (o == null)
164             return false;
165         return _dependentBeans.remove(o);
166     }
167 
168     /* ------------------------------------------------------------ */
169     public void dumpStdErr()
170     {
171         try
172         {
173             dump(System.err,"");
174         }
175         catch (IOException e)
176         {
177             Log.warn(e);
178         }
179     }
180     
181     /* ------------------------------------------------------------ */
182     public String dump()
183     {
184         return dump(this);
185     }    
186     
187     /* ------------------------------------------------------------ */
188     public static String dump(Dumpable dumpable)
189     {
190         StringBuilder b = new StringBuilder();
191         try
192         {
193             dumpable.dump(b,"");
194         }
195         catch (IOException e)
196         {
197             Log.warn(e);
198         }
199         return b.toString();
200     }    
201 
202     /* ------------------------------------------------------------ */
203     public void dump(Appendable out) throws IOException
204     {
205         dump(out,"");
206     }
207 
208     /* ------------------------------------------------------------ */
209     protected void dumpThis(Appendable out) throws IOException
210     {
211         out.append(String.valueOf(this)).append("\n");
212     }
213     
214     /* ------------------------------------------------------------ */
215     public void dump(Appendable out,String indent) throws IOException
216     {
217         dumpThis(out);
218         dump(out,indent,_dependentBeans);
219     }
220     
221     /* ------------------------------------------------------------ */
222     public static void dump(Appendable out,String indent,Collection<?>... collections) throws IOException
223     {
224         if (collections.length==0)
225             return;
226         int size=0;
227         for (Collection<?> c : collections)
228             size+=c.size();    
229         if (size==0)
230             return;
231 
232         int i=0;
233         for (Collection<?> c : collections)
234         {
235             for (Object o : c)
236             {
237                 i++;
238                 out.append(indent).append(" +- ");
239 
240                 if (o instanceof Dumpable)
241                     ((Dumpable)o).dump(out,indent+(i==size?"    ":" |  "));
242                 else
243                     out.append(String.valueOf(o)).append("\n");
244             }
245             
246             if (i!=size)
247                 out.append(indent).append(" |\n");
248                 
249         }
250     }
251     
252     
253     
254 }