You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@qpid.apache.org by ri...@apache.org on 2006/10/20 13:46:58 UTC
svn commit: r466076 - in /incubator/qpid/trunk/qpid/java/client:
src/org/apache/qpid/client/ src/org/apache/qpid/jndi/
test/src/org/apache/qpid/test/ test/src/org/apache/qpid/test/unit/
test/src/org/apache/qpid/test/unit/jndi/
Author: ritchiem
Date: Fri Oct 20 04:46:56 2006
New Revision: 466076
URL: http://svn.apache.org/viewvc?view=rev&rev=466076
Log:
Resolution to QPID-23
Added Simple JNDI SPI Class that uses a PropertiesFile to create a ContextFactory for use with in JNDI.
Added a unit test to test using properties file to get correct objects from JNDI lookup.
Modifed AMQHeadersExchange.java to allow creation from a BindingURL.
Added:
incubator/qpid/trunk/qpid/java/client/src/org/apache/qpid/jndi/
incubator/qpid/trunk/qpid/java/client/src/org/apache/qpid/jndi/Example.properties (with props)
incubator/qpid/trunk/qpid/java/client/src/org/apache/qpid/jndi/NameParserImpl.java (with props)
incubator/qpid/trunk/qpid/java/client/src/org/apache/qpid/jndi/PropertiesFileInitialContextFactory.java (with props)
incubator/qpid/trunk/qpid/java/client/src/org/apache/qpid/jndi/ReadOnlyContext.java (with props)
incubator/qpid/trunk/qpid/java/client/test/src/org/apache/qpid/test/
incubator/qpid/trunk/qpid/java/client/test/src/org/apache/qpid/test/unit/
incubator/qpid/trunk/qpid/java/client/test/src/org/apache/qpid/test/unit/jndi/
incubator/qpid/trunk/qpid/java/client/test/src/org/apache/qpid/test/unit/jndi/PropertiesFileInitialContextFactoryTest.java (with props)
Modified:
incubator/qpid/trunk/qpid/java/client/src/org/apache/qpid/client/AMQHeadersExchange.java
Modified: incubator/qpid/trunk/qpid/java/client/src/org/apache/qpid/client/AMQHeadersExchange.java
URL: http://svn.apache.org/viewvc/incubator/qpid/trunk/qpid/java/client/src/org/apache/qpid/client/AMQHeadersExchange.java?view=diff&rev=466076&r1=466075&r2=466076
==============================================================================
--- incubator/qpid/trunk/qpid/java/client/src/org/apache/qpid/client/AMQHeadersExchange.java (original)
+++ incubator/qpid/trunk/qpid/java/client/src/org/apache/qpid/client/AMQHeadersExchange.java Fri Oct 20 04:46:56 2006
@@ -18,12 +18,18 @@
package org.apache.qpid.client;
import org.apache.qpid.exchange.ExchangeDefaults;
+import org.apache.qpid.url.BindingURL;
/**
* A destination backed by a headers exchange
*/
public class AMQHeadersExchange extends AMQDestination
{
+ public AMQHeadersExchange(BindingURL binding)
+ {
+ this(binding.getExchangeName());
+ }
+
public AMQHeadersExchange(String queueName)
{
super(queueName, ExchangeDefaults.HEADERS_EXCHANGE_CLASS, queueName, true, true, null);
Added: incubator/qpid/trunk/qpid/java/client/src/org/apache/qpid/jndi/Example.properties
URL: http://svn.apache.org/viewvc/incubator/qpid/trunk/qpid/java/client/src/org/apache/qpid/jndi/Example.properties?view=auto&rev=466076
==============================================================================
--- incubator/qpid/trunk/qpid/java/client/src/org/apache/qpid/jndi/Example.properties (added)
+++ incubator/qpid/trunk/qpid/java/client/src/org/apache/qpid/jndi/Example.properties Fri Oct 20 04:46:56 2006
@@ -0,0 +1,21 @@
+java.naming.factory.initial = org.apache.qpid.jndi.PropertiesFileInitialConextFactory
+
+# use the following property to configure the default connector
+#java.naming.provider.url - ignored.
+
+# register some connection factories
+# connectionfactory.[jndiname] = [ConnectionURL]
+connectionfactory.local = amqp://guest:guest@clientid/testpath?brokerlist='vm://:1'
+
+# register some queues in JNDI using the form
+# queue.[jndiName] = [physicalName]
+queue.MyQueue = example.MyQueue
+
+# register some topics in JNDI using the form
+# topic.[jndiName] = [physicalName]
+topic.ibmStocks = stocks.nyse.ibm
+
+# Register an AMQP destination in JNDI
+# NOTE: Qpid currently only supports direct,topics and headers
+# destination.[jniName] = [BindingURL]
+destination.direct = direct://amq.direct//directQueue
Propchange: incubator/qpid/trunk/qpid/java/client/src/org/apache/qpid/jndi/Example.properties
------------------------------------------------------------------------------
svn:eol-style = native
Added: incubator/qpid/trunk/qpid/java/client/src/org/apache/qpid/jndi/NameParserImpl.java
URL: http://svn.apache.org/viewvc/incubator/qpid/trunk/qpid/java/client/src/org/apache/qpid/jndi/NameParserImpl.java?view=auto&rev=466076
==============================================================================
--- incubator/qpid/trunk/qpid/java/client/src/org/apache/qpid/jndi/NameParserImpl.java (added)
+++ incubator/qpid/trunk/qpid/java/client/src/org/apache/qpid/jndi/NameParserImpl.java Fri Oct 20 04:46:56 2006
@@ -0,0 +1,37 @@
+/**
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.qpid.jndi;
+
+import javax.naming.CompositeName;
+import javax.naming.Name;
+import javax.naming.NameParser;
+import javax.naming.NamingException;
+
+/**
+ * A default implementation of {@link NameParser}
+ * <p/>
+ * Based on class from ActiveMQ.
+ */
+public class NameParserImpl implements NameParser
+{
+ public Name parse(String name) throws NamingException
+ {
+ return new CompositeName(name);
+ }
+}
Propchange: incubator/qpid/trunk/qpid/java/client/src/org/apache/qpid/jndi/NameParserImpl.java
------------------------------------------------------------------------------
svn:eol-style = native
Added: incubator/qpid/trunk/qpid/java/client/src/org/apache/qpid/jndi/PropertiesFileInitialContextFactory.java
URL: http://svn.apache.org/viewvc/incubator/qpid/trunk/qpid/java/client/src/org/apache/qpid/jndi/PropertiesFileInitialContextFactory.java?view=auto&rev=466076
==============================================================================
--- incubator/qpid/trunk/qpid/java/client/src/org/apache/qpid/jndi/PropertiesFileInitialContextFactory.java (added)
+++ incubator/qpid/trunk/qpid/java/client/src/org/apache/qpid/jndi/PropertiesFileInitialContextFactory.java Fri Oct 20 04:46:56 2006
@@ -0,0 +1,289 @@
+/*
+ *
+ * Copyright (c) 2006 The Apache Software Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.qpid.jndi;
+
+import org.apache.log4j.Logger;
+import org.apache.qpid.client.AMQConnectionFactory;
+import org.apache.qpid.client.AMQHeadersExchange;
+import org.apache.qpid.client.AMQQueue;
+import org.apache.qpid.client.AMQTopic;
+import org.apache.qpid.exchange.ExchangeDefaults;
+import org.apache.qpid.url.AMQBindingURL;
+import org.apache.qpid.url.BindingURL;
+import org.apache.qpid.url.URLSyntaxException;
+
+import javax.jms.ConnectionFactory;
+import javax.jms.Destination;
+import javax.jms.Queue;
+import javax.jms.Topic;
+import javax.naming.Context;
+import javax.naming.NamingException;
+import javax.naming.spi.InitialContextFactory;
+import java.util.Hashtable;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+
+public class PropertiesFileInitialContextFactory implements InitialContextFactory
+{
+ protected final Logger _logger = Logger.getLogger(getClass());
+
+ private String CONNECTION_FACTORY_PREFIX = "connectionfactory.";
+ private String DESTINATION_PREFIX = "destination.";
+ private String QUEUE_PREFIX = "queue.";
+ private String TOPIC_PREFIX = "topic.";
+
+ public Context getInitialContext(Hashtable environment) throws NamingException
+ {
+ Map data = new ConcurrentHashMap();
+
+ createConnectionFactories(data, environment);
+
+ createDestinations(data, environment);
+
+ createQueues(data, environment);
+
+ createTopics(data, environment);
+
+ return createContext(data, environment);
+ }
+
+ // Implementation methods
+ //-------------------------------------------------------------------------
+ protected ReadOnlyContext createContext(Map data, Hashtable environment)
+ {
+ return new ReadOnlyContext(environment, data);
+ }
+
+ protected void createConnectionFactories(Map data, Hashtable environment)
+ {
+ for (Iterator iter = environment.entrySet().iterator(); iter.hasNext();)
+ {
+ Map.Entry entry = (Map.Entry) iter.next();
+ String key = entry.getKey().toString();
+ if (key.startsWith(CONNECTION_FACTORY_PREFIX))
+ {
+ String jndiName = key.substring(CONNECTION_FACTORY_PREFIX.length());
+ ConnectionFactory cf = createFactory(entry.getValue().toString());
+ if (cf != null)
+ {
+ data.put(jndiName, cf);
+ }
+ }
+ }
+ }
+
+ protected void createDestinations(Map data, Hashtable environment)
+ {
+ for (Iterator iter = environment.entrySet().iterator(); iter.hasNext();)
+ {
+ Map.Entry entry = (Map.Entry) iter.next();
+ String key = entry.getKey().toString();
+ if (key.startsWith(DESTINATION_PREFIX))
+ {
+ String jndiName = key.substring(DESTINATION_PREFIX.length());
+ Destination dest = createDestination(entry.getValue().toString());
+ if (dest != null)
+ {
+ data.put(jndiName, dest);
+ }
+ }
+ }
+ }
+
+ protected void createQueues(Map data, Hashtable environment)
+ {
+ for (Iterator iter = environment.entrySet().iterator(); iter.hasNext();)
+ {
+ Map.Entry entry = (Map.Entry) iter.next();
+ String key = entry.getKey().toString();
+ if (key.startsWith(QUEUE_PREFIX))
+ {
+ String jndiName = key.substring(QUEUE_PREFIX.length());
+ Queue q = createQueue(entry.getValue().toString());
+ if (q != null)
+ {
+ data.put(jndiName, q);
+ }
+ }
+ }
+ }
+
+ protected void createTopics(Map data, Hashtable environment)
+ {
+ for (Iterator iter = environment.entrySet().iterator(); iter.hasNext();)
+ {
+ Map.Entry entry = (Map.Entry) iter.next();
+ String key = entry.getKey().toString();
+ if (key.startsWith(TOPIC_PREFIX))
+ {
+ String jndiName = key.substring(TOPIC_PREFIX.length());
+ Topic t = createTopic(entry.getValue().toString());
+ if (t != null)
+ {
+ data.put(jndiName, t);
+ }
+ }
+ }
+ }
+
+ /**
+ * Factory method to create new Connection Factory instances
+ */
+ protected ConnectionFactory createFactory(String url)
+ {
+ try
+ {
+ return new AMQConnectionFactory(url);
+ }
+ catch (URLSyntaxException urlse)
+ {
+ _logger.warn("Unable to createFactories:" + urlse);
+ }
+ return null;
+ }
+
+ /**
+ * Factory method to create new Destination instances from an AMQP BindingURL
+ */
+ protected Destination createDestination(String bindingURL)
+ {
+ AMQBindingURL binding;
+ try
+ {
+ binding = new AMQBindingURL(bindingURL);
+ }
+ catch (URLSyntaxException urlse)
+ {
+ _logger.warn("Unable to destination:" + urlse);
+ return null;
+ }
+
+ if (binding.getExchangeClass().equals(ExchangeDefaults.TOPIC_EXCHANGE_CLASS))
+ {
+ return createTopic(binding);
+ }
+ else if (binding.getExchangeClass().equals(ExchangeDefaults.DIRECT_EXCHANGE_CLASS))
+ {
+ return createQueue(binding);
+ }
+ else if (binding.getExchangeClass().equals(ExchangeDefaults.HEADERS_EXCHANGE_CLASS))
+ {
+ return createHeaderExchange(binding);
+ }
+
+ _logger.warn("Binding: '" + binding + "' not supported");
+ return null;
+ }
+
+ /**
+ * Factory method to create new Queue instances
+ */
+ protected Queue createQueue(Object value)
+ {
+ if (value instanceof String)
+
+ {
+ return new AMQQueue((String) value);
+ }
+ else if (value instanceof BindingURL)
+
+ {
+ return new AMQQueue((BindingURL) value);
+ }
+
+ return null;
+ }
+
+ /**
+ * Factory method to create new Topic instances
+ */
+ protected Topic createTopic(Object value)
+ {
+ if (value instanceof String)
+ {
+ return new AMQTopic((String) value);
+ }
+ else if (value instanceof BindingURL)
+
+ {
+ return new AMQTopic((BindingURL) value);
+ }
+
+ return null;
+ }
+
+ /**
+ * Factory method to create new HeaderExcahnge instances
+ */
+ protected Destination createHeaderExchange(Object value)
+ {
+ if (value instanceof String)
+ {
+ return new AMQHeadersExchange((String) value);
+ }
+ else if (value instanceof BindingURL)
+ {
+ return new AMQHeadersExchange((BindingURL) value);
+ }
+
+ return null;
+ }
+
+ // Properties
+ //-------------------------------------------------------------------------
+ public String getConnectionPrefix()
+ {
+ return CONNECTION_FACTORY_PREFIX;
+ }
+
+ public void setConnectionPrefix(String connectionPrefix)
+ {
+ this.CONNECTION_FACTORY_PREFIX = connectionPrefix;
+ }
+
+ public String getDestinationPrefix()
+ {
+ return DESTINATION_PREFIX;
+ }
+
+ public void setDestinationPrefix(String destinationPrefix)
+ {
+ this.DESTINATION_PREFIX = destinationPrefix;
+ }
+
+ public String getQueuePrefix()
+ {
+ return QUEUE_PREFIX;
+ }
+
+ public void setQueuePrefix(String queuePrefix)
+ {
+ this.QUEUE_PREFIX = queuePrefix;
+ }
+
+ public String getTopicPrefix()
+ {
+ return TOPIC_PREFIX;
+ }
+
+ public void setTopicPrefix(String topicPrefix)
+ {
+ this.TOPIC_PREFIX = topicPrefix;
+ }
+}
Propchange: incubator/qpid/trunk/qpid/java/client/src/org/apache/qpid/jndi/PropertiesFileInitialContextFactory.java
------------------------------------------------------------------------------
svn:eol-style = native
Added: incubator/qpid/trunk/qpid/java/client/src/org/apache/qpid/jndi/ReadOnlyContext.java
URL: http://svn.apache.org/viewvc/incubator/qpid/trunk/qpid/java/client/src/org/apache/qpid/jndi/ReadOnlyContext.java?view=auto&rev=466076
==============================================================================
--- incubator/qpid/trunk/qpid/java/client/src/org/apache/qpid/jndi/ReadOnlyContext.java (added)
+++ incubator/qpid/trunk/qpid/java/client/src/org/apache/qpid/jndi/ReadOnlyContext.java Fri Oct 20 04:46:56 2006
@@ -0,0 +1,497 @@
+/**
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.qpid.jndi;
+
+import javax.naming.*;
+import javax.naming.spi.NamingManager;
+import java.io.Serializable;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Hashtable;
+import java.util.Iterator;
+import java.util.Map;
+
+/**
+ * Based on class from ActiveMQ.
+ * A read-only Context
+ * <p/>
+ * This version assumes it and all its subcontext are read-only and any attempt
+ * to modify (e.g. through bind) will result in an OperationNotSupportedException.
+ * Each Context in the tree builds a cache of the entries in all sub-contexts
+ * to optimise the performance of lookup.
+ * </p>
+ * <p>This implementation is intended to optimise the performance of lookup(String)
+ * to about the level of a HashMap get. It has been observed that the scheme
+ * resolution phase performed by the JVM takes considerably longer, so for
+ * optimum performance lookups should be coded like:</p>
+ * <code>
+ * Context componentContext = (Context)new InitialContext().lookup("java:comp");
+ * String envEntry = (String) componentContext.lookup("env/myEntry");
+ * String envEntry2 = (String) componentContext.lookup("env/myEntry2");
+ * </code>
+ *
+ * @version $Revision: 1.2 $ $Date: 2005/08/27 03:52:39 $
+ */
+public class ReadOnlyContext implements Context, Serializable
+{
+ private static final long serialVersionUID = -5754338187296859149L;
+ protected static final NameParser nameParser = new NameParserImpl();
+
+ protected final Hashtable environment; // environment for this context
+ protected final Map bindings; // bindings at my level
+ protected final Map treeBindings; // all bindings under me
+
+ private boolean frozen = false;
+ private String nameInNamespace = "";
+ public static final String SEPARATOR = "/";
+
+ public ReadOnlyContext()
+ {
+ environment = new Hashtable();
+ bindings = new HashMap();
+ treeBindings = new HashMap();
+ }
+
+ public ReadOnlyContext(Hashtable env)
+ {
+ if (env == null)
+ {
+ this.environment = new Hashtable();
+ }
+ else
+ {
+ this.environment = new Hashtable(env);
+ }
+ this.bindings = Collections.EMPTY_MAP;
+ this.treeBindings = Collections.EMPTY_MAP;
+ }
+
+ public ReadOnlyContext(Hashtable environment, Map bindings)
+ {
+ if (environment == null)
+ {
+ this.environment = new Hashtable();
+ }
+ else
+ {
+ this.environment = new Hashtable(environment);
+ }
+ this.bindings = bindings;
+ treeBindings = new HashMap();
+ frozen = true;
+ }
+
+ public ReadOnlyContext(Hashtable environment, Map bindings, String nameInNamespace)
+ {
+ this(environment, bindings);
+ this.nameInNamespace = nameInNamespace;
+ }
+
+ protected ReadOnlyContext(ReadOnlyContext clone, Hashtable env)
+ {
+ this.bindings = clone.bindings;
+ this.treeBindings = clone.treeBindings;
+ this.environment = new Hashtable(env);
+ }
+
+ protected ReadOnlyContext(ReadOnlyContext clone, Hashtable env, String nameInNamespace)
+ {
+ this(clone, env);
+ this.nameInNamespace = nameInNamespace;
+ }
+
+ public void freeze()
+ {
+ frozen = true;
+ }
+
+ boolean isFrozen()
+ {
+ return frozen;
+ }
+
+ /**
+ * internalBind is intended for use only during setup or possibly by suitably synchronized superclasses.
+ * It binds every possible lookup into a map in each context. To do this, each context
+ * strips off one name segment and if necessary creates a new context for it. Then it asks that context
+ * to bind the remaining name. It returns a map containing all the bindings from the next context, plus
+ * the context it just created (if it in fact created it). (the names are suitably extended by the segment
+ * originally lopped off).
+ *
+ * @param name
+ * @param value
+ * @return
+ * @throws javax.naming.NamingException
+ */
+ protected Map internalBind(String name, Object value) throws NamingException
+ {
+ assert name != null && name.length() > 0;
+ assert!frozen;
+
+ Map newBindings = new HashMap();
+ int pos = name.indexOf('/');
+ if (pos == -1)
+ {
+ if (treeBindings.put(name, value) != null)
+ {
+ throw new NamingException("Something already bound at " + name);
+ }
+ bindings.put(name, value);
+ newBindings.put(name, value);
+ }
+ else
+ {
+ String segment = name.substring(0, pos);
+ assert segment != null;
+ assert!segment.equals("");
+ Object o = treeBindings.get(segment);
+ if (o == null)
+ {
+ o = newContext();
+ treeBindings.put(segment, o);
+ bindings.put(segment, o);
+ newBindings.put(segment, o);
+ }
+ else if (!(o instanceof ReadOnlyContext))
+ {
+ throw new NamingException("Something already bound where a subcontext should go");
+ }
+ ReadOnlyContext readOnlyContext = (ReadOnlyContext) o;
+ String remainder = name.substring(pos + 1);
+ Map subBindings = readOnlyContext.internalBind(remainder, value);
+ for (Iterator iterator = subBindings.entrySet().iterator(); iterator.hasNext();)
+ {
+ Map.Entry entry = (Map.Entry) iterator.next();
+ String subName = segment + "/" + (String) entry.getKey();
+ Object bound = entry.getValue();
+ treeBindings.put(subName, bound);
+ newBindings.put(subName, bound);
+ }
+ }
+ return newBindings;
+ }
+
+ protected ReadOnlyContext newContext()
+ {
+ return new ReadOnlyContext();
+ }
+
+ public Object addToEnvironment(String propName, Object propVal) throws NamingException
+ {
+ return environment.put(propName, propVal);
+ }
+
+ public Hashtable getEnvironment() throws NamingException
+ {
+ return (Hashtable) environment.clone();
+ }
+
+ public Object removeFromEnvironment(String propName) throws NamingException
+ {
+ return environment.remove(propName);
+ }
+
+ public Object lookup(String name) throws NamingException
+ {
+ if (name.length() == 0)
+ {
+ return this;
+ }
+ Object result = treeBindings.get(name);
+ if (result == null)
+ {
+ result = bindings.get(name);
+ }
+ if (result == null)
+ {
+ int pos = name.indexOf(':');
+ if (pos > 0)
+ {
+ String scheme = name.substring(0, pos);
+ Context ctx = NamingManager.getURLContext(scheme, environment);
+ if (ctx == null)
+ {
+ throw new NamingException("scheme " + scheme + " not recognized");
+ }
+ return ctx.lookup(name);
+ }
+ else
+ {
+ // Split out the first name of the path
+ // and look for it in the bindings map.
+ CompositeName path = new CompositeName(name);
+
+ if (path.size() == 0)
+ {
+ return this;
+ }
+ else
+ {
+ String first = path.get(0);
+ Object obj = bindings.get(first);
+ if (obj == null)
+ {
+ throw new NameNotFoundException(name);
+ }
+ else if (obj instanceof Context && path.size() > 1)
+ {
+ Context subContext = (Context) obj;
+ obj = subContext.lookup(path.getSuffix(1));
+ }
+ return obj;
+ }
+ }
+ }
+ if (result instanceof LinkRef)
+ {
+ LinkRef ref = (LinkRef) result;
+ result = lookup(ref.getLinkName());
+ }
+ if (result instanceof Reference)
+ {
+ try
+ {
+ result = NamingManager.getObjectInstance(result, null, null, this.environment);
+ }
+ catch (NamingException e)
+ {
+ throw e;
+ }
+ catch (Exception e)
+ {
+ throw(NamingException) new NamingException("could not look up : " + name).initCause(e);
+ }
+ }
+ if (result instanceof ReadOnlyContext)
+ {
+ String prefix = getNameInNamespace();
+ if (prefix.length() > 0)
+ {
+ prefix = prefix + SEPARATOR;
+ }
+ result = new ReadOnlyContext((ReadOnlyContext) result, environment, prefix + name);
+ }
+ return result;
+ }
+
+ public Object lookup(Name name) throws NamingException
+ {
+ return lookup(name.toString());
+ }
+
+ public Object lookupLink(String name) throws NamingException
+ {
+ return lookup(name);
+ }
+
+ public Name composeName(Name name, Name prefix) throws NamingException
+ {
+ Name result = (Name) prefix.clone();
+ result.addAll(name);
+ return result;
+ }
+
+ public String composeName(String name, String prefix) throws NamingException
+ {
+ CompositeName result = new CompositeName(prefix);
+ result.addAll(new CompositeName(name));
+ return result.toString();
+ }
+
+ public NamingEnumeration list(String name) throws NamingException
+ {
+ Object o = lookup(name);
+ if (o == this)
+ {
+ return new ListEnumeration();
+ }
+ else if (o instanceof Context)
+ {
+ return ((Context) o).list("");
+ }
+ else
+ {
+ throw new NotContextException();
+ }
+ }
+
+ public NamingEnumeration listBindings(String name) throws NamingException
+ {
+ Object o = lookup(name);
+ if (o == this)
+ {
+ return new ListBindingEnumeration();
+ }
+ else if (o instanceof Context)
+ {
+ return ((Context) o).listBindings("");
+ }
+ else
+ {
+ throw new NotContextException();
+ }
+ }
+
+ public Object lookupLink(Name name) throws NamingException
+ {
+ return lookupLink(name.toString());
+ }
+
+ public NamingEnumeration list(Name name) throws NamingException
+ {
+ return list(name.toString());
+ }
+
+ public NamingEnumeration listBindings(Name name) throws NamingException
+ {
+ return listBindings(name.toString());
+ }
+
+ public void bind(Name name, Object obj) throws NamingException
+ {
+ throw new OperationNotSupportedException();
+ }
+
+ public void bind(String name, Object obj) throws NamingException
+ {
+ throw new OperationNotSupportedException();
+ }
+
+ public void close() throws NamingException
+ {
+ // ignore
+ }
+
+ public Context createSubcontext(Name name) throws NamingException
+ {
+ throw new OperationNotSupportedException();
+ }
+
+ public Context createSubcontext(String name) throws NamingException
+ {
+ throw new OperationNotSupportedException();
+ }
+
+ public void destroySubcontext(Name name) throws NamingException
+ {
+ throw new OperationNotSupportedException();
+ }
+
+ public void destroySubcontext(String name) throws NamingException
+ {
+ throw new OperationNotSupportedException();
+ }
+
+ public String getNameInNamespace() throws NamingException
+ {
+ return nameInNamespace;
+ }
+
+ public NameParser getNameParser(Name name) throws NamingException
+ {
+ return nameParser;
+ }
+
+ public NameParser getNameParser(String name) throws NamingException
+ {
+ return nameParser;
+ }
+
+ public void rebind(Name name, Object obj) throws NamingException
+ {
+ throw new OperationNotSupportedException();
+ }
+
+ public void rebind(String name, Object obj) throws NamingException
+ {
+ throw new OperationNotSupportedException();
+ }
+
+ public void rename(Name oldName, Name newName) throws NamingException
+ {
+ throw new OperationNotSupportedException();
+ }
+
+ public void rename(String oldName, String newName) throws NamingException
+ {
+ throw new OperationNotSupportedException();
+ }
+
+ public void unbind(Name name) throws NamingException
+ {
+ throw new OperationNotSupportedException();
+ }
+
+ public void unbind(String name) throws NamingException
+ {
+ throw new OperationNotSupportedException();
+ }
+
+ private abstract class LocalNamingEnumeration implements NamingEnumeration
+ {
+ private Iterator i = bindings.entrySet().iterator();
+
+ public boolean hasMore() throws NamingException
+ {
+ return i.hasNext();
+ }
+
+ public boolean hasMoreElements()
+ {
+ return i.hasNext();
+ }
+
+ protected Map.Entry getNext()
+ {
+ return (Map.Entry) i.next();
+ }
+
+ public void close() throws NamingException
+ {
+ }
+ }
+
+ private class ListEnumeration extends LocalNamingEnumeration
+ {
+ public Object next() throws NamingException
+ {
+ return nextElement();
+ }
+
+ public Object nextElement()
+ {
+ Map.Entry entry = getNext();
+ return new NameClassPair((String) entry.getKey(), entry.getValue().getClass().getName());
+ }
+ }
+
+ private class ListBindingEnumeration extends LocalNamingEnumeration
+ {
+ public Object next() throws NamingException
+ {
+ return nextElement();
+ }
+
+ public Object nextElement()
+ {
+ Map.Entry entry = getNext();
+ return new Binding((String) entry.getKey(), entry.getValue());
+ }
+ }
+}
Propchange: incubator/qpid/trunk/qpid/java/client/src/org/apache/qpid/jndi/ReadOnlyContext.java
------------------------------------------------------------------------------
svn:eol-style = native
Added: incubator/qpid/trunk/qpid/java/client/test/src/org/apache/qpid/test/unit/jndi/PropertiesFileInitialContextFactoryTest.java
URL: http://svn.apache.org/viewvc/incubator/qpid/trunk/qpid/java/client/test/src/org/apache/qpid/test/unit/jndi/PropertiesFileInitialContextFactoryTest.java?view=auto&rev=466076
==============================================================================
--- incubator/qpid/trunk/qpid/java/client/test/src/org/apache/qpid/test/unit/jndi/PropertiesFileInitialContextFactoryTest.java (added)
+++ incubator/qpid/trunk/qpid/java/client/test/src/org/apache/qpid/test/unit/jndi/PropertiesFileInitialContextFactoryTest.java Fri Oct 20 04:46:56 2006
@@ -0,0 +1,110 @@
+/*
+ *
+ * Copyright (c) 2006 The Apache Software Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.qpid.test.unit.jndi;
+
+import junit.framework.JUnit4TestAdapter;
+import org.apache.qpid.client.AMQConnectionFactory;
+import org.apache.qpid.client.AMQQueue;
+import org.apache.qpid.client.AMQTopic;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+
+import javax.naming.Context;
+import javax.naming.InitialContext;
+import javax.naming.NamingException;
+import javax.naming.spi.InitialContextFactory;
+import java.util.Properties;
+
+public class PropertiesFileInitialContextFactoryTest
+{
+ InitialContextFactory contextFactory;
+ Properties _properties;
+
+ @Before
+ public void setupProperties()
+ {
+ _properties = new Properties();
+ _properties.put("java.naming.factory.initial", "org.apache.qpid.jndi.PropertiesFileInitialContextFactory");
+ _properties.put("connectionfactory.local", "amqp://guest:guest@clientid/testpath?brokerlist='vm://:1'");
+ _properties.put("queue.MyQueue", "example.MyQueue");
+ _properties.put("topic.ibmStocks", "stocks.nyse.ibm");
+ _properties.put("destination.direct", "direct://amq.direct//directQueue");
+ }
+
+ @Test
+ public void test()
+ {
+ Context ctx = null;
+ try
+ {
+ ctx = new InitialContext(_properties);
+ }
+ catch (NamingException ne)
+ {
+ Assert.fail("Error loading context:" + ne);
+ }
+
+ try
+ {
+ AMQConnectionFactory cf = (AMQConnectionFactory) ctx.lookup("local");
+ Assert.assertEquals("amqp://guest:guest@clientid/testpath?brokerlist='vm://:1'", cf.getConnectionURL().toString());
+ }
+ catch (NamingException ne)
+ {
+ Assert.fail("Unable to create Connection Factory:" + ne);
+ }
+
+ try
+ {
+ AMQQueue queue = (AMQQueue) ctx.lookup("MyQueue");
+ Assert.assertEquals("example.MyQueue", queue.getRoutingKey());
+ }
+ catch (NamingException ne)
+ {
+ Assert.fail("Unable to create queue:" + ne);
+ }
+
+ try
+ {
+ AMQTopic topic = (AMQTopic) ctx.lookup("ibmStocks");
+ Assert.assertEquals("stocks.nyse.ibm", topic.getTopicName());
+ }
+ catch (Exception ne)
+ {
+ Assert.fail("Unable to create topic:" + ne);
+ }
+
+ try
+ {
+ AMQQueue direct = (AMQQueue) ctx.lookup("direct");
+ Assert.assertEquals("directQueue", direct.getRoutingKey());
+ }
+ catch (NamingException ne)
+ {
+ Assert.fail("Unable to create direct destination:" + ne);
+ }
+
+
+ }
+
+ public static junit.framework.Test suite()
+ {
+ return new JUnit4TestAdapter(PropertiesFileInitialContextFactoryTest.class);
+ }
+}
Propchange: incubator/qpid/trunk/qpid/java/client/test/src/org/apache/qpid/test/unit/jndi/PropertiesFileInitialContextFactoryTest.java
------------------------------------------------------------------------------
svn:eol-style = native