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