View Javadoc

1   /*
2    * $Id: AutoDiscoveryRedeliveryHandlerFactory.java 20501 2010-12-08 00:52:19Z tcarlson $
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.transport.jms.redelivery;
12  
13  import org.mule.config.i18n.CoreMessages;
14  import org.mule.transport.jms.JmsConnector;
15  import org.mule.transport.jms.JmsConstants;
16  
17  import java.util.Enumeration;
18  import java.util.concurrent.atomic.AtomicReference;
19  
20  import javax.jms.ConnectionMetaData;
21  import javax.jms.JMSException;
22  
23  import org.apache.commons.logging.Log;
24  import org.apache.commons.logging.LogFactory;
25  
26  /**
27   * This factory will consult JMS connection metadata for supported optional properties and use
28   * those, if available, otherwise falling back to the manual counting of redeliveries.
29   *
30   * @see CountingRedeliveryHandlerFactory
31   * @see org.mule.transport.jms.redelivery.JmsXRedeliveryHandlerFactory
32   * @see javax.jms.ConnectionMetaData
33   */
34  public class AutoDiscoveryRedeliveryHandlerFactory implements RedeliveryHandlerFactory
35  {
36      protected final Log logger = LogFactory.getLog(getClass());
37  
38      protected AtomicReference<RedeliveryHandler> delegateHandler = new AtomicReference<RedeliveryHandler>(null);
39  
40      protected JmsConnector connector;
41  
42      public AutoDiscoveryRedeliveryHandlerFactory(JmsConnector connector)
43      {
44          if (connector == null)
45          {
46              throw new IllegalArgumentException(CoreMessages.objectIsNull("connector").getMessage());
47          }
48          this.connector = connector;
49      }
50  
51      public RedeliveryHandler create()
52      {
53          RedeliveryHandler result;
54  
55          // initialize, accounting for concurrency
56          if (delegateHandler.get() == null)
57          {
58              RedeliveryHandler newInstance = createInstance();
59              boolean ok = delegateHandler.compareAndSet(null, newInstance);
60              if (!ok)
61              {
62                  // someone was faster to initialize it, use this ref instead
63                  result = delegateHandler.get();
64              }
65              else
66              {
67                  result = newInstance;
68              }
69          }
70          else
71          {
72              // just re-use existing handler
73              result = delegateHandler.get();
74          }
75  
76          return result;
77      }
78  
79      /**
80       * Create an instance using the discovery mechanism.
81       *
82       * @return an implementation based on the results of discovery
83       */
84      protected RedeliveryHandler createInstance()
85      {
86          RedeliveryHandler newInstance;
87          try
88          {
89              ConnectionMetaData metaData = connector.getConnection().getMetaData();
90              boolean supportsDeliveryCount = false;
91              final Enumeration propNames = metaData.getJMSXPropertyNames();
92              while (propNames.hasMoreElements())
93              {
94                  String p = (String) propNames.nextElement();
95                  if (JmsConstants.JMS_X_DELIVERY_COUNT.equals(p))
96                  {
97                      supportsDeliveryCount = true;
98                      break;
99                  }
100             }
101 
102             newInstance = (supportsDeliveryCount) ? new JmsXRedeliveryHandler() : new CountingRedeliveryHandler();
103         }
104         catch (JMSException e)
105         {
106             // fallback to defaults
107             newInstance = new CountingRedeliveryHandler();
108         }
109 
110         if (logger.isDebugEnabled())
111         {
112             logger.debug("Using " + newInstance.getClass().getName());
113         }
114 
115         return newInstance;
116     }
117 
118 }