You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@directory.apache.org by ps...@apache.org on 2005/03/30 04:15:50 UTC
svn commit: r159458 - in directory/naming/trunk/naming-core/src:
java/org/apache/naming/SelectorJNDIContext.java
test/org/apache/naming/SelectorJNDIContextTest.java
Author: psteitz
Date: Tue Mar 29 18:15:48 2005
New Revision: 159458
URL: http://svn.apache.org/viewcvs?view=rev&rev=159458
Log:
Added SelectorJNDIContext.
Added:
directory/naming/trunk/naming-core/src/java/org/apache/naming/SelectorJNDIContext.java
directory/naming/trunk/naming-core/src/test/org/apache/naming/SelectorJNDIContextTest.java
Added: directory/naming/trunk/naming-core/src/java/org/apache/naming/SelectorJNDIContext.java
URL: http://svn.apache.org/viewcvs/directory/naming/trunk/naming-core/src/java/org/apache/naming/SelectorJNDIContext.java?view=auto&rev=159458
==============================================================================
--- directory/naming/trunk/naming-core/src/java/org/apache/naming/SelectorJNDIContext.java (added)
+++ directory/naming/trunk/naming-core/src/java/org/apache/naming/SelectorJNDIContext.java Tue Mar 29 18:15:48 2005
@@ -0,0 +1,207 @@
+/*
+ * Copyright 2005 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.naming;
+
+import java.util.Hashtable;
+import javax.naming.CompositeName;
+import javax.naming.Context;
+import javax.naming.Name;
+import javax.naming.NamingException;
+import javax.naming.NamingEnumeration;
+
+/**
+ * Context implementation that delegates JNDI operations to named
+ * {@link NamingContext} instances, using names maintained in the
+ * {@link ContextBindings}. The {@link #getBoundContext} method, used to
+ * locate the appropriate Context instance for delegation, returns the context
+ * referred to by the most recently parsed jndi URL, or the context selected
+ * (or created) by the constructor, if no jndi URLs have been parsed.
+ *
+ * @version $Revision: 123167 $ $Date: 2003/11/30 05:22:15 $
+ */
+
+public class SelectorJNDIContext extends SelectorContext {
+
+ /**
+ * Namespace URL.
+ */
+ private static final String prefix = "jndi:";
+
+ /*
+ * Context named by the most recently resolved
+ * jndi URL.
+ */
+ private Context context = null;
+
+
+ /**
+ * Namespace URL length.
+ */
+ private static final int prefixLength = prefix.length();
+
+
+ /**
+ * Builds a selector jndi context using the given environment.
+ * <p>
+ * If the environment contains a name for the context (under the
+ * key <code>NamingContextFactory.Name</code>), the current context
+ * (the context used by jndi operations) is set to the named context. If
+ * env contains no name entry, the default name,
+ * <code>NamingContextFactory.DEFAULT_NAME</code> is assumed.
+ */
+ public SelectorJNDIContext(Hashtable env) {
+ super(env);
+ try {
+ context =new NamingContextFactory().getInitialContext(env);
+ } catch (NamingException ex) {
+ // Should never happen
+ }
+ }
+
+ /**
+ * Retrieves the named object.
+ *
+ * @param name the name of the object to look up
+ * @return the object bound to name
+ * @exception NamingException if a naming exception is encountered
+ */
+ public Object lookup(String name)
+ throws NamingException {
+ String parsedName = parseName(name);
+ return getBoundContext().lookup(parsedName);
+ }
+
+ /**
+ * Enumerates the names bound in the named context, along with the class
+ * names of objects bound to them.
+ *
+ * @param name the name of the context to list
+ * @return an enumeration of the names and class names of the bindings in
+ * this context. Each element of the enumeration is of type NameClassPair.
+ * @exception NamingException if a naming exception is encountered
+ */
+ public NamingEnumeration list(String name)
+ throws NamingException {
+ String parsedName = parseName(name);
+ return getBoundContext().list(parsedName);
+ }
+
+ /**
+ * Returns the bound context.
+ * <p>
+ * The bound context is the context named in the URL header of the most
+ * recently (successfully) parsed jndi URL. If no jndi URL has been
+ * parsed, the bound context is that set by the constructor. See
+ * {@link #SelectorJNDIContext(Hashtable)}.
+ *
+ * @return The bound context
+ */
+ protected Context getBoundContext()
+ throws NamingException {
+
+ return context;
+ }
+
+
+ protected void updateContext(String name) throws NamingException {
+ Hashtable env = new Hashtable();
+ env.put(NamingContextFactory.NAME, name);
+ context = new NamingContextFactory().getInitialContext(env);
+ }
+
+
+ /**
+ * If a "jndi:" URL header is present, the first component of the name
+ * following the URL header is assumed to be the name of a bound context
+ * in {@link ContextBindings}. For example, "jndi:global/config/host" names
+ * the "config/host" entry in the context bound under the name "global" in
+ * <code>ContextBindings</code>. If the header is present, but the named
+ * context does not exist, a <code>NamingException</code> is thrown.
+ * If the named context does exist, the current context is changed to refer
+ * to this context and the name is returned with the URL header and context
+ * name removed. In the example above, "config/host" would be returned
+ * (assuming "global" is bound to a context). If there is no header
+ * present, <code>name</code> is returned unchanged.
+ *
+ * @param name The name to parse
+ * @return the parsed name
+ * @exception NamingException if the jndi URL header is present, but the
+ * first component of the name following the header does not correspond to
+ * a bound context
+ */
+ protected String parseName(String name)
+ throws NamingException {
+
+ if ((name.startsWith(prefix))) {
+ String suffix = name.substring(prefixLength);
+ CompositeName cname = new CompositeName(suffix);
+ String contextName = cname.get(0);
+ Context ctx = ContextBindings.getContext(contextName);
+ if (ctx == null) {
+ throw new NamingException(sm.getString
+ ("contextBindings.unknownContext", contextName));
+ } else {
+ setContext(ctx);
+ }
+ return cname.getSuffix(1).toString();
+ } else {
+ return name;
+ }
+ }
+
+ /**
+ * If a "jndi:" URL header is present, the first component of the name
+ * following the URL header is assumed to be the name of a bound context
+ * in {@link ContextBindings}. For example, "jndi:global/config/host" names
+ * the "config/host" entry in the context bound under the name "global" in
+ * <code>ContextBindings</code>. If the header is present, but the named
+ * context does not exist, a <code>NamingException</code> is thrown.
+ * If the named context does exist, the current context is changed to refer
+ * to this context and the name is returned with the URL header and context
+ * name removed. In the example above, "config/host" would be returned
+ * (assuming "global" is bound to a context). If there is no header
+ * present, <code>name</code> is returned unchanged.
+ *
+ * @param name The name to parse
+ * @return The parsed name
+ * @exception NamingException if this is not an initial context and there
+ * is no "java:" URL header
+ */
+ protected Name parseName(Name name)
+ throws NamingException {
+
+ if ((!name.isEmpty())
+ && (name.get(0).equals(prefix))) {
+ updateContext(name.get(1));
+ return (name.getSuffix(1));
+ } else {
+ return name;
+ }
+ }
+
+ /**
+ * Sets underlying context
+ *
+ * @param context The context to set.
+ */
+ protected void setContext(Context context) {
+ this.context = context;
+ }
+
+}
+
Added: directory/naming/trunk/naming-core/src/test/org/apache/naming/SelectorJNDIContextTest.java
URL: http://svn.apache.org/viewcvs/directory/naming/trunk/naming-core/src/test/org/apache/naming/SelectorJNDIContextTest.java?view=auto&rev=159458
==============================================================================
--- directory/naming/trunk/naming-core/src/test/org/apache/naming/SelectorJNDIContextTest.java (added)
+++ directory/naming/trunk/naming-core/src/test/org/apache/naming/SelectorJNDIContextTest.java Tue Mar 29 18:15:48 2005
@@ -0,0 +1,124 @@
+/*
+ * Copyright 2005 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.naming;
+
+import java.util.Hashtable;
+
+import javax.naming.Context;
+import javax.naming.NamingException;
+import javax.naming.NameNotFoundException;
+
+import junit.framework.Test;
+import junit.framework.TestSuite;
+import junit.textui.TestRunner;
+
+
+/**
+ * Unit tests for basic ops on an {@link SelectorJNDIContext}.
+ *
+ * @version $Revision$ $Date$
+ */
+public class SelectorJNDIContextTest extends AbstractContextTest {
+
+ public SelectorJNDIContextTest(String name) {
+ super(name);
+ }
+
+ public static void main(String[] args) {
+ TestRunner.run(suite());
+ }
+
+ public static Test suite() {
+ TestSuite suite = new TestSuite(SelectorJNDIContextTest.class);
+ suite.setName("SelectorJNDIContext Tests");
+ return suite;
+ }
+
+ protected Context makeInitialContext() {
+ return new SelectorJNDIContext(new Hashtable());
+ }
+
+ public void testGetNameInNamespace() throws Exception {
+ assertEquals(SelectorContext.prefix, initialContext.getNameInNamespace());
+ }
+
+ public void testGetBoundContext() throws Exception {
+ // initially, context should be anonymous global context
+ assertEquals(
+ ContextBindings.getContext
+ (NamingContextFactory.DEFAULT_NAME).lookup
+ (firstContextName() + "/" + secondContextName() + "/" + firstBoundName()),
+ initialContext.lookup
+ (firstContextName() + "/" + secondContextName() + "/" + firstBoundName()));
+
+ /* Create a new named context and parse a jndi url so the selected
+ context changes. */
+ Context ctx = new NamingContext(new Hashtable(), "test");
+ ctx.createSubcontext("config");
+ ctx.bind("config/host", "jakarta.apache.org");
+ ContextBindings.bindContext("test", ctx);
+ assertEquals("jakarta.apache.org",
+ (String) initialContext.lookup("jndi:test/config/host"));
+
+ // Lookups with no URL headers go the named context
+ assertEquals("jakarta.apache.org",
+ (String) initialContext.lookup("config/host"));
+
+ // Reset back so teardown works
+ initialContext.lookup("jndi:" + NamingContextFactory.DEFAULT_NAME );
+ }
+
+ public void testConstructor() throws Exception {
+ // Create a named context
+ Context ctx = new NamingContext(new Hashtable(), "test2");
+ ctx.createSubcontext("config");
+ ctx.bind("config/host", "minotaur.apache.org");
+ ContextBindings.bindContext("test2", ctx);
+
+ /* Create a SelectorJNDIContext with the name of the bound context
+ in its environment */
+ Hashtable env = new Hashtable();
+ env.put(NamingContextFactory.NAME, "test2");
+ Context selectorJNDIContext = new SelectorJNDIContext(env);
+
+ // Lookups with no jndi URL header should use named context
+ assertEquals("minotaur.apache.org",
+ (String) selectorJNDIContext.lookup("config/host"));
+
+ // Now switch contexts using jndi URL
+ assertEquals(
+ ContextBindings.getContext
+ (NamingContextFactory.DEFAULT_NAME).lookup
+ (firstContextName() + "/" + secondContextName() + "/" + firstBoundName()),
+ selectorJNDIContext.lookup
+ ("jndi:" + NamingContextFactory.DEFAULT_NAME + "/" +
+ firstContextName() + "/" + secondContextName() + "/" + firstBoundName()));
+ }
+
+ public void testParseName() throws Exception {
+ try {
+ initialContext.lookup("jndi:" + NamingContextFactory.DEFAULT_NAME + "/boo");
+ } catch (NameNotFoundException ex) {
+ // expected
+ }
+ try {
+ initialContext.lookup("jndi:x");
+ } catch (NamingException ex) {
+ // expected
+ }
+ }
+
+}