1
2
3
4
5
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
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 }