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.store.DeserializationPostInitialisable;
15 import org.mule.util.xa.AbstractXAResourceManager;
16 import org.mule.util.xa.DefaultXASession;
17
18 import java.io.Serializable;
19
20 import org.apache.commons.logging.Log;
21 import org.apache.commons.logging.LogFactory;
22
23
24
25
26 class TransactionalQueueSession extends DefaultXASession implements QueueSession
27 {
28 private Log logger = LogFactory.getLog(TransactionalQueueSession.class);
29
30 protected TransactionalQueueManager queueManager;
31
32 public TransactionalQueueSession(AbstractXAResourceManager resourceManager,
33 TransactionalQueueManager queueManager)
34 {
35 super(resourceManager);
36 this.queueManager = queueManager;
37 }
38
39 @Override
40 public Queue getQueue(String name)
41 {
42 QueueInfo queue = queueManager.getQueue(name);
43 return new QueueImpl(queue);
44 }
45
46 protected class QueueImpl implements Queue
47 {
48 protected QueueInfo queue;
49
50 public QueueImpl(QueueInfo queue)
51 {
52 this.queue = queue;
53 }
54
55 @Override
56 public void put(Serializable item) throws InterruptedException, ObjectStoreException
57 {
58 offer(item, Long.MAX_VALUE);
59 }
60
61 @Override
62 public boolean offer(Serializable item, long timeout) throws InterruptedException, ObjectStoreException
63 {
64 if (localContext != null)
65 {
66 return ((QueueTransactionContext) localContext).offer(queue, item, timeout);
67 }
68 else
69 {
70 try
71 {
72 Serializable id = queueManager.doStore(queue, item);
73 try
74 {
75 if (!queue.offer(id, 0, timeout))
76 {
77 queueManager.doRemove(queue, id);
78 return false;
79 }
80 else
81 {
82 return true;
83 }
84 }
85 catch (InterruptedException e)
86 {
87 queueManager.doRemove(queue, id);
88 throw e;
89 }
90 }
91 catch (ObjectStoreException e)
92 {
93 throw new RuntimeException(e);
94 }
95 }
96 }
97
98 @Override
99 public Serializable take() throws InterruptedException
100 {
101 return poll(Long.MAX_VALUE);
102 }
103
104 @Override
105 public void untake(Serializable item) throws InterruptedException, ObjectStoreException
106 {
107 if (localContext != null)
108 {
109 ((QueueTransactionContext) localContext).untake(queue, item);
110 }
111 else
112 {
113 Serializable id = queueManager.doStore(queue, item);
114 queue.untake(id);
115 }
116 }
117
118 @Override
119 public Serializable poll(long timeout) throws InterruptedException
120 {
121 try
122 {
123 if (localContext != null)
124 {
125 Serializable item = ((QueueTransactionContext) localContext).poll(queue, timeout);
126 return postProcessIfNeeded(item);
127 }
128 else if (queue.canTakeFromStore())
129 {
130 Serializable item = queue.takeNextItemFromStore(timeout);
131 return postProcessIfNeeded(item);
132 }
133 else
134 {
135 Serializable id = queue.poll(timeout);
136 if (id != null)
137 {
138 Serializable item = queueManager.doLoad(queue, id);
139 if (item != null)
140 {
141 queueManager.doRemove(queue, id);
142 }
143 return postProcessIfNeeded(item);
144 }
145 return null;
146 }
147 }
148 catch (InterruptedException iex)
149 {
150 if (queueManager.getMuleContext().isStopping())
151 {
152 throw iex;
153 }
154
155 return null;
156 }
157 catch (ObjectStoreException e)
158 {
159 throw new RuntimeException(e);
160 }
161 }
162
163 @Override
164 public Serializable peek() throws InterruptedException
165 {
166 try
167 {
168 if (localContext != null)
169 {
170 Serializable item = ((QueueTransactionContext) localContext).peek(queue);
171 return postProcessIfNeeded(item);
172 }
173 else
174 {
175 Serializable id = queue.peek();
176 if (id != null)
177 {
178 Serializable item = queueManager.doLoad(queue, id);
179 return postProcessIfNeeded(item);
180 }
181 return null;
182 }
183 }
184 catch (ObjectStoreException e)
185 {
186 throw new RuntimeException(e);
187 }
188 }
189
190 @Override
191 public int size()
192 {
193 if (localContext != null)
194 {
195 return ((QueueTransactionContext) localContext).size(queue);
196 }
197 else
198 {
199 return queue.getSize();
200 }
201 }
202
203 @Override
204 public String getName()
205 {
206 return queue.getName();
207 }
208
209
210
211
212 private Serializable postProcessIfNeeded(Serializable item)
213 {
214 try
215 {
216 if (item instanceof DeserializationPostInitialisable)
217 {
218 DeserializationPostInitialisable.Implementation.init(item, queueManager.getMuleContext());
219 }
220 return item;
221 }
222 catch (Exception e)
223 {
224 logger.warn("Unable to deserialize message", e);
225 return null;
226 }
227 }
228 }
229 }