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