Docjar: A Java Source and Docuemnt Enginecom.*    java.*    javax.*    org.*    all    new    plug-in

Quick Search    Search Deep

Source code: recoin/container/RetrievalContainer.java


1   
2   package recoin.container;
3   
4   import java.util.Enumeration;
5   import java.util.Vector;
6   
7   import org.apache.log4j.Logger;
8   
9   import recoin.exception.ComponentException;
10  import recoin.exception.ComponentRunnableException;
11  import recoin.group.ComponentRunnable;
12  import recoin.group.ComponentSupport;
13  import recoin.group.ComponentSupportImpl;
14  import recoin.system.session.ComponentChain;
15  import recoin.util.TimeLog;
16  
17  /**
18   * A RetrievalContainer is a very simple container object that can be used in a RetrievalCycle
19   * to store data that is used during retrieval. This data could be anything from
20   * input to the retrieval process like a query, output that has been created, result lists for example,
21   * or any other data that aids in the retrieval process.
22   * <br><br>
23   * The RetrievalContainer is passed along different ModuleGroup objects and it lets the Component
24   * objects of a particular group access, process and store information inside the container.
25   * A RetrievalContainer object can switch between two different states to signal if there
26   * still are threads operating on its data. The RetrievalContainer class provides functions to
27   * block and wake up threads when this state changes.<br>
28   * This is important, because the RetrievalCycle waits for this signal in the wait set
29   * of this RetrievalContainer while it is being processed by a certain ModuleGroup.
30   * <br><br>
31   * It extends the simple class ComponentSupportImpl in order for a RetrievalContainer
32   * object to be passed to Component objects. 
33   * @author Jan H. Scheufen
34   * @version 0.2.9
35   */
36  public class RetrievalContainer extends ComponentSupportImpl
37  {
38    /**
39     * The logger for this class
40     */
41    static Logger logger;
42    /**
43     * The flag to signal the end of processing this RetrievalContainer. Inital value is 'true'.
44     */
45    private boolean finished = true;
46    /**
47     * A ComponentChain object that can be used to distribute the container to a
48     * predefined number Component objects.
49     */  
50    private ComponentChain componentChain = null;
51    /**
52     * The ThreadGroup to group the threads working on this RetrievalContainer.
53     */
54    protected ThreadGroup threadGroup;
55    /**
56     * The ComponentRunnable objects that process this RetrievalContainer.
57     */
58    protected Vector runnables;
59    /**
60     * The ComponentSupport objects used in the retrieval process.
61     */
62    protected Vector componentSupport;
63    /**
64     * A special Vector that stores exceptions there was a problem inside a Component
65     * that processed this RetrievalContainer. 
66     */
67    protected Vector exceptions;
68    /**
69     * The timelog to protocol the time needed for the RetrievalCycle and by individual components.
70     */
71    public TimeLog timeLog;
72    
73    /**
74     * Creates a new RetrievalContainer.<br>
75     * The TimeLog of the RetrievalContainer is initiated with a new DurationStamp. 
76     */
77    public RetrievalContainer() 
78    {
79      logger = Logger.getLogger( RetrievalContainer.class.getName() );
80      runnables = new Vector();
81      componentSupport = new Vector();
82      exceptions = new Vector();
83      threadGroup = new ThreadGroup("");
84      timeLog = new TimeLog(true);
85    }
86      
87    /**
88     * Sets the field <code>finished</code> to the specified value. If 'true' it
89     * wakes up a single thread waiting in the wait set of this RetrievalContainer.
90     * Normaly this should only be a RetrievalCycle object, because the
91     * method cannot garantue to wake up a specific thread waiting for a notify()
92     * from this RetrievalContainer.
93     * @param fin the state of this RetrievalContainer
94     */
95    public void setFinished(boolean fin) 
96    {
97      finished = fin;
98      if( finished )
99      {
100       logger.debug("Notifying waiting RetrievalCycle.");
101       notify();
102     }    
103   }
104   
105   /**
106    * Adds the calling thread to the wait set of this RetrievalContainer object. The method
107    * uses a guarded wait by re-checking the value of the finished field to avoid spurious
108    * or accidental wake ups.
109    * @throws InterruptedException
110    */
111   public synchronized void waitForFinished() throws InterruptedException 
112   {
113     while( !finished )
114     {
115       wait();
116     }    
117   }
118   
119   /**
120    * Returns the TimeLog of the RetrievalContainer.
121    * @return the TimeLog
122    */
123   public TimeLog getTimeLog()
124   {
125     return timeLog;
126   }
127   
128   /**
129    * Starts all ComponentRunnables currently contained in this RetrievalContainer.
130    */
131   public void startRunnables()
132   {
133     if( runnables.size() > 0 )
134     {
135       threadGroup = new ThreadGroup("RunnableGroup");
136       logger.debug("Starting "+runnables.size()+" ComponentRunnables.");
137       for( Enumeration enum = runnables.elements(); enum.hasMoreElements(); )
138       {
139         ComponentRunnable runnable = null;
140         try
141         {
142           runnable = (ComponentRunnable) enum.nextElement();
143         }
144         catch (ClassCastException e)
145         {
146           logger.error("ClassCastException while starting ComponentRunnable.");
147         }
148         logger.debug("Starting ComponentRunnable "+runnable.getClass().getName());
149         Thread t = new Thread( threadGroup, runnable );
150         t.setName( runnable.getThreadName() );
151         runnable.setUp();
152         t.start();
153       }
154     }
155     else
156     {
157       logger.debug("No ComponentRunnables found! Proceeding ...");
158       checkFinished();
159     }
160   }
161   
162   /**
163    * Adds the specified ComponentRunnable to this RetrievalContainer.
164    * @param runnable the ComponentRunnable
165    */
166   public void addRunnable( ComponentRunnable runnable )
167   {
168     logger.debug("Adding Runnable to container.");
169     this.runnables.add( runnable );
170   }
171   
172   /**
173    * Adds the ComponentRunnable objects inside the specified Vector to this RetrievalContainer.
174    * @param runnableVector a Vector containing ComponentRunnable objects
175    */
176   public void addRunnables(Vector runnableVector)
177   {
178     logger.debug("Adding Runnables to container.");
179     for( Enumeration enum = runnableVector.elements(); enum.hasMoreElements(); )
180     {
181       this.runnables.add( ((ComponentRunnable) enum.nextElement()) );
182     }
183   }
184 
185   /**
186    * Adds the specified ComponentSupport to this RetrievalContainer.
187    * @param support the ComponentSupport to add
188    */
189   public synchronized void addComponentSupport( ComponentSupport support )
190   {
191     this.componentSupport.add( support );
192   }
193 
194   /**
195    * Adds the specified Vector of ComponentSupport objects to this RetrievalContainer.
196    * @param support the ComponentSupport objects
197    */
198   public synchronized void addComponentSupports( Vector supports )
199   {
200     this.componentSupport.add( supports );
201   }
202 
203   /**
204    * Adds the specified ComponentException to this RetrievalContainer.
205    * @param e the ComponentException
206    */
207   public synchronized void addException( ComponentException e )
208   {
209     this.exceptions.add( e );
210   }
211 
212   /**
213    * Adds the specified ComponentRunnableException to this RetrievalContainer.
214    * @param e the ComponentRunnableException
215    */
216   public synchronized void addException( ComponentRunnableException e )
217   {
218     this.exceptions.add( e );
219   }
220 
221   /**
222    * Returns the ComponentChain of this RetrievalContainer.
223    * @return the ComponentChain
224    */
225   public ComponentChain getComponentChain()
226   {
227     return componentChain;
228   }
229 
230   /**
231    * Sets the ComponentChain of this RetrievalContainer.
232    * @param chain the ComponentChain
233    */
234   public void setComponentChain( ComponentChain chain )
235   {
236     this.componentChain = chain;
237   }
238 
239   /**
240    * Returns all ComponentSupport objects currently contained in this RetrievalContainer.
241    * @return a Vector of ComponentSupport objects.
242    */
243   public Vector getComponentSupport()
244   {
245     return componentSupport;
246   }
247   
248   /**
249    * Returns all ComponentSupport objects in this RetrievalContainer that are instances
250    * of the ResultList class.
251    * @return a Vector of ResultList objects
252    */
253   public Vector getResultLists()
254   {
255     Vector r = new Vector();
256     for( Enumeration enum = componentSupport.elements(); enum.hasMoreElements(); )
257     {
258       ComponentSupport cs = (ComponentSupport) enum.nextElement();
259       if( cs instanceof ResultList )
260         r.add( cs );
261     }
262     return r;
263   }
264 
265   /**
266    * Returns the exceptions that are currently contained in this RetrievalContainer.
267    * @return Vector
268    */
269   public Vector getExceptions()
270   {
271     return exceptions;
272   }
273   
274   /**
275    * Returns the ComponentSupport that has the specified chain ID. NULL if the specified
276    * ComponentSupport could not be found.
277    * @param chainID the chain ID of the desired ComponentSupport
278    * @return the ComponentSupport or NULL if it could not be found
279    */
280   public ComponentSupport getComponentSupport( String chainID )
281   {
282     for( Enumeration enum = componentSupport.elements(); enum.hasMoreElements(); )
283     {
284       ComponentSupport support = (ComponentSupport) enum.nextElement();
285       if( support.getChainID().equals(chainID) )
286         return support;
287     }
288     return null;
289   }
290   
291   /**
292    * This method checks if there are any more active threads working on this RetrievalContainer.
293    * If there are none or they have all finished processing, setFinished(true) is called
294    * and the Vector runnables is emptied to dispose of the no longer needed ComponentRunnable
295    * objects.
296    */
297   public synchronized void checkFinished()
298   {
299     logger.debug("CheckFinish() called on RetrievalContainer. Active Threads: "+threadGroup.activeCount());
300     if( threadGroup.activeCount() <= 1 ) // calling Thread may still be active!
301     {
302       runnables = new Vector();
303       setFinished(true);
304     }
305   }
306 
307 }