001    /**
002     * Licensed to the Apache Software Foundation (ASF) under one or more
003     * contributor license agreements.  See the NOTICE file distributed with
004     * this work for additional information regarding copyright ownership.
005     * The ASF licenses this file to You under the Apache License, Version 2.0
006     * (the "License"); you may not use this file except in compliance with
007     * the License.  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    package org.apache.activemq.jndi;
018    
019    import java.net.URISyntaxException;
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    import java.util.concurrent.ConcurrentHashMap;
028    
029    import javax.jms.Queue;
030    import javax.jms.Topic;
031    import javax.naming.Context;
032    import javax.naming.NamingException;
033    import javax.naming.spi.InitialContextFactory;
034    
035    import org.apache.activemq.ActiveMQConnectionFactory;
036    import org.apache.activemq.command.ActiveMQQueue;
037    import org.apache.activemq.command.ActiveMQTopic;
038    
039    /**
040     * A factory of the ActiveMQ InitialContext which contains
041     * {@link ConnectionFactory} instances as well as a child context called
042     * <i>destinations</i> which contain all of the current active destinations, in
043     * child context depending on the QoS such as transient or durable and queue or
044     * topic.
045     * 
046     * @version $Revision: 1.2 $
047     */
048    public class ActiveMQInitialContextFactory implements InitialContextFactory {
049    
050        private static final String[] DEFAULT_CONNECTION_FACTORY_NAMES = {"ConnectionFactory", "QueueConnectionFactory", "TopicConnectionFactory"};
051    
052        private String connectionPrefix = "connection.";
053        private String queuePrefix = "queue.";
054        private String topicPrefix = "topic.";
055    
056        public Context getInitialContext(Hashtable environment) throws NamingException {
057            // lets create a factory
058            Map<String, Object> data = new ConcurrentHashMap<String, Object>();
059            String[] names = getConnectionFactoryNames(environment);
060            for (int i = 0; i < names.length; i++) {
061                ActiveMQConnectionFactory factory = null;
062                String name = names[i];
063    
064                try {
065                    factory = createConnectionFactory(name, environment);
066                } catch (Exception e) {
067                    throw new NamingException("Invalid broker URL");
068    
069                }
070                /*
071                 * if( broker==null ) { try { broker = factory.getEmbeddedBroker(); }
072                 * catch (JMSException e) { log.warn("Failed to get embedded
073                 * broker", e); } }
074                 */
075                data.put(name, factory);
076            }
077    
078            createQueues(data, environment);
079            createTopics(data, environment);
080            /*
081             * if (broker != null) { data.put("destinations",
082             * broker.getDestinationContext(environment)); }
083             */
084            data.put("dynamicQueues", new LazyCreateContext() {
085                private static final long serialVersionUID = 6503881346214855588L;
086    
087                protected Object createEntry(String name) {
088                    return new ActiveMQQueue(name);
089                }
090            });
091            data.put("dynamicTopics", new LazyCreateContext() {
092                private static final long serialVersionUID = 2019166796234979615L;
093    
094                protected Object createEntry(String name) {
095                    return new ActiveMQTopic(name);
096                }
097            });
098    
099            return createContext(environment, data);
100        }
101    
102        // Properties
103        // -------------------------------------------------------------------------
104        public String getTopicPrefix() {
105            return topicPrefix;
106        }
107    
108        public void setTopicPrefix(String topicPrefix) {
109            this.topicPrefix = topicPrefix;
110        }
111    
112        public String getQueuePrefix() {
113            return queuePrefix;
114        }
115    
116        public void setQueuePrefix(String queuePrefix) {
117            this.queuePrefix = queuePrefix;
118        }
119    
120        // Implementation methods
121        // -------------------------------------------------------------------------
122    
123        protected ReadOnlyContext createContext(Hashtable environment, Map<String, Object> data) {
124            return new ReadOnlyContext(environment, data);
125        }
126    
127        protected ActiveMQConnectionFactory createConnectionFactory(String name, Hashtable environment) throws URISyntaxException {
128            Hashtable temp = new Hashtable(environment);
129            String prefix = connectionPrefix + name + ".";
130            for (Iterator iter = environment.entrySet().iterator(); iter.hasNext();) {
131                Map.Entry entry = (Map.Entry)iter.next();
132                String key = (String)entry.getKey();
133                if (key.startsWith(prefix)) {
134                    // Rename the key...
135                    temp.remove(key);
136                    key = key.substring(prefix.length());
137                    temp.put(key, entry.getValue());
138                }
139            }
140            return createConnectionFactory(temp);
141        }
142    
143        protected String[] getConnectionFactoryNames(Map environment) {
144            String factoryNames = (String)environment.get("connectionFactoryNames");
145            if (factoryNames != null) {
146                List<String> list = new ArrayList<String>();
147                for (StringTokenizer enumeration = new StringTokenizer(factoryNames, ","); enumeration.hasMoreTokens();) {
148                    list.add(enumeration.nextToken().trim());
149                }
150                int size = list.size();
151                if (size > 0) {
152                    String[] answer = new String[size];
153                    list.toArray(answer);
154                    return answer;
155                }
156            }
157            return DEFAULT_CONNECTION_FACTORY_NAMES;
158        }
159    
160        protected void createQueues(Map<String, Object> data, Hashtable environment) {
161            for (Iterator iter = environment.entrySet().iterator(); iter.hasNext();) {
162                Map.Entry entry = (Map.Entry)iter.next();
163                String key = entry.getKey().toString();
164                if (key.startsWith(queuePrefix)) {
165                    String jndiName = key.substring(queuePrefix.length());
166                    data.put(jndiName, createQueue(entry.getValue().toString()));
167                }
168            }
169        }
170    
171        protected void createTopics(Map<String, Object> data, Hashtable environment) {
172            for (Iterator iter = environment.entrySet().iterator(); iter.hasNext();) {
173                Map.Entry entry = (Map.Entry)iter.next();
174                String key = entry.getKey().toString();
175                if (key.startsWith(topicPrefix)) {
176                    String jndiName = key.substring(topicPrefix.length());
177                    data.put(jndiName, createTopic(entry.getValue().toString()));
178                }
179            }
180        }
181    
182        /**
183         * Factory method to create new Queue instances
184         */
185        protected Queue createQueue(String name) {
186            return new ActiveMQQueue(name);
187        }
188    
189        /**
190         * Factory method to create new Topic instances
191         */
192        protected Topic createTopic(String name) {
193            return new ActiveMQTopic(name);
194        }
195    
196        /**
197         * Factory method to create a new connection factory from the given
198         * environment
199         */
200        protected ActiveMQConnectionFactory createConnectionFactory(Hashtable environment) throws URISyntaxException {
201            ActiveMQConnectionFactory answer = new ActiveMQConnectionFactory();
202            Properties properties = new Properties();
203            properties.putAll(environment);
204            answer.setProperties(properties);
205            return answer;
206        }
207    
208        public String getConnectionPrefix() {
209            return connectionPrefix;
210        }
211    
212        public void setConnectionPrefix(String connectionPrefix) {
213            this.connectionPrefix = connectionPrefix;
214        }
215    
216    }