1 /**
2 * Copyright 2005-2006 the original author or authors.
3 *
4 * Licensed under the Gnu General Pubic License, Version 2.0 (the
5 * "License"); you may not use this file except in compliance with
6 * the License. You may obtain a copy of the License at
7 *
8 * http://www.opensource.org/licenses/gpl-license.php
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
13 * See the Gnu General Public License for more details.
14 */
15 package org.figure8.join.core.messaging;
16
17 import org.figure8.join.core.ContainerContextHandler;
18 import org.figure8.join.core.InfrastructureException;
19 import org.figure8.join.core.InvalidParameterException;
20 import org.figure8.join.core.setup.ApplicationConfig;
21 import org.figure8.join.core.setup.ActiveMQConfigurator;
22 import org.figure8.join.util.LogUtil;
23
24 import org.apache.commons.logging.Log;
25
26 import javax.jms.Queue;
27 import javax.jms.Topic;
28 import javax.naming.InitialContext;
29 import javax.naming.NameNotFoundException;
30 import javax.naming.NamingException;
31
32 import java.util.Properties;
33 /**
34 * This is an implementation of {@link JMSDestinationResolver} for resolving
35 * ActiveMQ provider destinations. It uses ActiveMQ Jndi integration to resolve
36 * remote destinations.
37 * @author <a href="mailto:laurent.broudoux@free.fr">Laurent Broudoux</a>
38 * @version $Revision: 1.1 $
39 */
40 public class ActiveMQDestinationResolver implements JMSDestinationResolver{
41
42
43
44 /** Get a commons logger. */
45 private static final Log log = LogUtil.getLog(ActiveMQDestinationResolver.class);
46
47 /** Value of naming factory for ActiveMQ Jndi implementation */
48 public static final String AMQ_NAMING_FACTORY = "org.activemq.jndi.ActiveMQInitialContextFactory";
49 /** Name of ActiveMQ properties prefix for queue names */
50 public static final String AMQ_QUEUE_PREFIX = "queue.";
51 /** Name of ActiveMQ properties preix for topic names */
52 public static final String AMQ_TOPIC_PREFIX = "topic.";
53
54
55
56
57 /** The application configuration to use for acquiring destinations */
58 protected ApplicationConfig configuration;
59
60
61
62
63 /** Creates a new instance of ActiveMQDestinationResolver */
64 public ActiveMQDestinationResolver(){
65 }
66
67
68
69
70 /**
71 * Set the current application conifguration to this resolver
72 * @param configuration The application configured settings
73 */
74 public void setApplicationConfig(ApplicationConfig configuration){
75 this.configuration = configuration;
76 }
77
78 /**
79 * Resolve a JMS queue using its name. Resolution means name resolution and
80 * application of mechanism necessary to acquire the queue (may be a remote queue)
81 * @param name The name of the queue to retrive
82 * @throws InfrastructureException if acquisition context (Jndi for example) is not available
83 * @throws InvalidParameterException if the specified destination name is unknown by resolution system
84 * @return The acquired queue
85 */
86 public Queue resolveQueue(String name) throws InfrastructureException, InvalidParameterException{
87
88 Object object = null;
89
90
91 if (!configuration.isDissociatedSetup())
92 object = resolveLocalObject(name);
93
94 else object = resolveRemoteObject(name, true);
95
96
97 if (!(object instanceof Queue)){
98
99 log.error("Context object denoted by '" + name + "' is not a javax.jms.Queue !");
100 throw new InvalidParameterException("Context object '" + name + "' is not a Queue");
101 }
102 return (Queue)object;
103 }
104
105 /**
106 * Resolve a JMS topic using its name. Resolution means name resolution and
107 * application of mechanism necessary to acquire the topic (may be a remote topic)
108 * @param name The name of the topic to retrieve
109 * @throws InfrastructureException if acquisition context (Jndi for example) is not available
110 * @throws InvalidParameterException if the specified destination name is unknown by resolution system
111 * @return The acquired topic
112 */
113 public Topic resolveTopic(String name) throws InfrastructureException, InvalidParameterException{
114
115 Object object = null;
116
117
118 if (!configuration.isDissociatedSetup())
119 object = resolveLocalObject(name);
120
121 else object = resolveRemoteObject(name, false);
122
123
124 if (!(object instanceof Topic)){
125
126 log.error("Context object denoted by '" + name + "' is not a javax.jms.Topic !");
127 throw new InvalidParameterException("Context object '" + name + "' is not a Topic");
128 }
129 return (Topic)object;
130 }
131
132
133
134
135 /**
136 * Resolve destination as a locally available object through container context.
137 * @param name The name of destination to lookup
138 * @return The resolved local object
139 */
140 protected Object resolveLocalObject(String name) throws InfrastructureException, InvalidParameterException{
141 if (log.isDebugEnabled())
142 log.debug("Resolving '" + name + "' destination using local container context");
143
144 ContainerContextHandler handler = ContainerContextHandler.getInstance();
145 return handler.getComponent(name);
146 }
147
148 /**
149 * Resolve destination as a remote object bound into a Jndi tree.
150 * @param name The jndi name of destination to lookup
151 * @param isQueue Flag telling telling whether destination is a queue or a topic
152 * @return The resolved remote object
153 */
154 protected Object resolveRemoteObject(String name, boolean isQueue) throws InfrastructureException, InvalidParameterException{
155 if (log.isDebugEnabled())
156 log.debug("Resolving '" + name + "' queue using remote container definition");
157 try{
158
159 Properties environment = buildEnvironment(name, isQueue);
160 if (log.isDebugEnabled())
161 log.debug("Looking for destination '" + name + "' using environment " + environment);
162 InitialContext ctx = new InitialContext(environment);
163 return ctx.lookup(name);
164 }
165 catch (NameNotFoundException nnfe){
166
167 log.error("The remote destination " + name + " cannot be found");
168 throw new InvalidParameterException("The remote destintion cannot be found", nnfe);
169 }
170 catch (NamingException ne){
171
172 log.error("Remote connection failed with NamingException: " + ne.getMessage());
173 throw new InfrastructureException("Remote connection failed with NamingException", ne);
174 }
175 }
176
177
178
179
180 /**
181 * @param name The name of destination to build environment for
182 * @param isQueue Whether destination corresponding to name is a queue
183 * @return The set of properties for initializing Jndi context
184 */
185 private Properties buildEnvironment(String name, boolean isQueue){
186
187 Properties environment = new Properties();
188 environment.put(InitialContext.INITIAL_CONTEXT_FACTORY, AMQ_NAMING_FACTORY);
189 environment.put(InitialContext.PROVIDER_URL, configuration.getProperty(ActiveMQConfigurator.AMQ_BROKER_URL));
190 environment.put(ActiveMQConfigurator.AMQ_BROKER_URL, configuration.getProperty(ActiveMQConfigurator.AMQ_BROKER_URL));
191
192 if (isQueue)
193 environment.put(AMQ_QUEUE_PREFIX + name, name);
194 else
195 environment.put(AMQ_TOPIC_PREFIX + name, name);
196 return environment;
197 }
198 }