View Javadoc

1   /*
2    * Copyright (c) 2004-2005, University Health Network.  All rights reserved. Distributed under the BSD 
3    * license (see http://opensource.org/licenses/bsd-license.php).
4    *  
5    * Created on 5-Jan-2005
6    */
7   package ca.uhn.cache.internal.impl;
8   
9   import java.util.Date;
10  import java.util.NoSuchElementException;
11  
12  import org.apache.commons.logging.Log;
13  import org.apache.commons.logging.LogFactory;
14  
15  import EDU.oswego.cs.dl.util.concurrent.LinkedQueue;
16  
17  import ca.uhn.cache.CacheReasonEnum;
18  import ca.uhn.cache.VolatilityEnum;
19  import ca.uhn.cache.impl.Chunk;
20  import ca.uhn.cache.impl.Query;
21  import ca.uhn.cache.internal.IChunk;
22  import ca.uhn.cache.internal.IChunkIterator;
23  
24  /***
25   * Default implementation of IChunkIterator.  The default 
26   * close() method does nothing, and should be overridden to perform any 
27   * required cleanup.  
28   * 
29   * Note that this class is NOT thread-safe in the sense of supporting multiple 
30   * iterating clients (although different threads may add and iterate concurrently).   
31   * 
32   * @author <a href="mailto:bryan.tripp@uhn.on.ca">Bryan Tripp</a>
33   * @version $Revision: 1.2 $ updated on $Date: 2005/01/25 23:59:09 $ by $Author: bryan_tripp $
34   */
35  public class ChunkIterator implements IChunkIterator {
36      
37      private static final Log ourLog = LogFactory.getLog(ChunkIterator.class);
38  
39      private LinkedQueue myQueue;
40      private IChunk myNextChunk;
41      
42      /***
43       * New instance. 
44       */
45      public ChunkIterator() {
46          myQueue = new LinkedQueue();
47      }
48      
49      /***
50       * @param theChunk a chunk to be added to the iteration list. 
51       */
52      public void add(IChunk theChunk) {
53          try {
54              myQueue.put(theChunk);
55          } catch (InterruptedException e) {
56              ourLog.error("Failed to add IChunk to iterator", e);
57          }
58      }
59  
60      /***
61       * Must be called when all items have been added.  
62       */
63      public void finished() {
64          try {
65              myQueue.put(new EndMarker());
66          } catch (InterruptedException e) {
67              ourLog.error("Failed to add end marker to iterator", e);
68          }
69      }
70      
71      /*** 
72       * @see ca.uhn.cache.internal.IChunkIterator#hasNext()
73       */
74      public boolean hasNext() {
75          while (myNextChunk == null) {
76              try {
77                  myNextChunk = (IChunk) myQueue.poll(1);
78              } catch (InterruptedException e) {
79                  //we'll just try again
80              }
81          }
82          
83          boolean done = (myNextChunk instanceof EndMarker);
84          if (done) {
85              close();
86          }
87          
88          return !done;
89      }
90  
91      /*** 
92       * @see ca.uhn.cache.internal.IChunkIterator#next()
93       */
94      public IChunk next() throws NoSuchElementException {
95          if (!hasNext()) {
96              throw new NoSuchElementException("No further IChunks are available");
97          } 
98          
99          IChunk next = myNextChunk;
100         myNextChunk = null;            
101         
102         return next;
103     }
104 
105     /*** 
106      * Does nothing by default (override if you want to do something here). 
107      * 
108      * @see ca.uhn.cache.internal.IChunkIterator#close()
109      */
110     public void close() {
111     }
112     
113     /***
114      * Marker added to queue on finish().  Could set a finished flag, but this might be 
115      * out of order due to threading.  
116      *  
117      * @author <a href="mailto:bryan.tripp@uhn.on.ca">Bryan Tripp</a>
118      * @version $Revision: 1.2 $ updated on $Date: 2005/01/25 23:59:09 $ by $Author: bryan_tripp $
119      */
120     private static class EndMarker extends Chunk  {
121 
122         /***
123          */
124         public EndMarker() {            
125             super("END QUEUE MARKER", VolatilityEnum.STABLE, new Date(), new Date(), new Date(), 
126                     new CacheReasonEnum[0], new Query());
127         }
128         
129     }
130 
131 }