1
2
3
4
5
6
7
8
9
10
11 package org.mule.util.queue;
12
13 import org.mule.api.store.ObjectStoreException;
14 import org.mule.util.xa.AbstractTransactionContext;
15 import org.mule.util.xa.ResourceManagerException;
16
17 import java.io.Serializable;
18 import java.util.ArrayList;
19 import java.util.HashMap;
20 import java.util.List;
21 import java.util.Map;
22
23 public class QueueTransactionContext extends AbstractTransactionContext
24 {
25 private final TransactionalQueueManager transactionalQueueManager;
26 private Map<QueueInfo, List<Serializable>> added;
27 private Map<QueueInfo, List<Serializable>> removed;
28
29 public QueueTransactionContext(TransactionalQueueManager transactionalQueueManager)
30 {
31 super();
32 this.transactionalQueueManager = transactionalQueueManager;
33 }
34
35 public boolean offer(QueueInfo queue, Serializable item, long offerTimeout) throws InterruptedException, ObjectStoreException
36 {
37 readOnly = false;
38 if (queue.canTakeFromStore())
39 {
40 queue.writeToObjectStore(item);
41 return true;
42 }
43
44 initializeAdded();
45
46 List<Serializable> queueAdded = lookupQueue(queue);
47
48 if (queue.offer(null, queueAdded.size(), offerTimeout))
49 {
50 queueAdded.add(item);
51 return true;
52 }
53 else
54 {
55 return false;
56 }
57 }
58
59 public void untake(QueueInfo queue, Serializable item) throws InterruptedException, ObjectStoreException
60 {
61 readOnly = false;
62 if (queue.canTakeFromStore())
63 {
64 queue.writeToObjectStore(item);
65 }
66
67 initializeAdded();
68
69 List<Serializable> queueAdded = lookupQueue(queue);
70 queueAdded.add(item);
71 }
72
73 public Serializable poll(QueueInfo queue, long pollTimeout) throws InterruptedException, ObjectStoreException
74 {
75 readOnly = false;
76 if (added != null)
77 {
78 List<Serializable> queueAdded = added.get(queue);
79 if (queueAdded != null && queueAdded.size() > 0)
80 {
81 return queueAdded.remove(queueAdded.size() - 1);
82 }
83 }
84
85 if (queue.canTakeFromStore())
86 {
87
88 return queue.takeNextItemFromStore(timeout);
89 }
90
91 Serializable key;
92 Serializable value = null;
93 try
94 {
95 key = queue.poll(pollTimeout);
96 }
97 catch (InterruptedException e)
98 {
99 if (!transactionalQueueManager.getMuleContext().isStopping())
100 {
101 throw e;
102 }
103
104 return null;
105 }
106
107 if (key != null)
108 {
109 if (removed == null)
110 {
111 removed = new HashMap<QueueInfo, List<Serializable>>();
112 }
113 List<Serializable> queueRemoved = removed.get(queue);
114 if (queueRemoved == null)
115 {
116 queueRemoved = new ArrayList<Serializable>();
117 removed.put(queue, queueRemoved);
118 }
119 value = transactionalQueueManager.doLoad(queue, key);
120 if (value != null)
121 {
122 queueRemoved.add(key);
123 }
124 }
125 return value;
126 }
127
128 public Serializable peek(QueueInfo queue) throws InterruptedException, ObjectStoreException
129 {
130 readOnly = false;
131 if (added != null)
132 {
133 List<Serializable> queueAdded = added.get(queue);
134 if (queueAdded != null)
135 {
136 return queueAdded.get(queueAdded.size() - 1);
137 }
138 }
139
140 Serializable o = queue.peek();
141 if (o != null)
142 {
143 o = transactionalQueueManager.doLoad(queue, o);
144 }
145 return o;
146 }
147
148 public int size(QueueInfo queue)
149 {
150 int sz = queue.getSize();
151 if (added != null)
152 {
153 List<Serializable> queueAdded = added.get(queue);
154 if (queueAdded != null)
155 {
156 sz += queueAdded.size();
157 }
158 }
159 return sz;
160 }
161
162 @Override
163 public void doCommit() throws ResourceManagerException
164 {
165 try
166 {
167 if (added != null)
168 {
169 for (Map.Entry<QueueInfo, List<Serializable>> entry : added.entrySet())
170 {
171 QueueInfo queue = entry.getKey();
172 List<Serializable> queueAdded = entry.getValue();
173 if (queueAdded != null && queueAdded.size() > 0)
174 {
175 for (Serializable object : queueAdded)
176 {
177 Serializable id = transactionalQueueManager.doStore(queue, object);
178 queue.putNow(id);
179 }
180 }
181 }
182 }
183 if (removed != null)
184 {
185 for (Map.Entry<QueueInfo, List<Serializable>> entry : removed.entrySet())
186 {
187 QueueInfo queue = entry.getKey();
188 List<Serializable> queueRemoved = entry.getValue();
189 if (queueRemoved != null && queueRemoved.size() > 0)
190 {
191 for (Serializable id : queueRemoved)
192 {
193 transactionalQueueManager.doRemove(queue, id);
194 }
195 }
196 }
197 }
198 }
199 catch (Exception e)
200 {
201 throw new ResourceManagerException(e);
202 }
203 finally
204 {
205 added = null;
206 removed = null;
207 }
208
209 }
210
211 @Override
212 public void doRollback() throws ResourceManagerException
213 {
214 if (removed != null)
215 {
216 for (Map.Entry<QueueInfo, List<Serializable>> entry : removed.entrySet())
217 {
218 QueueInfo queue = entry.getKey();
219 List<Serializable> queueRemoved = entry.getValue();
220 if (queueRemoved != null && queueRemoved.size() > 0)
221 {
222 for (Serializable id : queueRemoved)
223 {
224 queue.putNow(id);
225 }
226 }
227 }
228 }
229 added = null;
230 removed = null;
231 }
232
233 protected void initializeAdded()
234 {
235 if (added == null)
236 {
237 added = new HashMap<QueueInfo, List<Serializable>>();
238 }
239 }
240
241 protected List<Serializable> lookupQueue(QueueInfo queue)
242 {
243 List<Serializable> queueAdded = added.get(queue);
244 if (queueAdded == null)
245 {
246 queueAdded = new ArrayList<Serializable>();
247 added.put(queue, queueAdded);
248 }
249 return queueAdded;
250 }
251 }