View Javadoc

1   /*
2    * $Id: TransactionalQueueSession.java 22855 2011-09-04 17:45:44Z mike.schilling $
3    * --------------------------------------------------------------------------------------
4    * Copyright (c) MuleSoft, Inc.  All rights reserved.  http://www.mulesoft.com
5    *
6    * The software in this package is published under the terms of the CPAL v1.0
7    * license, a copy of which has been included with this distribution in the
8    * LICENSE.txt file.
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   * A Queue session that is used to manage the transaction context of a Queue
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                 // if stopping, ignore
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          *  Note -- this must handle null items
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 }