001 /**
002 *
003 * Copyright 2004 Protique Ltd
004 *
005 * Licensed under the Apache License, Version 2.0 (the "License");
006 * you may not use this file except in compliance with the License.
007 * You may obtain a copy of the License at
008 *
009 * http://www.apache.org/licenses/LICENSE-2.0
010 *
011 * Unless required by applicable law or agreed to in writing, software
012 * distributed under the License is distributed on an "AS IS" BASIS,
013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014 * See the License for the specific language governing permissions and
015 * limitations under the License.
016 *
017 **/
018 package org.activemq.jndi;
019
020 import java.util.ArrayList;
021 import java.util.Hashtable;
022 import java.util.Iterator;
023 import java.util.List;
024 import java.util.Map;
025 import java.util.Properties;
026 import java.util.StringTokenizer;
027
028 import javax.jms.ConnectionFactory;
029 import javax.jms.JMSException;
030 import javax.jms.Queue;
031 import javax.jms.Topic;
032 import javax.naming.Context;
033 import javax.naming.NamingException;
034 import javax.naming.spi.InitialContextFactory;
035
036 import org.activemq.ActiveMQConnectionFactory;
037 import org.activemq.broker.Broker;
038 import org.activemq.message.ActiveMQQueue;
039 import org.activemq.message.ActiveMQTopic;
040 import org.apache.commons.logging.Log;
041 import org.apache.commons.logging.LogFactory;
042
043 import EDU.oswego.cs.dl.util.concurrent.ConcurrentHashMap;
044
045 /**
046 * A factory of the ActiveMQ InitialContext which contains {@link ConnectionFactory}
047 * instances as well as a child context called <i>destinations</i> which contain all of the
048 * current active destinations, in child context depending on the QoS such as
049 * transient or durable and queue or topic.
050 *
051 * @version $Revision: 1.1.1.1 $
052 */
053 public class ActiveMQInitialContextFactory implements InitialContextFactory {
054 private static final transient Log log = LogFactory.getLog(ActiveMQInitialContextFactory.class);
055
056 protected static final String[] defaultConnectionFactoryNames = {
057 "ConnectionFactory", "QueueConnectionFactory", "TopicConnectionFactory"
058 };
059
060 private String connectionPrefix = "connection.";
061 private String queuePrefix = "queue.";
062 private String topicPrefix = "topic.";
063
064 public Context getInitialContext(Hashtable environment) throws NamingException {
065 // lets create a factory
066 Map data = new ConcurrentHashMap();
067 Broker broker = null;
068
069 String[] names = getConnectionFactoryNames(environment);
070 for (int i = 0; i < names.length; i++) {
071
072 String name = names[i];
073 ActiveMQConnectionFactory factory = createConnectionFactory(name, environment);
074
075 if( broker==null ) {
076 try {
077 broker = factory.getEmbeddedBroker();
078 }
079 catch (JMSException e) {
080 log.warn("Failed to get embedded broker", e);
081 }
082 }
083 data.put(name,factory);
084 }
085
086 createQueues(data, environment);
087 createTopics(data, environment);
088 if (broker != null) {
089 data.put("destinations", broker.getDestinationContext(environment));
090 }
091
092 data.put("dynamicQueues", new LazyCreateContext() {
093 protected Object createEntry(String name) {
094 return new ActiveMQQueue(name);
095 }
096 });
097 data.put("dynamicTopics", new LazyCreateContext() {
098 protected Object createEntry(String name) {
099 return new ActiveMQTopic(name);
100 }
101 });
102
103 return new ReadOnlyContext(environment, data);
104 }
105
106 private ActiveMQConnectionFactory createConnectionFactory(String name, Hashtable environment) {
107 Hashtable temp = new Hashtable(environment);
108 String prefix = connectionPrefix+name+".";
109 for (Iterator iter = environment.keySet().iterator(); iter.hasNext();) {
110 String key = (String) iter.next();
111 if( key.startsWith(prefix) ) {
112 Object value = environment.get(key);
113 // Rename the key...
114 temp.remove(key);
115 key = key.substring(prefix.length());
116 temp.put(key, value);
117 }
118 }
119 return createConnectionFactory(temp);
120 }
121
122 // Properties
123 //-------------------------------------------------------------------------
124 public String getTopicPrefix() {
125 return topicPrefix;
126 }
127
128 public void setTopicPrefix(String topicPrefix) {
129 this.topicPrefix = topicPrefix;
130 }
131
132 public String getQueuePrefix() {
133 return queuePrefix;
134 }
135
136 public void setQueuePrefix(String queuePrefix) {
137 this.queuePrefix = queuePrefix;
138 }
139
140 // Implementation methods
141 //-------------------------------------------------------------------------
142 protected String[] getConnectionFactoryNames(Map environment) {
143 String factoryNames = (String) environment.get("connectionFactoryNames");
144 if (factoryNames != null) {
145 List list = new ArrayList();
146 for (StringTokenizer enumeration = new StringTokenizer(factoryNames, ","); enumeration.hasMoreTokens();) {
147 list.add(enumeration.nextToken().trim());
148 }
149 int size = list.size();
150 if (size > 0) {
151 String[] answer = new String[size];
152 list.toArray(answer);
153 return answer;
154 }
155 }
156 return defaultConnectionFactoryNames;
157 }
158
159 protected void createQueues(Map data, Hashtable environment) {
160 for (Iterator iter = environment.entrySet().iterator(); iter.hasNext();) {
161 Map.Entry entry = (Map.Entry) iter.next();
162 String key = entry.getKey().toString();
163 if (key.startsWith(queuePrefix)) {
164 String jndiName = key.substring(queuePrefix.length());
165 data.put(jndiName, createQueue(entry.getValue().toString()));
166 }
167 }
168 }
169
170 protected void createTopics(Map data, Hashtable environment) {
171 for (Iterator iter = environment.entrySet().iterator(); iter.hasNext();) {
172 Map.Entry entry = (Map.Entry) iter.next();
173 String key = entry.getKey().toString();
174 if (key.startsWith(topicPrefix)) {
175 String jndiName = key.substring(topicPrefix.length());
176 data.put(jndiName, createTopic(entry.getValue().toString()));
177 }
178 }
179 }
180
181 /**
182 * Factory method to create new Queue instances
183 */
184 protected Queue createQueue(String name) {
185 return new ActiveMQQueue(name);
186 }
187
188 /**
189 * Factory method to create new Topic instances
190 */
191 protected Topic createTopic(String name) {
192 return new ActiveMQTopic(name);
193 }
194
195 /**
196 * Factory method to create a new connection factory from the given environment
197 */
198 protected ActiveMQConnectionFactory createConnectionFactory(Hashtable environment) {
199 ActiveMQConnectionFactory answer = new ActiveMQConnectionFactory();
200 Properties properties = new Properties();
201 properties.putAll(environment);
202 answer.setProperties(properties);
203 return answer;
204 }
205
206 public String getConnectionPrefix() {
207 return connectionPrefix;
208 }
209
210
211 public void setConnectionPrefix(String connectionPrefix) {
212 this.connectionPrefix = connectionPrefix;
213 }
214
215 }