View Javadoc

1   /*
2    * $Id: DefaultJmsTopicResolver.java 19191 2010-08-25 21:05:23Z 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;
12  
13  import org.mule.api.endpoint.ImmutableEndpoint;
14  import org.mule.util.MapUtils;
15  import org.mule.util.StringMessageUtils;
16  
17  import javax.jms.Destination;
18  import javax.jms.Queue;
19  import javax.jms.Topic;
20  
21  import org.apache.commons.logging.Log;
22  import org.apache.commons.logging.LogFactory;
23  
24  /**
25   * A default implementation of the resolver uses endpoint's
26   * resource info and Java's {@code instanceof} operator to
27   * detect JMS topics.
28   */
29  public class DefaultJmsTopicResolver implements JmsTopicResolver
30  {
31      /**
32       * logger used by this class
33       */
34      protected static final Log logger = LogFactory.getLog(DefaultJmsTopicResolver.class);
35  
36      /**
37       * Connector back-reference.
38       */
39      private JmsConnector connector;
40  
41      /**
42       * Create an instance of the resolver.
43       * @param connector owning connector
44       */
45      public DefaultJmsTopicResolver (final JmsConnector connector)
46      {
47          this.connector = connector;
48      }
49  
50  
51      /**
52       * Getter for property 'connector'.
53       *
54       * @return Value for property 'connector'.
55       */
56      public JmsConnector getConnector ()
57      {
58          return connector;
59      }
60  
61      /**
62       * Will use endpoint's resource info to detect a topic,
63       * as in {@code jms://topic:trade.PriceUpdatesTopic}. This
64       * method will call {@link #isTopic(org.mule.api.endpoint.ImmutableEndpoint, boolean)}
65       * with fallback flag set to <strong>true</false>.
66       * <p/>
67       * <strong>NOTE:</strong> When using topics, use the '.' (dot) symbol for subcontext separation,
68       * as opposed to '/'. Otherwise the resource info may not get properly translated for the
69       * topic endpoint due to the way URI's are parsed. 
70       * @param endpoint endpoint to test
71       * @return true if the endpoint has a topic configuration
72       * @see #isTopic(org.mule.api.endpoint.ImmutableEndpoint, boolean) 
73       */
74      public boolean isTopic (ImmutableEndpoint endpoint)
75      {
76          return isTopic(endpoint, true);
77      }
78  
79      /** {@inheritDoc} */
80      public boolean isTopic (ImmutableEndpoint endpoint, boolean fallbackToEndpointProperties)
81      {
82          String resourceInfo = endpoint.getEndpointURI().getResourceInfo();
83  
84          boolean topic = JmsConstants.TOPIC_PROPERTY.equalsIgnoreCase(resourceInfo) ||
85                  endpoint.getEndpointURI().toString().contains(JmsConstants.TOPIC_PROPERTY + ":");
86          if (!topic && fallbackToEndpointProperties)
87          {
88              topic = MapUtils.getBooleanValue(endpoint.getProperties(), JmsConstants.TOPIC_PROPERTY, false);
89          }
90  
91          return topic;
92      }
93  
94      /**
95       * Will use an {@code instanceof} operator. Keep in mind
96       * that may fail for JMS systems implementing both a
97       * {@code javax.jms.Topic} and {@code javax.jms.Queue} in
98       * a single destination class implementation.
99       * @param destination a jms destination to test
100      * @return {@code true} if the destination is a topic
101      */
102     public boolean isTopic (Destination destination)
103     {
104         checkInvariants(destination);
105 
106         return destination instanceof Topic;
107     }
108 
109     /**
110      * Perform some sanity checks, will complain in the log.
111      * @param destination destination to test
112      */
113     protected void checkInvariants (final Destination destination)
114     {
115         if (destination instanceof Topic && destination instanceof Queue
116             && connector.getJmsSupport() instanceof Jms102bSupport)
117         {
118             logger.error(StringMessageUtils.getBoilerPlate(
119                     "Destination implements both Queue and Topic "
120                     + "while complying with JMS 1.0.2b specification. "
121                     + "Please report your application server or JMS vendor name and version "
122                     + "to dev<_at_>mule.codehaus.org or http://www.mulesoft.org/jira"));
123         }
124     }
125 }