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/02/13 00:30:34 UTC
svn commit: r153579 - in incubator/directory/naming/trunk:
naming-config/src/conf/ naming-config/src/java/org/apache/naming/config/
naming-config/src/test/ naming-config/src/test/org/apache/naming/config/
naming-core/src/java/org/apache/naming/
naming-core/src/test/org/apache/naming/ xdocs/
Author: psteitz
Date: Sat Feb 12 15:30:30 2005
New Revision: 153579
URL: http://svn.apache.org/viewcvs?view=rev&rev=153579
Log:
* Added support for named contexts to XMLConfigurator (DIRNAMING-12).
* Changed loadConfiguration to use update semantics
* Fixed bug in destroyContext method reported by Roland Berger.
* Added ContextUtils class of static methods to manipulate contexts.
* Added methods to ContextBindings to get bound context names, clear
context bindings and destroy bound contexts.
Added:
incubator/directory/naming/trunk/naming-config/src/test/test-jndi1.xml
incubator/directory/naming/trunk/naming-core/src/java/org/apache/naming/ContextUtils.java
incubator/directory/naming/trunk/naming-core/src/test/org/apache/naming/ContextUtilsTest.java
Modified:
incubator/directory/naming/trunk/naming-config/src/conf/naming.dtd
incubator/directory/naming/trunk/naming-config/src/java/org/apache/naming/config/Config.java
incubator/directory/naming/trunk/naming-config/src/java/org/apache/naming/config/XmlConfigurator.java
incubator/directory/naming/trunk/naming-config/src/test/org/apache/naming/config/XmlConfiguratorTest.java
incubator/directory/naming/trunk/naming-config/src/test/test-jndi.xml
incubator/directory/naming/trunk/naming-config/src/test/test-jndi2.xml
incubator/directory/naming/trunk/naming-core/src/java/org/apache/naming/ContextBindings.java
incubator/directory/naming/trunk/naming-core/src/test/org/apache/naming/ContextBindingsTest.java
incubator/directory/naming/trunk/xdocs/changes.xml
Modified: incubator/directory/naming/trunk/naming-config/src/conf/naming.dtd
URL: http://svn.apache.org/viewcvs/incubator/directory/naming/trunk/naming-config/src/conf/naming.dtd?view=diff&r1=153578&r2=153579
==============================================================================
--- incubator/directory/naming/trunk/naming-config/src/conf/naming.dtd (original)
+++ incubator/directory/naming/trunk/naming-config/src/conf/naming.dtd Sat Feb 12 15:30:30 2005
@@ -1,6 +1,6 @@
<!ELEMENT naming (context*)>
-<!ELEMENT context ((context|environment|resource)*)>
+<!ELEMENT context ((environment|resource)*)>
<!ATTLIST context
name CDATA #IMPLIED>
Modified: incubator/directory/naming/trunk/naming-config/src/java/org/apache/naming/config/Config.java
URL: http://svn.apache.org/viewcvs/incubator/directory/naming/trunk/naming-config/src/java/org/apache/naming/config/Config.java?view=diff&r1=153578&r2=153579
==============================================================================
--- incubator/directory/naming/trunk/naming-config/src/java/org/apache/naming/config/Config.java (original)
+++ incubator/directory/naming/trunk/naming-config/src/java/org/apache/naming/config/Config.java Sat Feb 12 15:30:30 2005
@@ -28,9 +28,11 @@
import javax.naming.CompositeName;
import javax.naming.InvalidNameException;
import javax.naming.StringRefAddr;
-
+
+import org.apache.commons.collections.map.UnmodifiableMap;
import org.apache.commons.lang.builder.ToStringBuilder;
-import org.apache.commons.lang.builder.ToStringStyle;
+import org.apache.commons.lang.builder.ToStringStyle;
+
import org.apache.naming.ResourceRef;
/**
@@ -48,7 +50,7 @@
{
/** list of context configurations */
private final Collection contextList = new LinkedList();
-
+
/**
* Adds a new Context configuration to the context list.
*
@@ -68,24 +70,27 @@
{
return Collections.unmodifiableCollection(contextList);
}
-
+
/**
- * Generates and returns a sorted list of all configured names.
+ * Generates and returns a map, keyed on context name, of sorted sets
+ * of all configured names.
*
- * @return configured names
+ * @return map of sets of configured names, keyed on context name.
* @throws InvalidNameException if an invalid name is encountered
*/
- public Set generateSortedSubcontextNameSet() throws InvalidNameException
+ public Map generateSortedSubcontextNameSet() throws InvalidNameException
{
- Set sortedSubcontextNameSet = new TreeSet();
+ Map sortedSubcontextNameMap = new HashMap();
for (Iterator i = contextList.iterator(); i.hasNext();)
- {
+ {
+ Set sortedSubcontextNameSet = new TreeSet();
Context context = (Context) i.next();
- context.addSubContextNames(sortedSubcontextNameSet);
+ context.addSubContextNames(sortedSubcontextNameSet);
+ sortedSubcontextNameMap.put(context.getName(), sortedSubcontextNameSet);
}
- return Collections.unmodifiableSet(sortedSubcontextNameSet);
+ return UnmodifiableMap.decorate(sortedSubcontextNameMap);
}
-
+
/**
* Returns a string representation of the context list.
*
@@ -94,22 +99,28 @@
public String toString()
{
return new ToStringBuilder(this, ToStringStyle.MULTI_LINE_STYLE)
- .append("contextList", contextList)
- .toString();
+ .append("contextList", contextList)
+ .toString();
}
}
-
+
/**
* Configuration for a Context. Contexts contain lists of
- * {@link org.apache.naming.config.Config$Environment} entries and
- * {@link org.apache.naming.config.Config$Resource} references.
+ * {@link org.apache.naming.config.Config$Environment} entries,
+ * {@link org.apache.naming.config.Config$Resource} references, and
+ * {@link org.apache.naming.config.Config$Link} links.
*/
public static final class Context
- {
- private String name;
+ {
+ /** External name of the context -- key in ContextBindings */
+ private String name;
+
+ /** Base name relative to which property and resource bindings are set up */
+ private String base;
+
private final Collection environmentList = new LinkedList();
private final Collection resourceList = new LinkedList();
-
+
/**
* Adds an Environment configuration to the environment list.
*
@@ -119,7 +130,7 @@
{
environmentList.add(environment);
}
-
+
/**
* Adds the subcontext names in this Context to the input set.
*
@@ -147,13 +158,13 @@
addSubContextNames(name, sortedSubcontextNameSet);
}
}
-
+
private void addSubContextNames(CompositeName name, Set sortedSubcontextNameSet) {
for (int j = 1; j <= name.size() - 1; j++) {
sortedSubcontextNameSet.add(name.getPrefix(j).toString());
}
}
-
+
/**
* Adds a Resource configuration to the resource list.
*
@@ -164,6 +175,7 @@
resourceList.add(resource);
}
+
/**
* Returns the environment list.
*
@@ -173,7 +185,7 @@
{
return Collections.unmodifiableCollection(environmentList);
}
-
+
/**
* Returns the name of this context.
*
@@ -183,7 +195,7 @@
{
return name;
}
-
+
/**
* Sets the name of this context.
*
@@ -193,7 +205,7 @@
{
this.name = name;
}
-
+
/**
* Returns the resource list.
*
@@ -203,7 +215,7 @@
{
return Collections.unmodifiableCollection(resourceList);
}
-
+
/**
* Returns a string representation of the name, environment list and
* resource list of this context.
@@ -213,13 +225,27 @@
public String toString()
{
return new ToStringBuilder(this, ToStringStyle.MULTI_LINE_STYLE)
- .append("name", name)
- .append("environmentList", environmentList)
- .append("resourceList", resourceList)
- .toString();
+ .append("name", name)
+ .append("environmentList", environmentList)
+ .append("resourceList", resourceList)
+ .toString();
}
+ /**
+ * @return Returns the base.
+ */
+ public String getBase() {
+ return base;
+ }
+
+ /**
+ * @param base The base to set.
+ */
+ public void setBase(String base) {
+ this.base = base;
+ }
+
}
-
+
/**
* Configuration for an Environment entry. Environment entries represent
* JNDI environment properties that take values that are primitive java
@@ -241,7 +267,7 @@
{
return name;
}
-
+
/**
* Sets the name of this environment.
*
@@ -251,7 +277,7 @@
{
this.name = name;
}
-
+
/**
* Returns the class name of this environment entry.
*
@@ -261,7 +287,7 @@
{
return type;
}
-
+
/**
* Sets the class name of this environment entry.
*
@@ -271,7 +297,7 @@
{
this.type = type;
}
-
+
/**
* Returns the value of this environment entry as a String.
*
@@ -281,7 +307,7 @@
{
return value;
}
-
+
/**
* Sets the (String) value of this environment entry.
*
@@ -291,7 +317,7 @@
{
this.value = value;
}
-
+
/**
* Returns the JNDI name, type and value of this environment entry as
* as String.
@@ -301,12 +327,12 @@
public String toString()
{
return new ToStringBuilder(this, ToStringStyle.MULTI_LINE_STYLE)
- .append("name", name)
- .append("type", type)
- .append("value", value)
- .toString();
+ .append("name", name)
+ .append("type", type)
+ .append("value", value)
+ .toString();
}
-
+
/**
* Tries to create an instance of type <code>this.type</code> using
* <code>this.value</code>.
@@ -360,19 +386,19 @@
return null;
}
}
-
+
/**
- * Configuration for an JNDI resource reference. Resource references
- * include the type of the resource, the parameters to be used in creating
- * the resource instance and the JNDI name of the resource as a string,
- * relative to the initial context.
- */
+ * Configuration for a JNDI resource reference. Resource references
+ * include the type of the resource, the parameters to be used in creating
+ * the resource instance and the JNDI name of the resource as a string,
+ * relative to the initial context.
+ */
public static final class Resource
{
private String name;
private String type;
private final Map parameters = new HashMap();
-
+
/**
* Adds a name-value pair to the parameters associated with this resource.
*
@@ -393,7 +419,7 @@
{
return name;
}
-
+
/**
* Sets the name of this resource.
*
@@ -403,7 +429,7 @@
{
this.name = name;
}
-
+
/**
* Returns the parameters associated with this resource as a Map.
* The keys of the map are the parameter names.
@@ -414,7 +440,7 @@
{
return parameters;
}
-
+
/**
* Returns the type of this resource.
*
@@ -424,7 +450,7 @@
{
return type;
}
-
+
/**
* Sets the type of this resource.
*
@@ -434,13 +460,13 @@
{
this.type = type;
}
-
- /**
- * Creates a {@link ResourceRef} based on the configuration
- * properties of this resource.
- *
- * @return ResourceRef instance.
- */
+
+ /**
+ * Creates a {@link ResourceRef} based on the configuration
+ * properties of this resource.
+ *
+ * @return ResourceRef instance.
+ */
public Object createValue()
//TODO: exceptions?
{
@@ -453,7 +479,7 @@
}
return ref;
}
-
+
/**
* Returns the name, type and parameter list as a String.
*
@@ -462,11 +488,11 @@
public String toString()
{
return new ToStringBuilder(this, ToStringStyle.MULTI_LINE_STYLE)
- .append("name", name)
- .append("type", type)
- .append("parameters", parameters)
- .toString();
- }
+ .append("name", name)
+ .append("type", type)
+ .append("parameters", parameters)
+ .toString();
+ }
}
}
Modified: incubator/directory/naming/trunk/naming-config/src/java/org/apache/naming/config/XmlConfigurator.java
URL: http://svn.apache.org/viewcvs/incubator/directory/naming/trunk/naming-config/src/java/org/apache/naming/config/XmlConfigurator.java?view=diff&r1=153578&r2=153579
==============================================================================
--- incubator/directory/naming/trunk/naming-config/src/java/org/apache/naming/config/XmlConfigurator.java (original)
+++ incubator/directory/naming/trunk/naming-config/src/java/org/apache/naming/config/XmlConfigurator.java Sat Feb 12 15:30:30 2005
@@ -1,5 +1,5 @@
/*
- * Copyright 1999,2004 The Apache Software Foundation.
+ * Copyright 2004 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.
@@ -14,19 +14,19 @@
* limitations under the License.
*/
-
package org.apache.naming.config;
import java.io.IOException;
import java.io.InputStream;
+import java.util.Hashtable;
import java.util.Iterator;
+import java.util.Map;
import java.util.Set;
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.Name;
-import javax.naming.NameClassPair;
-import javax.naming.NamingEnumeration;
+import javax.naming.NameAlreadyBoundException;
import javax.naming.NamingException;
import org.apache.commons.digester.Digester;
@@ -35,14 +35,28 @@
import org.xml.sax.SAXException;
+import org.apache.naming.ContextBindings;
+import org.apache.naming.ContextUtils;
+import org.apache.naming.NamingContextFactory;
+
/**
* Configure an in-memory JNDI implementation using an XML configuration file.
+ * <p>
+ * Multiple named contexts can be configured, and names configured in the file
+ * can be made relative to a base name. Use the "base" attribute of the context
+ * element in the xml config to specify a base name and use the "name" attribute
+ * to specify an external name for the context, which will be its key in
+ * {@link org.apache.naming.ContextBindings}. Configurations added using
+ * {@link #loadConfiguration} add / update data for contexts already defined.
+ * To destroy contexts already defined, use either
+ * {@link #destroyInitialContext()}, which destroys the "anonymous" context
+ * (what new InitialContext() returns); or {@link #destroyAll}, which destroys
+ * all defined contexts (named or "anonymous").
*
* @author <a href="brett@apache.org">Brett Porter</a>
* @version $Id: XmlConfigurator.java,v 1.2 2003/12/01 02:02:45 brett Exp $
*/
-public class XmlConfigurator
-{
+public class XmlConfigurator {
private static final String COMP_CONTEXT_NAME = "java:comp";
private static final String ENV_CONTEXT_NAME = "env";
private static final String ROOT_ELEMENT = "naming";
@@ -55,59 +69,64 @@
private static final Log LOG = LogFactory.getLog(XmlConfigurator.class);
/**
- * Sets up initial context using
- * <code>org.apache.naming.java.javaURLContextFactory</code>.
+ * Sets up initial context using <code>org.apache.naming.NamingContextFactory</code>.
* <p>
* Also creates "env" subcontext in "java:comp" namespace.
*
* @throws NamingException if a NamingException occurs.
*/
- public static synchronized void setupInitialContext() throws NamingException {
- System.setProperty(Context.INITIAL_CONTEXT_FACTORY, "org.apache.naming.java.javaURLContextFactory");
- System.setProperty(Context.URL_PKG_PREFIXES, "org.apache.naming");
-
+ public static synchronized void setupInitialContext()
+ throws NamingException {
+ setSystemProperties();
Context initialContext = new InitialContext();
- envContext = initialContext.createSubcontext(COMP_CONTEXT_NAME).createSubcontext(ENV_CONTEXT_NAME);
+ envContext = initialContext.createSubcontext(
+ COMP_CONTEXT_NAME).createSubcontext(ENV_CONTEXT_NAME);
}
/**
- * Destroys initial context.
- * <p>
- * Invokes <code>Context.destroySubcontext(Name)</code> only on top-level
- * subcontexts.
+ * Destroys "anonymous" initial context, destoying subcontexts recursively.
*
- * @throws NamingException if a NamingException occurs.
+ * @throws NamingException if a NamingException occurs
*/
- public static synchronized void destroyInitialContext() throws NamingException {
- Context initialContext = new InitialContext();
- NamingEnumeration contexts = initialContext.list("");
- while (contexts.hasMore()) {
- initialContext.destroySubcontext(((NameClassPair) contexts.next()).getName());
- }
- envContext = null;
- initialContext = null;
+ public static synchronized void destroyInitialContext()
+ throws NamingException {
+ ContextUtils.destroyInitialContext();
}
/**
- * Loads xml configuration data from <code>inputFile</code> into initial context.
+ * Destroys all named contexts as well as "anonymous" context.
*
- * @param inputFile input xml configuration file
- * @throws NamingException if a NamingException occurs.
- * @throws ParseException if an error occurs parsing the configuration file.
+ * @throws NamingException if a naming exception occurs
*/
- public static synchronized void loadConfiguration(InputStream inputFile) throws NamingException, ParseException {
- if (envContext == null)
- {
- setupInitialContext();
- }
+ public static synchronized void destroyAll() throws NamingException {
+ ContextBindings.destroyBoundContexts();
+ ContextUtils.destroyInitialContext();
+ }
+
+ /**
+ * Sets System JNDI properties.
+ */
+ protected static synchronized void setSystemProperties() {
+ System.setProperty(
+ Context.INITIAL_CONTEXT_FACTORY,
+ "org.apache.naming.NamingContextFactory");
+ System.setProperty(Context.URL_PKG_PREFIXES, "org.apache.naming");
+ }
+ /**
+ * Parses input file, returning a <code>Config.Naming</code> structure.
+ *
+ * @param inputFile file to be parsed
+ * @return Config.Naming representing the config data in the file
+ * @throws ParseException if an error occurs parsing the file
+ */
+ protected static synchronized Config.Naming parseFile(
+ InputStream inputFile) throws ParseException {
Digester digester = new Digester();
-// TODO: string constants
digester.addObjectCreate(ROOT_ELEMENT, Config.Naming.class);
digester.addObjectCreate(CONTEXT_ELEMENT, Config.Context.class);
digester.addSetProperties(CONTEXT_ELEMENT);
digester.addSetNext(CONTEXT_ELEMENT, "addContext");
- // TODO: handle context inside context?
digester.addObjectCreate(ENV_ELEMENT, Config.Environment.class);
digester.addSetProperties(ENV_ELEMENT);
digester.addSetNext(ENV_ELEMENT, "addEnvironment");
@@ -118,64 +137,138 @@
digester.addCallParam(RES_PARAM_ELEMENT + "/name", 0);
digester.addCallParam(RES_PARAM_ELEMENT + "/value", 1);
- try
- {
+ try {
Config.Naming naming = (Config.Naming) digester.parse(inputFile);
if (naming == null) {
- throw new ParseException("Unable to find root element '" + ROOT_ELEMENT + "'");
+ throw new ParseException(
+ "Unable to find root element '" + ROOT_ELEMENT + "'");
}
if (LOG.isDebugEnabled()) {
LOG.debug("XML configuration loaded: " + naming.toString());
}
+ return naming;
+ } catch (IOException e) {
+ throw new ParseException("Error reading configuration file", e);
+ } catch (SAXException e) {
+ throw new ParseException("Error reading configuration file", e);
+ }
+ }
+ /**
+ * Creates naming contexts based on the configuration data in the
+ * input <code>Config.Naming</code> structure.
+ * <p>
+ * Uses update semantics -- i.e., contexts / entries that already exist are
+ * updated with the data in the input configuration.
+ *
+ * @param naming Config.Naming structure containing the context
+ * configuration data
+ * @throws NamingException if a NamingException occurs
+ */
+ protected static synchronized void makeContexts(Config.Naming naming)
+ throws NamingException {
+
+ // Get the map of sets of sorted context names, keyed on external name
+ Map sortedContextNames = naming.generateSortedSubcontextNameSet();
+
+ // Create named contexts
+ Hashtable env = new Hashtable();
+ for (Iterator i = naming.getContextList().iterator(); i.hasNext();) {
+ env.clear();
+ Config.Context ctx = (Config.Context) i.next();
+ Context jndiCtx = envContext;
+ if (ctx.getName() != null) {
+ env.put(NamingContextFactory.NAME, ctx.getName());
+ } else {
+ env.put( NamingContextFactory.NAME,
+ NamingContextFactory.DEFAULT_NAME);
+ }
- for (Iterator i = naming.getContextList().iterator(); i.hasNext();)
- {
- Config.Context ctx = (Config.Context) i.next();
- Context jndiCtx = envContext;
- if (ctx.getName() != null)
- {
- destroyInitialContext();
- Context initialContext = new InitialContext();
- Name nm = initialContext.getNameParser("").parse(ctx.getName());
+ if (ctx.getBase() != null) {
+ Context initialContext = new InitialContext(env);
+ Name nm = initialContext.getNameParser("").parse(ctx.getBase());
+ try {
envContext = initialContext.createSubcontext(nm.get(0));
- jndiCtx = envContext;
- for (int k = 1; k < nm.size(); k++) {
+ } catch (NameAlreadyBoundException e) {
+ envContext = (Context) initialContext.lookup(nm.get(0));
+ }
+ jndiCtx = envContext;
+ for (int k = 1; k < nm.size(); k++) {
+ try {
jndiCtx = jndiCtx.createSubcontext(nm.get(k));
+ } catch (NameAlreadyBoundException e) {
+ jndiCtx = (Context) jndiCtx.lookup(nm.get(k));
}
}
- precreateSubcontextTree(jndiCtx, naming.generateSortedSubcontextNameSet());
-
- for (Iterator j = ctx.getEnvironmentList().iterator(); j.hasNext();)
- {
- Config.Environment e = (Config.Environment) j.next();
- jndiCtx.rebind(e.getName(), e.createValue());
+ } else {
+ Context initialContext = new InitialContext(env);
+ try {
+ envContext = initialContext.createSubcontext(
+ COMP_CONTEXT_NAME).createSubcontext(
+ ENV_CONTEXT_NAME);
+ } catch (NameAlreadyBoundException e) {
+ envContext = (Context) initialContext.lookup(
+ COMP_CONTEXT_NAME + "/" + ENV_CONTEXT_NAME);
}
+ jndiCtx = envContext;
+ }
- for (Iterator j = ctx.getResourceList().iterator(); j.hasNext();)
- {
- Config.Resource r = (Config.Resource) j.next();
- jndiCtx.bind(r.getName(), r.createValue());
- }
+ precreateSubcontextTree( jndiCtx,
+ (Set) sortedContextNames.get( ctx.getName()));
+
+ for (Iterator j = ctx.getEnvironmentList().iterator();
+ j.hasNext();) {
+ Config.Environment e = (Config.Environment) j.next();
+ jndiCtx.rebind(e.getName(), e.createValue());
+ }
+
+ for (Iterator j = ctx.getResourceList().iterator(); j.hasNext();) {
+ Config.Resource r = (Config.Resource) j.next();
+ jndiCtx.rebind(r.getName(), r.createValue());
}
}
- catch (IOException e)
- {
- throw new ParseException("Error reading configuration file", e);
- }
- catch (SAXException e)
- {
- throw new ParseException("Error reading configuration file", e);
- }
}
- private static void precreateSubcontextTree(Context ctx, Set sortedSubcontextNameSet) throws NamingException
- {
- // TODO: don't recreate
- for (Iterator i = sortedSubcontextNameSet.iterator(); i.hasNext();)
- {
+ /**
+ * Loads xml configuration data from <code>inputFile</code>. Uses update
+ * semantics -- i.e., does not clear and create new context(s) and
+ * bindings, but adds to current definitions, overwriting previous
+ * configuration when contexts or bindings already exist. To clear existing
+ * configuration, use {@link #destroyInitialContext} or {@link #destroyAll}.
+ *
+ * @param inputFile input xml configuration file
+ * @throws NamingException if a NamingException occurs.
+ * @throws ParseException if an error occurs parsing the configuration file.
+ */
+ public static synchronized void loadConfiguration(InputStream inputFile)
+ throws NamingException, ParseException {
+ // Set system properties
+ setSystemProperties();
+ // Parse file and create contexts
+ makeContexts(parseFile(inputFile));
+ }
+
+ /**
+ * Creates all subcontexts named in <code>sortedSubcontextNameSet</code>.
+ * Some / all subcontexts may already exist. NamingException is only thrown
+ * if the names are invalid or required intermediary contexts are missing.
+ *
+ * @param ctx context
+ * @param sortedSubcontextNameSet set of names to Create
+ * @throws NamingException if names are invalid required intermediate
+ * contexts are missing
+ */
+ private static void precreateSubcontextTree(
+ Context ctx,
+ Set sortedSubcontextNameSet)
+ throws NamingException {
+ for (Iterator i = sortedSubcontextNameSet.iterator(); i.hasNext();) {
String name = (String) i.next();
- ctx.createSubcontext(name);
+ try {
+ ctx.createSubcontext(name);
+ } catch (NameAlreadyBoundException e) {
+ // ignore -- already created
+ }
}
}
Modified: incubator/directory/naming/trunk/naming-config/src/test/org/apache/naming/config/XmlConfiguratorTest.java
URL: http://svn.apache.org/viewcvs/incubator/directory/naming/trunk/naming-config/src/test/org/apache/naming/config/XmlConfiguratorTest.java?view=diff&r1=153578&r2=153579
==============================================================================
--- incubator/directory/naming/trunk/naming-config/src/test/org/apache/naming/config/XmlConfiguratorTest.java (original)
+++ incubator/directory/naming/trunk/naming-config/src/test/org/apache/naming/config/XmlConfiguratorTest.java Sat Feb 12 15:30:30 2005
@@ -19,13 +19,18 @@
import java.sql.Connection;
import java.sql.ResultSet;
-import java.sql.Statement;
+import java.sql.Statement;
+
+import java.util.Hashtable;
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.sql.DataSource;
-import junit.framework.TestCase;
+import junit.framework.TestCase;
+
+import org.apache.naming.ContextBindings;
+import org.apache.naming.NamingContextFactory;
/**
* Test case for the XML configuration methods, testing environment entries
@@ -70,18 +75,39 @@
/**
* Test for correctly configured environment entries.
+ *
* @throws Exception as tests do
*/
public void testEnvironment() throws Exception {
XmlConfigurator.loadConfiguration(getClass().getResourceAsStream("/test-jndi.xml"));
- checkEnvironment(DEFAULT_ROOT);
+ checkEnvironment(DEFAULT_ROOT, new InitialContext());
XmlConfigurator.destroyInitialContext();
+
XmlConfigurator.loadConfiguration(getClass().getResourceAsStream("/test-jndi2.xml"));
- checkEnvironment(ALT_ROOT);
+ checkEnvironment(ALT_ROOT, new InitialContext());
+
+ XmlConfigurator.loadConfiguration(getClass().getResourceAsStream("/test-jndi1.xml"));
+ // "named" global context has same environment entries -- verify
+ Hashtable env = new Hashtable();
+ env.put(Context.INITIAL_CONTEXT_FACTORY,
+ "org.apache.naming.NamingContextFactory");
+ env.put(Context.URL_PKG_PREFIXES, "org.apache.naming");
+ env.put(NamingContextFactory.NAME, "global"); //name attribute
+ InitialContext ctx = new InitialContext(env);
+ checkEnvironment(DEFAULT_ROOT, new InitialContext(env));
+
+ // "anonymous" context entries should be overwritten now
+ ctx = new InitialContext();
+ Context envCtx = (Context) ctx.lookup(ALT_ROOT);
+ String host = (String) envCtx.lookup("config/host");
+ Integer port = (Integer) envCtx.lookup("config/port");
+ assertEquals("Check host", "www.jakarta.org", host);
+ assertEquals("Check port", new Integer(85), port);
+
+ ContextBindings.destroyBoundContexts();
}
- protected void checkEnvironment(String root) throws Exception {
- Context ctx = new InitialContext();
+ protected void checkEnvironment(String root, Context ctx) throws Exception {
Context env = (Context) ctx.lookup(root);
String host = (String) env.lookup("config/host");
Integer port = (Integer) env.lookup("config/port");
@@ -106,7 +132,8 @@
*/
public void testDuplicateSubcontextName() throws Exception{
XmlConfigurator.loadConfiguration(getClass().getResourceAsStream("/test-jndi.xml"));
- checkDuplicateSubcontextName(DEFAULT_ROOT);
+ checkDuplicateSubcontextName(DEFAULT_ROOT);
+ XmlConfigurator.destroyInitialContext();
}
protected void checkDuplicateSubcontextName(String root) throws Exception {
@@ -125,14 +152,23 @@
*/
public void testJdbc() throws Exception {
XmlConfigurator.loadConfiguration(getClass().getResourceAsStream("/test-jndi.xml"));
- checkJdbc(DEFAULT_ROOT);
+ checkJdbc(DEFAULT_ROOT, new InitialContext());
XmlConfigurator.destroyInitialContext();
XmlConfigurator.loadConfiguration(getClass().getResourceAsStream("/test-jndi2.xml"));
- checkJdbc(ALT_ROOT);
+ checkJdbc(ALT_ROOT, new InitialContext());
+ XmlConfigurator.destroyInitialContext();
+ XmlConfigurator.loadConfiguration(getClass().getResourceAsStream("/test-jndi1.xml"));
+ checkJdbc(ALT_ROOT, new InitialContext());
+ Hashtable env = new Hashtable();
+ env.put(Context.INITIAL_CONTEXT_FACTORY,
+ "org.apache.naming.NamingContextFactory");
+ env.put(Context.URL_PKG_PREFIXES, "org.apache.naming");
+ env.put(NamingContextFactory.NAME, "global"); //name attribute
+ checkJdbc(DEFAULT_ROOT + "/global", new InitialContext(env));
+ ContextBindings.destroyBoundContexts();
}
- protected void checkJdbc(String root) throws Exception {
- Context ctx = new InitialContext();
+ protected void checkJdbc(String root, Context ctx) throws Exception {
Context env = (Context) ctx.lookup(root);
DataSource ds = (DataSource) env.lookup("jdbc/pool");
Connection con = null;
Modified: incubator/directory/naming/trunk/naming-config/src/test/test-jndi.xml
URL: http://svn.apache.org/viewcvs/incubator/directory/naming/trunk/naming-config/src/test/test-jndi.xml?view=diff&r1=153578&r2=153579
==============================================================================
--- incubator/directory/naming/trunk/naming-config/src/test/test-jndi.xml (original)
+++ incubator/directory/naming/trunk/naming-config/src/test/test-jndi.xml Sat Feb 12 15:30:30 2005
@@ -1,11 +1,5 @@
<naming>
<context>
- <context name="sub/context">
-
- <environment name="config/host" value="jakarta.apache.org" type="java.lang.String" />
- <environment name="config/port" value="8000" type="java.lang.Integer" />
- </context>
-
<environment name="config/host" value="www.apache.org" type="java.lang.String" />
<environment name="config/mytruebool" value="true" type="java.lang.Boolean" />
<environment name="config/myfalsebool" value="false" type="java.lang.Boolean" />
Added: incubator/directory/naming/trunk/naming-config/src/test/test-jndi1.xml
URL: http://svn.apache.org/viewcvs/incubator/directory/naming/trunk/naming-config/src/test/test-jndi1.xml?view=auto&rev=153579
==============================================================================
--- incubator/directory/naming/trunk/naming-config/src/test/test-jndi1.xml (added)
+++ incubator/directory/naming/trunk/naming-config/src/test/test-jndi1.xml Sat Feb 12 15:30:30 2005
@@ -0,0 +1,57 @@
+<naming>
+ <!--
+ Anonymous context with base specified, different environment values
+ from test-jndi2. Loading after jnti2 should overwrite environment entries.
+ -->
+ <context base="alt/root/context">
+ <environment name="config/host" value="www.jakarta.org" type="java.lang.String" />
+ <environment name="config/port" value="85" type="java.lang.Integer" />
+ <resource name="jdbc/pool" type="javax.sql.DataSource">
+ <parameter>
+ <name>driverClassName</name>
+ <value>org.hsqldb.jdbcDriver</value>
+ </parameter>
+ <parameter>
+ <name>url</name>
+ <value>jdbc:hsqldb:target/hsqldb</value>
+ </parameter>
+ <parameter>
+ <name>username</name>
+ <value>sa</value>
+ </parameter>
+ <parameter>
+ <name>password</name>
+ <value></value>
+ </parameter>
+ </resource>
+ </context>
+ <!--
+ Add another named context, default root, same environment entries
+ as jndi2.
+ -->
+ <context name="global" >
+ <environment name="config/host" value="www.apache.org" type="java.lang.String" />
+ <environment name="config/mytruebool" value="true" type="java.lang.Boolean" />
+ <environment name="config/myfalsebool" value="false" type="java.lang.Boolean" />
+ <environment name="config/port" value="80" type="java.lang.Integer" />
+ <environment name="jdbc/config/pool/user" value="dbuser" type="java.lang.String" />
+ <resource name="global/jdbc/pool" type="javax.sql.DataSource">
+ <parameter>
+ <name>driverClassName</name>
+ <value>org.hsqldb.jdbcDriver</value>
+ </parameter>
+ <parameter>
+ <name>url</name>
+ <value>jdbc:hsqldb:target/hsqldb</value>
+ </parameter>
+ <parameter>
+ <name>username</name>
+ <value>sa</value>
+ </parameter>
+ <parameter>
+ <name>password</name>
+ <value></value>
+ </parameter>
+ </resource>
+ </context>
+</naming>
Modified: incubator/directory/naming/trunk/naming-config/src/test/test-jndi2.xml
URL: http://svn.apache.org/viewcvs/incubator/directory/naming/trunk/naming-config/src/test/test-jndi2.xml?view=diff&r1=153578&r2=153579
==============================================================================
--- incubator/directory/naming/trunk/naming-config/src/test/test-jndi2.xml (original)
+++ incubator/directory/naming/trunk/naming-config/src/test/test-jndi2.xml Sat Feb 12 15:30:30 2005
@@ -1,5 +1,5 @@
<naming>
- <context name="alt/root/context">
+ <context base="alt/root/context">
<environment name="config/host" value="www.apache.org" type="java.lang.String" />
<environment name="config/mytruebool" value="true" type="java.lang.Boolean" />
<environment name="config/myfalsebool" value="false" type="java.lang.Boolean" />
Modified: incubator/directory/naming/trunk/naming-core/src/java/org/apache/naming/ContextBindings.java
URL: http://svn.apache.org/viewcvs/incubator/directory/naming/trunk/naming-core/src/java/org/apache/naming/ContextBindings.java?view=diff&r1=153578&r2=153579
==============================================================================
--- incubator/directory/naming/trunk/naming-core/src/java/org/apache/naming/ContextBindings.java (original)
+++ incubator/directory/naming/trunk/naming-core/src/java/org/apache/naming/ContextBindings.java Sat Feb 12 15:30:30 2005
@@ -17,7 +17,10 @@
package org.apache.naming;
+import java.util.Collections;
+import java.util.Enumeration;
import java.util.Hashtable;
+import java.util.Set;
import javax.naming.NamingException;
import javax.naming.Context;
@@ -498,6 +501,35 @@
return false;
}
-
+ /**
+ * Returns the names of bound contexts as an unmodifiable set.
+ *
+ * @return names of bound contexts
+ */
+ public static Set getContextNames() {
+ return Collections.unmodifiableSet(contextNameBindings.keySet());
+ }
+
+ /**
+ * Clears context bindings.
+ *
+ */
+ public static synchronized void clearContextBindings() {
+ contextNameBindings.clear();
+ }
+
+ /**
+ * Destroys all bound contexts and removes bindings.
+ *
+ * @throws NamingException
+ */
+ public static synchronized void destroyBoundContexts() throws NamingException {
+ Enumeration contexts = contextNameBindings.elements();
+ while (contexts.hasMoreElements()) {
+ ContextUtils.destroyContext((Context) contexts.nextElement());
+ }
+ clearContextBindings();
+ }
+
}
Added: incubator/directory/naming/trunk/naming-core/src/java/org/apache/naming/ContextUtils.java
URL: http://svn.apache.org/viewcvs/incubator/directory/naming/trunk/naming-core/src/java/org/apache/naming/ContextUtils.java?view=auto&rev=153579
==============================================================================
--- incubator/directory/naming/trunk/naming-core/src/java/org/apache/naming/ContextUtils.java (added)
+++ incubator/directory/naming/trunk/naming-core/src/java/org/apache/naming/ContextUtils.java Sat Feb 12 15:30:30 2005
@@ -0,0 +1,119 @@
+/*
+ * 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.ArrayList;
+import java.util.List;
+import java.util.Hashtable;
+
+import javax.naming.Binding;
+import javax.naming.Context;
+import javax.naming.ContextNotEmptyException;
+import javax.naming.InitialContext;
+import javax.naming.NamingEnumeration;
+import javax.naming.NamingException;
+import javax.naming.NotContextException;
+
+import org.apache.naming.ContextBindings;
+import org.apache.naming.NamingContextFactory;
+
+/**
+ * Collection of static methods that manipulate naming contexts.
+ */
+public class ContextUtils {
+
+ /*
+ * Prevent instantiation.
+ */
+ private ContextUtils() {}
+
+ /**
+ * Destroys a context, recursively destroying all subcontexts.
+ * Does not attempt to destroy foreign contexts named by link references.
+ *
+ * @param context context to destroy recursively
+ * @throws NamingException
+ */
+ public static synchronized void destroyContext(Context context)
+ throws NamingException {
+ NamingEnumeration contexts = context.listBindings("");
+ List bindings = new ArrayList();
+ while (contexts.hasMore()) {
+ bindings.add(contexts.next());
+ }
+ for (int i =0; i < bindings.size(); i++) {
+ Binding binding = (Binding) bindings.get(i);
+ Object obj = binding.getObject();
+ String name = binding.getName();
+ try {
+ context.destroySubcontext(name);
+ } catch (NotContextException ex) {
+ context.unbind(name);
+ } catch (ContextNotEmptyException e) {
+ destroyContext((Context) obj);
+ }
+ }
+ }
+
+ /**
+ * Destroys the context with the given external name and removes it from
+ * the context bindings table.
+ *
+ * @param name external name (i.e. key in {@link ContextBindings} of the
+ * context to destroy
+ * @throws NamingException
+ */
+ public static synchronized void destroyContext(String name)
+ throws NamingException {
+ Context context = ContextBindings.getContext(name);
+ if (context == null) {
+ throw new NamingException("Named context not found");
+ }
+ destroyContext(context);
+ ContextBindings.unbindContext(name);
+ }
+
+ /**
+ * Destroys initial context, destoying subcontexts recursively.
+ *
+ * @throws NamingException if a NamingException occurs
+ */
+ public static synchronized void destroyInitialContext() throws NamingException {
+ Context initialContext = new InitialContext();
+ destroyContext(initialContext);
+ ContextBindings.unbindContext(NamingContextFactory.DEFAULT_NAME);
+ }
+
+ /**
+ * Destroys the initial context based on the given environment, destoying
+ * subcontexts recursively. Removes context binding if environment contains
+ * the NamingContextFactory.NAME key.
+ *
+ * @throws NamingException if a NamingException occurs
+ */
+ public static synchronized void destroyInitialContext(Hashtable env)
+ throws NamingException {
+ Context initialContext = new InitialContext(env);
+ destroyContext(initialContext);
+ if (env.containsKey(NamingContextFactory.NAME)) {
+ ContextBindings.unbindContext(env.get(NamingContextFactory.NAME));
+ }
+ }
+
+}
+
Modified: incubator/directory/naming/trunk/naming-core/src/test/org/apache/naming/ContextBindingsTest.java
URL: http://svn.apache.org/viewcvs/incubator/directory/naming/trunk/naming-core/src/test/org/apache/naming/ContextBindingsTest.java?view=diff&r1=153578&r2=153579
==============================================================================
--- incubator/directory/naming/trunk/naming-core/src/test/org/apache/naming/ContextBindingsTest.java (original)
+++ incubator/directory/naming/trunk/naming-core/src/test/org/apache/naming/ContextBindingsTest.java Sat Feb 12 15:30:30 2005
@@ -16,8 +16,11 @@
package org.apache.naming;
import java.util.Hashtable;
+import java.util.HashSet;
+import java.util.Set;
import javax.naming.Context;
+import javax.naming.InitialContext;
import javax.naming.NamingException;
import junit.framework.Test;
@@ -29,7 +32,7 @@
/**
* Unit tests for {@link ContextBindings}.
*
- * @version $Revision: 1.2 $ $Date: 2003/11/30 05:36:07 $
+ * @version $Revision$ $Date: 2003/11/30 05:36:07 $
*/
public class ContextBindingsTest extends TestCase {
@@ -62,10 +65,7 @@
public void tearDown() throws Exception {
ContextAccessController.unsetSecurityToken(contextName, testToken1);
ContextAccessController.unsetSecurityToken(subName, testToken2);
- ContextBindings.unbindContext(contextName);
- ContextBindings.unbindContext(subName);
- testContext.destroySubcontext("env:comp");
- testContext = null;
+ ContextBindings.destroyBoundContexts();
}
public void testNameBindings() throws Exception {
@@ -210,4 +210,49 @@
ContextBindings.unbindClassLoader(contextName, testToken1);
assertFalse(ContextBindings.isClassLoaderBound());
}
+
+ protected void makeBindings() throws Exception {
+ // "Factory bound"
+ Hashtable env = new Hashtable();
+ env.put(Context.INITIAL_CONTEXT_FACTORY,
+ "org.apache.naming.NamingContextFactory");
+ env.put(Context.URL_PKG_PREFIXES, "org.apache.naming");
+ env.put(NamingContextFactory.NAME, "test1");
+ Context context1 = new InitialContext(env);
+
+ // Explicit binding
+ ContextBindings.bindContext("test2", testContext); // created in setup
+ }
+
+ public void testGetContextNames() throws Exception {
+ ContextBindings.clearContextBindings();
+ Set names = ContextBindings.getContextNames();
+ assertTrue(names.isEmpty());
+ makeBindings();
+ names = ContextBindings.getContextNames();
+ HashSet expected = new HashSet();
+ expected.add("test1");
+ expected.add("test2");
+ assertEquals(expected, names);
+ // Verify unmodifiable
+ try {
+ names.remove("test1");
+ fail("Expecting UnsupportedOperationException");
+ } catch (UnsupportedOperationException e) {
+ // Expected
+ }
+ try {
+ names.add("test3");
+ fail("Expecting UnsupportedOperationException");
+ } catch (UnsupportedOperationException e) {
+ // Expected
+ }
+ }
+
+ public void testDestroyBoundContexts() throws Exception {
+ makeBindings();
+ ContextBindings.destroyBoundContexts();
+ assertTrue(ContextBindings.getContextNames().isEmpty());
+ assertFalse(testContext.list("").hasMoreElements());
+ }
}
Added: incubator/directory/naming/trunk/naming-core/src/test/org/apache/naming/ContextUtilsTest.java
URL: http://svn.apache.org/viewcvs/incubator/directory/naming/trunk/naming-core/src/test/org/apache/naming/ContextUtilsTest.java?view=auto&rev=153579
==============================================================================
--- incubator/directory/naming/trunk/naming-core/src/test/org/apache/naming/ContextUtilsTest.java (added)
+++ incubator/directory/naming/trunk/naming-core/src/test/org/apache/naming/ContextUtilsTest.java Sat Feb 12 15:30:30 2005
@@ -0,0 +1,140 @@
+/*
+ * 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.InitialContext;
+import javax.naming.NamingException;
+
+import junit.framework.Test;
+import junit.framework.TestSuite;
+import junit.textui.TestRunner;
+import junit.framework.TestCase;
+
+
+/**
+ * Unit tests for {@link ContextUtils}.
+ *
+ * @version $Revision: 56478 $ $Date: 2003/11/30 05:36:07 $
+ */
+public class ContextUtilsTest extends TestCase {
+
+ public ContextUtilsTest(String name) {
+ super(name);
+ }
+
+ public static void main(String[] args) {
+ TestRunner.run(suite());
+ }
+
+ public static Test suite() {
+ TestSuite suite = new TestSuite(ContextUtilsTest.class);
+ suite.setName("ContextUils Tests");
+ return suite;
+ }
+
+ public void setUp() throws Exception {
+ }
+
+ public void tearDown() throws Exception {
+ }
+
+ public void testDestroyInitialContext() throws Exception {
+ // First try with named context
+ Hashtable env = new Hashtable();
+ env.put(NamingContextFactory.NAME, "test");
+ env.put(Context.INITIAL_CONTEXT_FACTORY,
+ "org.apache.naming.NamingContextFactory");
+ env.put(Context.URL_PKG_PREFIXES, "org.apache.naming");
+ checkInitialContext(env);
+
+ // Anonymous
+ env.clear();
+ env.put(Context.INITIAL_CONTEXT_FACTORY,
+ "org.apache.naming.NamingContextFactory");
+ env.put(Context.URL_PKG_PREFIXES, "org.apache.naming");
+ checkInitialContext(env);
+ }
+
+ public void testDestroyContext() throws Exception {
+ Hashtable env = new Hashtable();
+
+ // Anonymous
+ env.put(Context.INITIAL_CONTEXT_FACTORY,
+ "org.apache.naming.NamingContextFactory");
+ env.put(Context.URL_PKG_PREFIXES, "org.apache.naming");
+ Context initialContext = makeInitialContext(env);
+ Context victim = (Context) initialContext.lookup("sub/next");
+ ContextUtils.destroyContext(victim);
+ try {
+ initialContext.lookup("sub/next");
+ fail("Expecting NamingException");
+ } catch (NamingException ex) {
+ // Expected
+ }
+ ContextUtils.destroyInitialContext(env);
+
+ // Named
+ initialContext = makeInitialContext(env);
+ victim = (Context) initialContext.lookup("sub/next");
+ ContextBindings.bindContext("victim", victim);
+ ContextUtils.destroyContext("victim");
+ try {
+ initialContext.lookup("sub/next");
+ fail("Expecting NamingException");
+ } catch (NamingException ex) {
+ // Expected
+ }
+ assertNull(ContextBindings.getContext("victim"));
+
+ try {
+ ContextUtils.destroyContext("victim");
+ fail("Expecting NamingException");
+ } catch (NamingException e) {
+ // Expected
+ }
+
+ ContextUtils.destroyInitialContext(env);
+ }
+
+ protected void checkInitialContext(Hashtable env) throws Exception {
+ killInitialContext(env, makeInitialContext(env));
+ }
+
+ protected Context makeInitialContext(Hashtable env) throws Exception {
+ Context initialContext = new InitialContext(env);
+ initialContext.bind("foo", "bar");
+ initialContext.bind("int", new Integer(1));
+ initialContext.createSubcontext("sub");
+ Context subContext = (Context) initialContext.lookup("sub");
+ subContext.bind("foofoo","barbar");
+ subContext.createSubcontext("next");
+ Context nextContext = (Context) subContext.lookup("next");
+ subContext.bind("parent", initialContext); // cycle
+ nextContext.bind("grandpa", initialContext); // multi-generational cycle
+ assertEquals("initial lookup", "barbar", initialContext.lookup("sub/foofoo"));
+ assertEquals("inbred lookup", "barbar", initialContext.lookup("sub/next/grandpa/sub/foofoo"));
+ return initialContext;
+ }
+
+ protected void killInitialContext(Hashtable env, Context context) throws Exception {
+ ContextUtils.destroyInitialContext(env);
+ assertNull(ContextBindings.getContext("test"));
+ assertFalse(context.list("").hasMore());
+ }
+}
Modified: incubator/directory/naming/trunk/xdocs/changes.xml
URL: http://svn.apache.org/viewcvs/incubator/directory/naming/trunk/xdocs/changes.xml?view=diff&r1=153578&r2=153579
==============================================================================
--- incubator/directory/naming/trunk/xdocs/changes.xml (original)
+++ incubator/directory/naming/trunk/xdocs/changes.xml Sat Feb 12 15:30:30 2005
@@ -44,6 +44,14 @@
When using NamingContextFactory, a NAME property may be specified to
retrieve or create a named context.
</action>
+ <action dev="psteitz" type="update" issue="DIRNAMING-12">
+ Added support for named contexts to XMLConfigurator.
+ Changed loadConfiguration to use update semantics.
+ Fixed bug in destroyContext method.
+ Added ContextUtils class of static methods to manipulate contexts.
+ Added methods to ContextBindings to get bound context names, clear
+ context bindings and destroy bound contexts.
+ </action>
</release>
<release version="0.8" date="2005-01-15"
description="Apache Directory Naming 0.8 - Incubator Technology Preview">