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 }