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 2003/12/07 22:00:05 UTC

svn commit: rev 1384 - in incubator/directory/naming: . branches tags trunk trunk/core trunk/core/src trunk/core/src/java trunk/core/src/java/org trunk/core/src/java/org/apache trunk/core/src/java/org/apache/directory trunk/core/src/java/org/apache/directory/naming trunk/core/src/java/org/apache/directory/naming/java trunk/core/src/java/org/apache/directory/naming/resources trunk/core/src/java/org/apache/directory/naming/resources/jndi trunk/core/src/test trunk/core/src/test/org trunk/core/src/test/org/apache trunk/core/src/test/org/apache/directory trunk/core/src/test/org/apache/directory/naming trunk/factory trunk/factory/src trunk/factory/src/java trunk/factory/src/java/org trunk/factory/src/java/org/apache trunk/factory/src/java/org/apache/directory trunk/factory/src/java/org/apache/directory/naming trunk/factory/src/java/org/apache/directory/naming/config trunk/factory/src/java/org/apache/directory/naming/factory trunk/factory/src/test trunk/factory/src/test/org trunk/factory/src/test/org/apache trunk/factory/src/test/org/apache/directory trunk/factory/src/test/org/apache/directory/naming trunk/factory/src/test/org/apache/directory/naming/config trunk/xdocs

Author: psteitz
Date: Sun Dec  7 13:00:05 2003
New Revision: 1384

Added:
   incubator/directory/naming/
   incubator/directory/naming/branches/
   incubator/directory/naming/tags/
   incubator/directory/naming/trunk/
   incubator/directory/naming/trunk/LICENSE.txt
   incubator/directory/naming/trunk/checkstyle.xml
   incubator/directory/naming/trunk/core/
   incubator/directory/naming/trunk/core/project.properties
   incubator/directory/naming/trunk/core/project.xml
   incubator/directory/naming/trunk/core/src/
   incubator/directory/naming/trunk/core/src/java/
   incubator/directory/naming/trunk/core/src/java/org/
   incubator/directory/naming/trunk/core/src/java/org/apache/
   incubator/directory/naming/trunk/core/src/java/org/apache/directory/
   incubator/directory/naming/trunk/core/src/java/org/apache/directory/naming/
   incubator/directory/naming/trunk/core/src/java/org/apache/directory/naming/Constants.java
   incubator/directory/naming/trunk/core/src/java/org/apache/directory/naming/ContextAccessController.java
   incubator/directory/naming/trunk/core/src/java/org/apache/directory/naming/ContextBindings.java
   incubator/directory/naming/trunk/core/src/java/org/apache/directory/naming/EjbRef.java
   incubator/directory/naming/trunk/core/src/java/org/apache/directory/naming/JndiPermission.java
   incubator/directory/naming/trunk/core/src/java/org/apache/directory/naming/LocalStrings.properties
   incubator/directory/naming/trunk/core/src/java/org/apache/directory/naming/LocalStrings_es.properties
   incubator/directory/naming/trunk/core/src/java/org/apache/directory/naming/LocalStrings_fr.properties
   incubator/directory/naming/trunk/core/src/java/org/apache/directory/naming/LocalStrings_ja.properties
   incubator/directory/naming/trunk/core/src/java/org/apache/directory/naming/NameParserImpl.java
   incubator/directory/naming/trunk/core/src/java/org/apache/directory/naming/NamingContext.java
   incubator/directory/naming/trunk/core/src/java/org/apache/directory/naming/NamingContextBindingsEnumeration.java
   incubator/directory/naming/trunk/core/src/java/org/apache/directory/naming/NamingContextEnumeration.java
   incubator/directory/naming/trunk/core/src/java/org/apache/directory/naming/NamingEntry.java
   incubator/directory/naming/trunk/core/src/java/org/apache/directory/naming/NamingService.java
   incubator/directory/naming/trunk/core/src/java/org/apache/directory/naming/NamingServiceMBean.java
   incubator/directory/naming/trunk/core/src/java/org/apache/directory/naming/ResourceEnvRef.java
   incubator/directory/naming/trunk/core/src/java/org/apache/directory/naming/ResourceLinkRef.java
   incubator/directory/naming/trunk/core/src/java/org/apache/directory/naming/ResourceRef.java
   incubator/directory/naming/trunk/core/src/java/org/apache/directory/naming/SelectorContext.java
   incubator/directory/naming/trunk/core/src/java/org/apache/directory/naming/StringManager.java
   incubator/directory/naming/trunk/core/src/java/org/apache/directory/naming/TransactionRef.java
   incubator/directory/naming/trunk/core/src/java/org/apache/directory/naming/java/
   incubator/directory/naming/trunk/core/src/java/org/apache/directory/naming/java/javaURLContextFactory.java
   incubator/directory/naming/trunk/core/src/java/org/apache/directory/naming/java/package.html
   incubator/directory/naming/trunk/core/src/java/org/apache/directory/naming/package.html
   incubator/directory/naming/trunk/core/src/java/org/apache/directory/naming/resources/
   incubator/directory/naming/trunk/core/src/java/org/apache/directory/naming/resources/BaseDirContext.java
   incubator/directory/naming/trunk/core/src/java/org/apache/directory/naming/resources/Constants.java
   incubator/directory/naming/trunk/core/src/java/org/apache/directory/naming/resources/DirContextURLConnection.java
   incubator/directory/naming/trunk/core/src/java/org/apache/directory/naming/resources/DirContextURLStreamHandler.java
   incubator/directory/naming/trunk/core/src/java/org/apache/directory/naming/resources/DirContextURLStreamHandlerFactory.java
   incubator/directory/naming/trunk/core/src/java/org/apache/directory/naming/resources/FileDirContext.java
   incubator/directory/naming/trunk/core/src/java/org/apache/directory/naming/resources/ImmutableNameNotFoundException.java
   incubator/directory/naming/trunk/core/src/java/org/apache/directory/naming/resources/LocalStrings.properties
   incubator/directory/naming/trunk/core/src/java/org/apache/directory/naming/resources/LocalStrings_fr.properties
   incubator/directory/naming/trunk/core/src/java/org/apache/directory/naming/resources/LocalStrings_ja.properties
   incubator/directory/naming/trunk/core/src/java/org/apache/directory/naming/resources/ProxyDirContext.java
   incubator/directory/naming/trunk/core/src/java/org/apache/directory/naming/resources/RecyclableNamingEnumeration.java
   incubator/directory/naming/trunk/core/src/java/org/apache/directory/naming/resources/Resource.java
   incubator/directory/naming/trunk/core/src/java/org/apache/directory/naming/resources/ResourceAttributes.java
   incubator/directory/naming/trunk/core/src/java/org/apache/directory/naming/resources/WARDirContext.java
   incubator/directory/naming/trunk/core/src/java/org/apache/directory/naming/resources/jndi/
   incubator/directory/naming/trunk/core/src/java/org/apache/directory/naming/resources/jndi/Handler.java
   incubator/directory/naming/trunk/core/src/test/
   incubator/directory/naming/trunk/core/src/test/org/
   incubator/directory/naming/trunk/core/src/test/org/apache/
   incubator/directory/naming/trunk/core/src/test/org/apache/directory/
   incubator/directory/naming/trunk/core/src/test/org/apache/directory/naming/
   incubator/directory/naming/trunk/core/src/test/org/apache/directory/naming/BasicContextTest.java
   incubator/directory/naming/trunk/core/src/test/org/apache/directory/naming/LocalStrings.properties
   incubator/directory/naming/trunk/core/src/test/org/apache/directory/naming/LocalStrings_es.properties
   incubator/directory/naming/trunk/core/src/test/org/apache/directory/naming/LocalStrings_fr.properties
   incubator/directory/naming/trunk/core/src/test/org/apache/directory/naming/LocalStrings_ja.properties
   incubator/directory/naming/trunk/factory/
   incubator/directory/naming/trunk/factory/project.properties
   incubator/directory/naming/trunk/factory/project.xml
   incubator/directory/naming/trunk/factory/src/
   incubator/directory/naming/trunk/factory/src/java/
   incubator/directory/naming/trunk/factory/src/java/org/
   incubator/directory/naming/trunk/factory/src/java/org/apache/
   incubator/directory/naming/trunk/factory/src/java/org/apache/directory/
   incubator/directory/naming/trunk/factory/src/java/org/apache/directory/naming/
   incubator/directory/naming/trunk/factory/src/java/org/apache/directory/naming/config/
   incubator/directory/naming/trunk/factory/src/java/org/apache/directory/naming/config/Config.java
   incubator/directory/naming/trunk/factory/src/java/org/apache/directory/naming/config/ParseException.java
   incubator/directory/naming/trunk/factory/src/java/org/apache/directory/naming/config/XmlConfigurator.java
   incubator/directory/naming/trunk/factory/src/java/org/apache/directory/naming/factory/
   incubator/directory/naming/trunk/factory/src/java/org/apache/directory/naming/factory/BeanFactory.java
   incubator/directory/naming/trunk/factory/src/java/org/apache/directory/naming/factory/Constants.java
   incubator/directory/naming/trunk/factory/src/java/org/apache/directory/naming/factory/EjbFactory.java
   incubator/directory/naming/trunk/factory/src/java/org/apache/directory/naming/factory/MailSessionFactory.java
   incubator/directory/naming/trunk/factory/src/java/org/apache/directory/naming/factory/ResourceEnvFactory.java
   incubator/directory/naming/trunk/factory/src/java/org/apache/directory/naming/factory/ResourceFactory.java
   incubator/directory/naming/trunk/factory/src/java/org/apache/directory/naming/factory/ResourceLinkFactory.java
   incubator/directory/naming/trunk/factory/src/java/org/apache/directory/naming/factory/SendMailFactory.java
   incubator/directory/naming/trunk/factory/src/java/org/apache/directory/naming/factory/TransactionFactory.java
   incubator/directory/naming/trunk/factory/src/java/org/apache/directory/naming/factory/TyrexFactory.java
   incubator/directory/naming/trunk/factory/src/java/org/apache/directory/naming/factory/TyrexResourceFactory.java
   incubator/directory/naming/trunk/factory/src/java/org/apache/directory/naming/factory/TyrexTransactionFactory.java
   incubator/directory/naming/trunk/factory/src/java/org/apache/directory/naming/factory/package.html
   incubator/directory/naming/trunk/factory/src/test/
   incubator/directory/naming/trunk/factory/src/test/org/
   incubator/directory/naming/trunk/factory/src/test/org/apache/
   incubator/directory/naming/trunk/factory/src/test/org/apache/directory/
   incubator/directory/naming/trunk/factory/src/test/org/apache/directory/naming/
   incubator/directory/naming/trunk/factory/src/test/org/apache/directory/naming/config/
   incubator/directory/naming/trunk/factory/src/test/org/apache/directory/naming/config/XmlConfiguratorTest.java
   incubator/directory/naming/trunk/factory/src/test/test-jndi.xml
   incubator/directory/naming/trunk/maven.log
   incubator/directory/naming/trunk/project.properties
   incubator/directory/naming/trunk/project.xml
   incubator/directory/naming/trunk/velocity.log
   incubator/directory/naming/trunk/xdocs/
   incubator/directory/naming/trunk/xdocs/building.xml
   incubator/directory/naming/trunk/xdocs/index.xml
   incubator/directory/naming/trunk/xdocs/navigation.xml
Log:
initial import of naming sources.

Added: incubator/directory/naming/trunk/LICENSE.txt
==============================================================================
--- (empty file)
+++ incubator/directory/naming/trunk/LICENSE.txt	Sun Dec  7 13:00:05 2003
@@ -0,0 +1,53 @@
+/* ====================================================================
+ * The Apache Software License, Version 1.1
+ *
+ * Copyright (c) 2002-2003 The Apache Software Foundation.  All rights
+ * reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. The end-user documentation included with the redistribution, if
+ *    any, must include the following acknowledgement:
+ *       "This product includes software developed by the
+ *        Apache Software Foundation (http://www.apache.org/)."
+ *    Alternately, this acknowledgement may appear in the software itself,
+ *    if and wherever such third-party acknowledgements normally appear.
+ *
+ * 4. The names "The Jakarta Project", "Commons", and "Apache Software
+ *    Foundation" must not be used to endorse or promote products derived
+ *    from this software without prior written permission. For written
+ *    permission, please contact apache@apache.org.
+ *
+ * 5. Products derived from this software may not be called "Apache"
+ *    nor may "Apache" appear in their names without prior written
+ *    permission of the Apache Software Foundation.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation.  For more
+ * information on the Apache Software Foundation, please see
+ * <http://www.apache.org/>.
+ */

Added: incubator/directory/naming/trunk/checkstyle.xml
==============================================================================
--- (empty file)
+++ incubator/directory/naming/trunk/checkstyle.xml	Sun Dec  7 13:00:05 2003
@@ -0,0 +1,22 @@
+<?xml version="1.0"?>
+
+<!DOCTYPE module PUBLIC
+    "-//Puppy Crawl//DTD Check Configuration 1.1//EN"
+    "http://www.puppycrawl.com/dtds/configuration_1_1.dtd">
+
+<!-- commons lang customization of default Checkstyle behavior -->
+<module name="Checker">
+  <property name="basedir" value="."/>
+  <property name="localeLanguage" value="en"/>
+  <module name="PackageHtml"/>
+    <module name="TreeWalker">
+    <module name="LineLength">
+      <property name="max" value="120"/>
+    </module>
+    <module name="JavadocMethod">
+      <property name="allowUndeclaredRTE" value="true"/>
+    </module>
+ </module>
+</module>
+                        
+

Added: incubator/directory/naming/trunk/core/project.properties
==============================================================================
--- (empty file)
+++ incubator/directory/naming/trunk/core/project.properties	Sun Dec  7 13:00:05 2003
@@ -0,0 +1,5 @@
+maven.checkstyle.properties=${basedir}/../checkstyle.xml
+maven.junit.fork=true
+maven.xdoc.date = left
+maven.checkstyle.header.file=${basedir}/../LICENSE.txt
+maven.multiproject.type=jar

Added: incubator/directory/naming/trunk/core/project.xml
==============================================================================
--- (empty file)
+++ incubator/directory/naming/trunk/core/project.xml	Sun Dec  7 13:00:05 2003
@@ -0,0 +1,7 @@
+<?xml version="1.0"?>
+<project>
+   <extend>${basedir}/../project.xml</extend>  
+   <id>commons-naming-core</id>
+   <name>Core</name>
+</project>
+

Added: incubator/directory/naming/trunk/core/src/java/org/apache/directory/naming/Constants.java
==============================================================================
--- (empty file)
+++ incubator/directory/naming/trunk/core/src/java/org/apache/directory/naming/Constants.java	Sun Dec  7 13:00:05 2003
@@ -0,0 +1,102 @@
+/*
+ * $Header: /home/cvs/jakarta-commons-sandbox/naming/core/src/java/org/apache/commons/naming/Constants.java,v 1.2 2003/10/13 08:16:47 rdonkin Exp $
+ * $Revision: 1.2 $
+ * $Date: 2003/10/13 08:16:47 $
+ *
+ * ====================================================================
+ *
+ * The Apache Software License, Version 1.1
+ *
+ * Copyright (c) 1999 The Apache Software Foundation.  All rights 
+ * reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. The end-user documentation included with the redistribution, if
+ *    any, must include the following acknowledgement:
+ *       "This product includes software developed by the 
+ *        Apache Software Foundation (http://www.apache.org/)."
+ *    Alternately, this acknowledgement may appear in the software itself,
+ *    if and wherever such third-party acknowledgements normally appear.
+ *
+ * 4. The names "The Jakarta Project", "Tomcat", and "Apache Software
+ *    Foundation" must not be used to endorse or promote products derived
+ *    from this software without prior written permission. For written 
+ *    permission, please contact apache@apache.org.
+ *
+ * 5. Products derived from this software may not be called "Apache"
+ *    nor may "Apache" appear in their names without prior written
+ *    permission of the Apache Software Foundation.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation.  For more
+ * information on the Apache Software Foundation, please see
+ * <http://www.apache.org/>.
+ *
+ * [Additional notices, if required by prior licensing conditions]
+ *
+ */ 
+
+
+package org.apache.directory.naming;
+
+
+/**
+ * Static constants for this package.
+ */
+
+public final class Constants {
+
+    public static final String Package = "org.apache.directory.naming";
+    
+     public static final String FactoryPackage = "org.apache.directory.naming.factory";
+
+    public static final String DEFAULT_RESOURCE_FACTORY = 
+        FactoryPackage + ".ResourceFactory";
+
+    public static final String DEFAULT_RESOURCE_LINK_FACTORY = 
+        FactoryPackage + ".ResourceLinkFactory";
+
+    public static final String DEFAULT_TRANSACTION_FACTORY = 
+        FactoryPackage + ".TransactionFactory";
+
+    public static final String DEFAULT_RESOURCE_ENV_FACTORY = 
+        FactoryPackage + ".ResourceEnvFactory";
+
+    public static final String DEFAULT_EJB_FACTORY = 
+        FactoryPackage + ".EjbFactory";
+
+    public static final String DBCP_DATASOURCE_FACTORY = 
+        "org.apache.commons.dbcp.BasicDataSourceFactory";
+
+    public static final String TYREX_RESOURCE_FACTORY =
+        FactoryPackage + ".TyrexResourceFactory";
+
+    public static final String TYREX_TRANSACTION_FACTORY = 
+        FactoryPackage + ".TyrexTransactionFactory";
+
+}

Added: incubator/directory/naming/trunk/core/src/java/org/apache/directory/naming/ContextAccessController.java
==============================================================================
--- (empty file)
+++ incubator/directory/naming/trunk/core/src/java/org/apache/directory/naming/ContextAccessController.java	Sun Dec  7 13:00:05 2003
@@ -0,0 +1,176 @@
+/*
+ * $Header: /home/cvs/jakarta-commons-sandbox/naming/core/src/java/org/apache/commons/naming/ContextAccessController.java,v 1.3 2003/11/30 05:15:06 psteitz Exp $
+ * $Revision: 1.3 $
+ * $Date: 2003/11/30 05:15:06 $
+ *
+ * ====================================================================
+ *
+ * The Apache Software License, Version 1.1
+ *
+ * Copyright (c) 1999 The Apache Software Foundation.  All rights 
+ * reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. The end-user documentation included with the redistribution, if
+ *    any, must include the following acknowledgement:
+ *       "This product includes software developed by the 
+ *        Apache Software Foundation (http://www.apache.org/)."
+ *    Alternately, this acknowledgement may appear in the software itself,
+ *    if and wherever such third-party acknowledgements normally appear.
+ *
+ * 4. The names "The Jakarta Project", "Tomcat", and "Apache Software
+ *    Foundation" must not be used to endorse or promote products derived
+ *    from this software without prior written permission. For written 
+ *    permission, please contact apache@apache.org.
+ *
+ * 5. Products derived from this software may not be called "Apache"
+ *    nor may "Apache" appear in their names without prior written
+ *    permission of the Apache Software Foundation.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation.  For more
+ * information on the Apache Software Foundation, please see
+ * <http://www.apache.org/>.
+ *
+ * [Additional notices, if required by prior licensing conditions]
+ *
+ */ 
+
+
+package org.apache.directory.naming;
+
+import java.util.Hashtable;
+import javax.naming.NamingException;
+
+/**
+ * Handles the access control on the JNDI contexts.
+ *
+ * @author Remy Maucherat
+ * @version $Revision: 1.3 $ $Date: 2003/11/30 05:15:06 $
+ */
+
+public class ContextAccessController {
+
+
+    // -------------------------------------------------------------- Variables
+
+
+    /**
+     * Catalina context names on which writing is not allowed.
+     */
+    private static Hashtable readOnlyContexts = new Hashtable();
+
+
+    /**
+     * Security tokens repository.
+     */
+    private static Hashtable securityTokens = new Hashtable();
+
+
+    // --------------------------------------------------------- Public Methods
+
+
+    /**
+     * Set a security token for a context. Can be set only once.
+     * 
+     * @param name Name of the context
+     * @param token Security token
+     */
+    public static void setSecurityToken(Object name, Object token) {
+        if ((!securityTokens.containsKey(name)) && (token != null)) {
+            securityTokens.put(name, token);
+        }
+    }
+
+
+    /**
+     * Remove a security token for a context.
+     * 
+     * @param name Name of the context
+     * @param token Security token
+     */
+    public static void unsetSecurityToken(Object name, Object token) {
+        if (checkSecurityToken(name, token)) {
+            securityTokens.remove(name);
+        }
+    }
+
+
+    /**
+     * Check a submitted security token. The submitted token must be equal to
+     * the token present in the repository. If no token is present for the 
+     * context, then returns true.
+     * 
+     * @param name Name of the context
+     * @param token Submitted security token
+     */
+    public static boolean checkSecurityToken
+        (Object name, Object token) {
+        Object refToken = securityTokens.get(name);
+        if (refToken == null)
+            return (true);
+        if ((refToken != null) && (refToken.equals(token)))
+            return (true);
+        return (false);
+    }
+
+
+    /**
+     * Allow writing to a context.
+     * 
+     * @param name Name of the context
+     * @param token Security token
+     */
+    public static void setWritable(Object name, Object token) {
+        if (checkSecurityToken(name, token))
+            readOnlyContexts.remove(name);
+    }
+
+
+    /**
+     * Set whether or not a context is writable.
+     * 
+     * @param name Name of the context
+     */
+    public static void setReadOnly(Object name) {
+        readOnlyContexts.put(name, name);
+    }
+
+
+    /**
+     * Returns if a context is writable.
+     * 
+     * @param name Name of the context
+     */
+    public static boolean isWritable(Object name) {
+        return !(readOnlyContexts.containsKey(name));
+    }
+
+
+}
+

Added: incubator/directory/naming/trunk/core/src/java/org/apache/directory/naming/ContextBindings.java
==============================================================================
--- (empty file)
+++ incubator/directory/naming/trunk/core/src/java/org/apache/directory/naming/ContextBindings.java	Sun Dec  7 13:00:05 2003
@@ -0,0 +1,414 @@
+/*
+ * $Header: /home/cvs/jakarta-commons-sandbox/naming/core/src/java/org/apache/commons/naming/ContextBindings.java,v 1.2 2003/10/13 08:16:47 rdonkin Exp $
+ * $Revision: 1.2 $
+ * $Date: 2003/10/13 08:16:47 $
+ *
+ * ====================================================================
+ *
+ * The Apache Software License, Version 1.1
+ *
+ * Copyright (c) 1999 The Apache Software Foundation.  All rights 
+ * reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. The end-user documentation included with the redistribution, if
+ *    any, must include the following acknowledgement:
+ *       "This product includes software developed by the 
+ *        Apache Software Foundation (http://www.apache.org/)."
+ *    Alternately, this acknowledgement may appear in the software itself,
+ *    if and wherever such third-party acknowledgements normally appear.
+ *
+ * 4. The names "The Jakarta Project", "Tomcat", and "Apache Software
+ *    Foundation" must not be used to endorse or promote products derived
+ *    from this software without prior written permission. For written 
+ *    permission, please contact apache@apache.org.
+ *
+ * 5. Products derived from this software may not be called "Apache"
+ *    nor may "Apache" appear in their names without prior written
+ *    permission of the Apache Software Foundation.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation.  For more
+ * information on the Apache Software Foundation, please see
+ * <http://www.apache.org/>.
+ *
+ * [Additional notices, if required by prior licensing conditions]
+ *
+ */ 
+
+
+package org.apache.directory.naming;
+
+import java.util.Hashtable;
+import javax.naming.NamingException;
+import javax.naming.Context;
+
+/**
+ * Handles the associations :
+ * <ul>
+ * <li>Catalina context name with the NamingContext</li>
+ * <li>Calling thread with the NamingContext</li>
+ * </ul>
+ *
+ * @author Remy Maucherat
+ * @version $Revision: 1.2 $ $Date: 2003/10/13 08:16:47 $
+ */
+
+public class ContextBindings {
+
+
+    // -------------------------------------------------------------- Variables
+
+
+    /**
+     * Bindings name - naming context. Keyed by name.
+     */
+    private static Hashtable contextNameBindings = new Hashtable();
+
+
+    /**
+     * Bindings thread - naming context. Keyed by thread id.
+     */
+    private static Hashtable threadBindings = new Hashtable();
+
+
+    /**
+     * Bindings thread - name. Keyed by thread id.
+     */
+    private static Hashtable threadNameBindings = new Hashtable();
+
+
+    /**
+     * Bindings class loader - naming context. Keyed by CL id.
+     */
+    private static Hashtable clBindings = new Hashtable();
+
+
+    /**
+     * Bindings class loader - name. Keyed by CL id.
+     */
+    private static Hashtable clNameBindings = new Hashtable();
+
+
+    /**
+     * The string manager for this package.
+     */
+    protected static StringManager sm = 
+        StringManager.getManager(Constants.Package);
+
+
+    // --------------------------------------------------------- Public Methods
+
+
+    /**
+     * Binds a context name.
+     * 
+     * @param name Name of the context
+     * @param context Associated naming context instance
+     */
+    public static void bindContext(Object name, Context context) {
+        bindContext(name, context, null);
+    }
+
+
+    /**
+     * Binds a context name.
+     * 
+     * @param name Name of the context
+     * @param context Associated naming context instance
+     * @param token Security token
+     */
+    public static void bindContext(Object name, Context context, 
+                                   Object token) {
+        if (ContextAccessController.checkSecurityToken(name, token))
+            contextNameBindings.put(name, context);
+    }
+
+
+    /**
+     * Unbind context name.
+     * 
+     * @param name Name of the context
+     */
+    public static void unbindContext(Object name) {
+        unbindContext(name, null);
+    }
+
+
+    /**
+     * Unbind context name.
+     * 
+     * @param name Name of the context
+     * @param token Security token
+     */
+    public static void unbindContext(Object name, Object token) {
+        if (ContextAccessController.checkSecurityToken(name, token))
+            contextNameBindings.remove(name);
+    }
+
+
+    /**
+     * Retrieve a naming context.
+     * 
+     * @param name Name of the context
+     */
+    static Context getContext(Object name) {
+        return (Context) contextNameBindings.get(name);
+    }
+
+
+    /**
+     * Binds a naming context to a thread.
+     * 
+     * @param name Name of the context
+     */
+    public static void bindThread(Object name) 
+        throws NamingException {
+        bindThread(name, null);
+    }
+
+
+    /**
+     * Binds a naming context to a thread.
+     * 
+     * @param name Name of the context
+     * @param token Security token
+     */
+    public static void bindThread(Object name, Object token) 
+        throws NamingException {
+        if (ContextAccessController.checkSecurityToken(name, token)) {
+            Context context = (Context) contextNameBindings.get(name);
+            if (context == null)
+                throw new NamingException
+                    (sm.getString("contextBindings.unknownContext", name));
+            threadBindings.put(Thread.currentThread(), context);
+            threadNameBindings.put(Thread.currentThread(), name);
+        }
+    }
+
+
+    /**
+     * Unbinds a naming context to a thread.
+     * 
+     * @param name Name of the context
+     */
+    public static void unbindThread(Object name) {
+        unbindThread(name, null);
+    }
+
+
+    /**
+     * Unbinds a naming context to a thread.
+     * 
+     * @param name Name of the context
+     * @param token Security token
+     */
+    public static void unbindThread(Object name, Object token) {
+        if (ContextAccessController.checkSecurityToken(name, token)) {
+            threadBindings.remove(Thread.currentThread());
+            threadNameBindings.remove(Thread.currentThread());
+        }
+    }
+
+
+    /**
+     * Retrieves the naming context bound to a thread.
+     */
+    public static Context getThread()
+        throws NamingException {
+        Context context = 
+            (Context) threadBindings.get(Thread.currentThread());
+        if (context == null)
+            throw new NamingException
+                (sm.getString("contextBindings.noContextBoundToThread"));
+        return context;
+    }
+
+
+    /**
+     * Retrieves the naming context name bound to a thread.
+     */
+    static Object getThreadName()
+        throws NamingException {
+        Object name = threadNameBindings.get(Thread.currentThread());
+        if (name == null)
+            throw new NamingException
+                (sm.getString("contextBindings.noContextBoundToThread"));
+        return name;
+    }
+
+
+    /**
+     * Tests if current thread is bound to a context.
+     */
+    public static boolean isThreadBound() {
+        return (threadBindings.containsKey(Thread.currentThread()));
+    }
+
+
+    /**
+     * Binds a naming context to a class loader.
+     * 
+     * @param name Name of the context
+     */
+    public static void bindClassLoader(Object name) 
+        throws NamingException {
+        bindClassLoader(name, null);
+    }
+
+
+    /**
+     * Binds a naming context to a thread.
+     * 
+     * @param name Name of the context
+     * @param token Security token
+     */
+    public static void bindClassLoader(Object name, Object token) 
+        throws NamingException {
+        bindClassLoader
+            (name, token, Thread.currentThread().getContextClassLoader());
+    }
+
+
+    /**
+     * Binds a naming context to a thread.
+     * 
+     * @param name Name of the context
+     * @param token Security token
+     */
+    public static void bindClassLoader(Object name, Object token, 
+                                       ClassLoader classLoader) 
+        throws NamingException {
+        if (ContextAccessController.checkSecurityToken(name, token)) {
+            Context context = (Context) contextNameBindings.get(name);
+            if (context == null)
+                throw new NamingException
+                    (sm.getString("contextBindings.unknownContext", name));
+            Object n = clNameBindings.get(classLoader);
+            // Only bind CL if it isn't already bound to the context
+            if (n == null) {
+                clBindings.put(classLoader, context);
+                clNameBindings.put(classLoader, name);
+            }
+        }
+    }
+
+
+    /**
+     * Unbinds a naming context to a class loader.
+     * 
+     * @param name Name of the context
+     */
+    public static void unbindClassLoader(Object name) {
+        unbindClassLoader(name, null);
+    }
+
+
+    /**
+     * Unbinds a naming context to a class loader.
+     * 
+     * @param name Name of the context
+     * @param token Security token
+     */
+    public static void unbindClassLoader(Object name, Object token) {
+        unbindClassLoader(name, token, 
+                          Thread.currentThread().getContextClassLoader());
+    }
+
+
+    /**
+     * Unbinds a naming context to a class loader.
+     * 
+     * @param name Name of the context
+     * @param token Security token
+     */
+    public static void unbindClassLoader(Object name, Object token, 
+                                         ClassLoader classLoader) {
+        if (ContextAccessController.checkSecurityToken(name, token)) {
+            Object n = clNameBindings.get(classLoader);
+            if (!(n.equals(name))) {
+                return;
+            }
+            clBindings.remove(classLoader);
+            clNameBindings.remove(classLoader);
+        }
+    }
+
+
+    /**
+     * Retrieves the naming context bound to a class loader.
+     */
+    public static Context getClassLoader()
+        throws NamingException {
+        ClassLoader cl = Thread.currentThread().getContextClassLoader();
+        Context context = null;
+        do {
+            context = (Context) clBindings.get(cl);
+            if (context != null) {
+                return context;
+            }
+        } while ((cl = cl.getParent()) != null);
+        throw new NamingException
+            (sm.getString("contextBindings.noContextBoundToCL"));
+    }
+
+
+    /**
+     * Retrieves the naming context name bound to a class loader.
+     */
+    static Object getClassLoaderName()
+        throws NamingException {
+        ClassLoader cl = Thread.currentThread().getContextClassLoader();
+        Object name = null;
+        do {
+            name = clNameBindings.get(cl);
+            if (name != null) {
+                return name;
+            }
+        } while ((cl = cl.getParent()) != null);
+        throw new NamingException
+            (sm.getString("contextBindings.noContextBoundToCL"));
+    }
+
+
+    /**
+     * Tests if current class loader is bound to a context.
+     */
+    public static boolean isClassLoaderBound() {
+        ClassLoader cl = Thread.currentThread().getContextClassLoader();
+        do {
+            if (clBindings.containsKey(cl)) {
+                return true;
+            }
+        } while ((cl = cl.getParent()) != null);
+        return false;
+    }
+
+
+}
+

Added: incubator/directory/naming/trunk/core/src/java/org/apache/directory/naming/EjbRef.java
==============================================================================
--- (empty file)
+++ incubator/directory/naming/trunk/core/src/java/org/apache/directory/naming/EjbRef.java	Sun Dec  7 13:00:05 2003
@@ -0,0 +1,184 @@
+/*
+ * $Header: /home/cvs/jakarta-commons-sandbox/naming/core/src/java/org/apache/commons/naming/EjbRef.java,v 1.2 2003/10/13 08:16:47 rdonkin Exp $
+ * $Revision: 1.2 $
+ * $Date: 2003/10/13 08:16:47 $
+ *
+ * ====================================================================
+ *
+ * The Apache Software License, Version 1.1
+ *
+ * Copyright (c) 1999 The Apache Software Foundation.  All rights 
+ * reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. The end-user documentation included with the redistribution, if
+ *    any, must include the following acknowledgement:
+ *       "This product includes software developed by the 
+ *        Apache Software Foundation (http://www.apache.org/)."
+ *    Alternately, this acknowledgement may appear in the software itself,
+ *    if and wherever such third-party acknowledgements normally appear.
+ *
+ * 4. The names "The Jakarta Project", "Tomcat", and "Apache Software
+ *    Foundation" must not be used to endorse or promote products derived
+ *    from this software without prior written permission. For written 
+ *    permission, please contact apache@apache.org.
+ *
+ * 5. Products derived from this software may not be called "Apache"
+ *    nor may "Apache" appear in their names without prior written
+ *    permission of the Apache Software Foundation.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation.  For more
+ * information on the Apache Software Foundation, please see
+ * <http://www.apache.org/>.
+ *
+ * [Additional notices, if required by prior licensing conditions]
+ *
+ */ 
+
+
+package org.apache.directory.naming;
+
+import java.util.Hashtable;
+import javax.naming.Reference;
+import javax.naming.Context;
+import javax.naming.StringRefAddr;
+
+/**
+ * Represents a reference address to an EJB.
+ *
+ * @author Remy Maucherat
+ * @version $Revision: 1.2 $ $Date: 2003/10/13 08:16:47 $
+ */
+
+public class EjbRef
+    extends Reference {
+
+
+    // -------------------------------------------------------------- Constants
+
+
+    /**
+     * Default factory for this reference.
+     */
+    public static final String DEFAULT_FACTORY = Constants.DEFAULT_EJB_FACTORY;
+
+
+    /**
+     * EJB type address type.
+     */
+    public static final String TYPE = "type";
+
+
+    /**
+     * Remote interface classname address type.
+     */
+    public static final String REMOTE = "remote";
+
+
+    /**
+     * Link address type.
+     */
+    public static final String LINK = "link";
+
+
+    // ----------------------------------------------------------- Constructors
+
+
+    /**
+     * EJB Reference.
+     * 
+     * @param ejbType EJB type
+     * @param home Home interface classname
+     * @param remote Remote interface classname
+     * @param link EJB link
+     */
+    public EjbRef(String ejbType, String home, String remote, String link) {
+        this(ejbType, home, remote, link, null, null);
+    }
+
+
+    /**
+     * EJB Reference.
+     * 
+     * @param ejbType EJB type
+     * @param home Home interface classname
+     * @param remote Remote interface classname
+     * @param link EJB link
+     */
+    public EjbRef(String ejbType, String home, String remote, String link,
+                  String factory, String factoryLocation) {
+        super(home, factory, factoryLocation);
+        StringRefAddr refAddr = null;
+        if (ejbType != null) {
+            refAddr = new StringRefAddr(TYPE, ejbType);
+            add(refAddr);
+        }
+        if (remote != null) {
+            refAddr = new StringRefAddr(REMOTE, remote);
+            add(refAddr);
+        }
+        if (link != null) {
+            refAddr = new StringRefAddr(LINK, link);
+            add(refAddr);
+        }
+    }
+
+
+    // ----------------------------------------------------- Instance Variables
+
+
+    // -------------------------------------------------------- RefAddr Methods
+
+
+    // ------------------------------------------------------ Reference Methods
+
+
+    /**
+     * Retrieves the class name of the factory of the object to which this 
+     * reference refers.
+     */
+    public String getFactoryClassName() {
+        String factory = super.getFactoryClassName();
+        if (factory != null) {
+            return factory;
+        } else {
+            factory = System.getProperty(Context.OBJECT_FACTORIES);
+            if (factory != null) {
+                return null;
+            } else {
+                return DEFAULT_FACTORY;
+            }
+        }
+    }
+
+
+    // ------------------------------------------------------------- Properties
+
+
+}

Added: incubator/directory/naming/trunk/core/src/java/org/apache/directory/naming/JndiPermission.java
==============================================================================
--- (empty file)
+++ incubator/directory/naming/trunk/core/src/java/org/apache/directory/naming/JndiPermission.java	Sun Dec  7 13:00:05 2003
@@ -0,0 +1,109 @@
+/*
+ * $Header: /home/cvs/jakarta-commons-sandbox/naming/core/src/java/org/apache/commons/naming/JndiPermission.java,v 1.3 2003/11/30 05:15:06 psteitz Exp $
+ * $Revision: 1.3 $
+ * $Date: 2003/11/30 05:15:06 $
+ *
+ * ====================================================================
+ *
+ * The Apache Software License, Version 1.1
+ *
+ * Copyright (c) 1999 The Apache Software Foundation.  All rights 
+ * reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. The end-user documentation included with the redistribution, if
+ *    any, must include the following acknowledgement:
+ *       "This product includes software developed by the 
+ *        Apache Software Foundation (http://www.apache.org/)."
+ *    Alternately, this acknowledgement may appear in the software itself,
+ *    if and wherever such third-party acknowledgements normally appear.
+ *
+ * 4. The names "The Jakarta Project", "Tomcat", and "Apache Software
+ *    Foundation" must not be used to endorse or promote products derived
+ *    from this software without prior written permission. For written 
+ *    permission, please contact apache@apache.org.
+ *
+ * 5. Products derived from this software may not be called "Apache"
+ *    nor may "Apache" appear in their names without prior written
+ *    permission of the Apache Software Foundation.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation.  For more
+ * information on the Apache Software Foundation, please see
+ * <http://www.apache.org/>.
+ *
+ * [Additional notices, if required by prior licensing conditions]
+ *
+ */ 
+
+
+package org.apache.directory.naming;
+
+import java.security.BasicPermission;
+import java.security.Permission;
+
+/**
+ * Java SecurityManager Permission class for JNDI name based file resources.
+ * <p>
+ * The JndiPermission extends the BasicPermission.
+ * The permission name is a full or partial jndi resource name.
+ * An * can be used at the end of the name to match all named
+ * resources that start with name.  There are no actions.</p>
+ * <p>
+ * Example that grants permission to read all JNDI file based resources:
+ * <li> permission org.apache.directory.naming.JndiPermission "*";</li>
+ * </p>
+ *
+ * @author Glenn Nielsen
+ * @version $Revision: 1.3 $ $Date: 2003/11/30 05:15:06 $
+ */
+
+public final class JndiPermission extends BasicPermission {
+
+    // ----------------------------------------------------------- Constructors
+
+    /**
+     * Creates a new JndiPermission with no actions
+     *
+     * @param name - JNDI resource path name
+     */
+    public JndiPermission(String name) {
+        super(name);
+    }
+
+    /**
+     * Creates a new JndiPermission with actions
+     *
+     * @param name - JNDI resource path name
+     * @param actions - JNDI actions (none defined)
+     */
+    public JndiPermission(String name, String actions) {
+        super(name,actions);
+    }
+
+}

Added: incubator/directory/naming/trunk/core/src/java/org/apache/directory/naming/LocalStrings.properties
==============================================================================
--- (empty file)
+++ incubator/directory/naming/trunk/core/src/java/org/apache/directory/naming/LocalStrings.properties	Sun Dec  7 13:00:05 2003
@@ -0,0 +1,10 @@
+contextBindings.unknownContext=Unknown context name : {0}
+contextBindings.noContextBoundToThread=No naming context bound to this thread
+contextBindings.noContextBoundToCL=No naming context bound to this class loader
+selectorContext.noJavaUrl=This context must be accessed throught a java: URL
+namingContext.contextExpected=Name is not bound to a Context
+namingContext.nameNotBound=Name {0} is not bound in this Context
+namingContext.readOnly=Context is read only
+namingContext.invalidName=Name is not valid
+namingContext.alreadyBound=Name {0} is already bound in this Context
+namingContext.noAbsoluteName=Can't generate an absolute name for this namespace
\ No newline at end of file

Added: incubator/directory/naming/trunk/core/src/java/org/apache/directory/naming/LocalStrings_es.properties
==============================================================================
--- (empty file)
+++ incubator/directory/naming/trunk/core/src/java/org/apache/directory/naming/LocalStrings_es.properties	Sun Dec  7 13:00:05 2003
@@ -0,0 +1,16 @@
+# $Id: LocalStrings_es.properties,v 1.1 2003/09/02 05:53:10 psteitz Exp $
+
+# language es
+
+# package org.apache.naming
+
+
+contextBindings.unknownContext=Contexto {0} desconocido 
+contextBindings.noContextBoundToThread=No hay contexto de nombres asociado a este hilo
+selectorContext.noJavaUrl=Este contexto debe de ser accedido a traves de una URL de tipo java:
+namingContext.contextExpected=El nombre no esta asociado a ningun Contexto
+namingContext.nameNotBound=El nombre {0} no este asociado a este contexto
+namingContext.readOnly=El contexto es de solo lectura
+namingContext.invalidName=Nombre no valido
+namingContext.noAbsoluteName=No se puede generar un nombre absoluto para este espacio de nombres
+namingContext.alreadyBound=El nombre {0} este ya asociado en este Contexto

Added: incubator/directory/naming/trunk/core/src/java/org/apache/directory/naming/LocalStrings_fr.properties
==============================================================================
--- (empty file)
+++ incubator/directory/naming/trunk/core/src/java/org/apache/directory/naming/LocalStrings_fr.properties	Sun Dec  7 13:00:05 2003
@@ -0,0 +1,10 @@
+contextBindings.unknownContext=Nom de Contexte inconnu : {0}
+contextBindings.noContextBoundToThread=Aucun Contexte de nommage li� � ce thread
+contextBindings.noContextBoundToCL=Aucun Contexte de nommage li� � ce chargeur de classes
+selectorContext.noJavaUrl=Ce Contexte doit �tre acc�d� par une java: URL
+namingContext.contextExpected=Le Nom n''est pas li� � un Contexte
+namingContext.nameNotBound=Le Nom {0} n''est pas li� � ce Contexte
+namingContext.readOnly=Le Contexte est en lecture seule
+namingContext.invalidName=Le Nom est invalide
+namingContext.alreadyBound=Le Nom {0} est d�j� li� � ce Contexte
+namingContext.noAbsoluteName=Impossible de g�n�rer un nom absolu pour cet espace de nommage (namespace)
\ No newline at end of file

Added: incubator/directory/naming/trunk/core/src/java/org/apache/directory/naming/LocalStrings_ja.properties
==============================================================================
--- (empty file)
+++ incubator/directory/naming/trunk/core/src/java/org/apache/directory/naming/LocalStrings_ja.properties	Sun Dec  7 13:00:05 2003
@@ -0,0 +1,10 @@
+contextBindings.unknownContext=\u672a\u77e5\u306e\u30b3\u30f3\u30c6\u30ad\u30b9\u30c8\u540d\u3067\u3059: {0}
+contextBindings.noContextBoundToThread=\u540d\u524d\u4ed8\u3051\u30b3\u30f3\u30c6\u30ad\u30b9\u30c8\u306f\u3053\u306e\u30b9\u30ec\u30c3\u30c9\u306b\u306f\u30d0\u30a4\u30f3\u30c9\u3055\u308c\u3066\u3044\u307e\u305b\u3093
+contextBindings.noContextBoundToCL=\u540d\u524d\u4ed8\u3051\u30b3\u30f3\u30c6\u30ad\u30b9\u30c8\u306f\u3053\u306e\u30af\u30e9\u30b9\u30ed\u30fc\u30c0\u306b\u306f\u30d0\u30a4\u30f3\u30c9\u3055\u308c\u3066\u3044\u307e\u305b\u3093
+selectorContext.noJavaUrl=\u3053\u306e\u30b3\u30f3\u30c6\u30ad\u30b9\u30c8\u306b\u306fjava: URL\u3092\u7528\u3044\u3066\u30a2\u30af\u30bb\u30b9\u3055\u308c\u306d\u3070\u3044\u3051\u307e\u305b\u3093
+namingContext.contextExpected=\u540d\u524d\u304c\u30b3\u30f3\u30c6\u30ad\u30b9\u30c8\u306b\u30d0\u30a4\u30f3\u30c9\u3055\u308c\u3066\u3044\u307e\u305b\u3093
+namingContext.nameNotBound=\u540d\u524d {0} \u306f\u3053\u306e\u30b3\u30f3\u30c6\u30ad\u30b9\u30c8\u306b\u30d0\u30a4\u30f3\u30c9\u3055\u308c\u3066\u3044\u307e\u305b\u3093
+namingContext.readOnly=\u30b3\u30f3\u30c6\u30ad\u30b9\u30c8\u306f\u30ea\u30fc\u30c9\u30aa\u30f3\u30ea\u30fc\u3067\u3059
+namingContext.invalidName=\u540d\u524d\u306f\u7121\u52b9\u3067\u3059
+namingContext.alreadyBound=\u540d\u524d {0} \u306f\u3059\u3067\u306b\u3053\u306e\u30b3\u30f3\u30c6\u30ad\u30b9\u30c8\u306b\u30d0\u30a4\u30f3\u30c9\u3055\u308c\u3066\u3044\u307e\u3059
+namingContext.noAbsoluteName=\u3053\u306e\u540d\u524d\u7a7a\u9593\u306b\u7d76\u5bfe\u540d\u3092\u751f\u6210\u3067\u304d\u307e\u305b\u3093

Added: incubator/directory/naming/trunk/core/src/java/org/apache/directory/naming/NameParserImpl.java
==============================================================================
--- (empty file)
+++ incubator/directory/naming/trunk/core/src/java/org/apache/directory/naming/NameParserImpl.java	Sun Dec  7 13:00:05 2003
@@ -0,0 +1,103 @@
+/*
+ * $Header: /home/cvs/jakarta-commons-sandbox/naming/core/src/java/org/apache/commons/naming/NameParserImpl.java,v 1.2 2003/10/13 08:16:47 rdonkin Exp $
+ * $Revision: 1.2 $
+ * $Date: 2003/10/13 08:16:47 $
+ *
+ * ====================================================================
+ *
+ * The Apache Software License, Version 1.1
+ *
+ * Copyright (c) 1999 The Apache Software Foundation.  All rights 
+ * reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. The end-user documentation included with the redistribution, if
+ *    any, must include the following acknowledgement:
+ *       "This product includes software developed by the 
+ *        Apache Software Foundation (http://www.apache.org/)."
+ *    Alternately, this acknowledgement may appear in the software itself,
+ *    if and wherever such third-party acknowledgements normally appear.
+ *
+ * 4. The names "The Jakarta Project", "Tomcat", and "Apache Software
+ *    Foundation" must not be used to endorse or promote products derived
+ *    from this software without prior written permission. For written 
+ *    permission, please contact apache@apache.org.
+ *
+ * 5. Products derived from this software may not be called "Apache"
+ *    nor may "Apache" appear in their names without prior written
+ *    permission of the Apache Software Foundation.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation.  For more
+ * information on the Apache Software Foundation, please see
+ * <http://www.apache.org/>.
+ *
+ * [Additional notices, if required by prior licensing conditions]
+ *
+ */ 
+
+
+package org.apache.directory.naming;
+
+import javax.naming.NameParser;
+import javax.naming.Name;
+import javax.naming.NamingException;
+import javax.naming.CompositeName;
+
+/**
+ * Parses names.
+ *
+ * @author Remy Maucherat
+ * @version $Revision: 1.2 $ $Date: 2003/10/13 08:16:47 $
+ */
+
+public class NameParserImpl 
+    implements NameParser {
+
+
+    // ----------------------------------------------------- Instance Variables
+
+
+    // ----------------------------------------------------- NameParser Methods
+
+
+    /**
+     * Parses a name into its components.
+     * 
+     * @param name The non-null string name to parse
+     * @return A non-null parsed form of the name using the naming convention 
+     * of this parser.
+     */
+    public Name parse(String name)
+        throws NamingException {
+        return new CompositeName(name);
+    }
+
+
+}
+

Added: incubator/directory/naming/trunk/core/src/java/org/apache/directory/naming/NamingContext.java
==============================================================================
--- (empty file)
+++ incubator/directory/naming/trunk/core/src/java/org/apache/directory/naming/NamingContext.java	Sun Dec  7 13:00:05 2003
@@ -0,0 +1,947 @@
+/*
+ * $Header: /home/cvs/jakarta-commons-sandbox/naming/core/src/java/org/apache/commons/naming/NamingContext.java,v 1.3 2003/11/30 05:22:15 psteitz Exp $
+ * $Revision: 1.3 $
+ * $Date: 2003/11/30 05:22:15 $
+ *
+ * ====================================================================
+ *
+ * The Apache Software License, Version 1.1
+ *
+ * Copyright (c) 1999 The Apache Software Foundation.  All rights 
+ * reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. The end-user documentation included with the redistribution, if
+ *    any, must include the following acknowledgement:
+ *       "This product includes software developed by the 
+ *        Apache Software Foundation (http://www.apache.org/)."
+ *    Alternately, this acknowledgement may appear in the software itself,
+ *    if and wherever such third-party acknowledgements normally appear.
+ *
+ * 4. The names "The Jakarta Project", "Tomcat", and "Apache Software
+ *    Foundation" must not be used to endorse or promote products derived
+ *    from this software without prior written permission. For written 
+ *    permission, please contact apache@apache.org.
+ *
+ * 5. Products derived from this software may not be called "Apache"
+ *    nor may "Apache" appear in their names without prior written
+ *    permission of the Apache Software Foundation.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation.  For more
+ * information on the Apache Software Foundation, please see
+ * <http://www.apache.org/>.
+ *
+ * [Additional notices, if required by prior licensing conditions]
+ *
+ */ 
+
+
+package org.apache.directory.naming;
+
+import java.util.Hashtable;
+import java.util.Enumeration;
+import javax.naming.Context;
+import javax.naming.Name;
+import javax.naming.LinkRef;
+import javax.naming.CompositeName;
+import javax.naming.NameParser;
+import javax.naming.Referenceable;
+import javax.naming.Reference;
+import javax.naming.NamingEnumeration;
+import javax.naming.NamingException;
+import javax.naming.NameNotFoundException;
+import javax.naming.NotContextException;
+import javax.naming.InitialContext;
+import javax.naming.OperationNotSupportedException;
+import javax.naming.spi.NamingManager;
+
+/**
+ * Catalina JNDI Context implementation.
+ *
+ * @author Remy Maucherat
+ * @version $Revision: 1.3 $ $Date: 2003/11/30 05:22:15 $
+ */
+
+public class NamingContext implements Context {
+
+
+    // -------------------------------------------------------------- Constants
+
+
+    /**
+     * Name parser for this context.
+     */
+    protected static final NameParser nameParser = new NameParserImpl();
+
+
+    // ----------------------------------------------------------- Constructors
+
+
+    /**
+     * Builds a naming context using the given environment.
+     */
+    public NamingContext(Hashtable env, String name) 
+        throws NamingException {
+        this.bindings = new Hashtable();
+        this.env = new Hashtable();
+        // FIXME ? Could be put in the environment ?
+        this.name = name;
+        // Populating the environment hashtable
+        if (env != null ) {
+            Enumeration envEntries = env.keys();
+            while (envEntries.hasMoreElements()) {
+                String entryName = (String) envEntries.nextElement();
+                addToEnvironment(entryName, env.get(entryName));
+            }
+        }
+    }
+
+
+    /**
+     * Builds a naming context using the given environment.
+     */
+    public NamingContext(Hashtable env, String name, Hashtable bindings) 
+        throws NamingException {
+        this(env, name);
+        this.bindings = bindings;
+    }
+
+
+    // ----------------------------------------------------- Instance Variables
+
+
+    /**
+     * Environment.
+     */
+    protected Hashtable env;
+
+
+    /**
+     * The string manager for this package.
+     */
+    protected StringManager sm = StringManager.getManager(Constants.Package);
+
+
+    /**
+     * Bindings in this Context.
+     */
+    protected Hashtable bindings;
+
+
+    /**
+     * Name of the associated Catalina Context.
+     */
+    protected String name;
+
+
+    // --------------------------------------------------------- Public Methods
+
+
+    // -------------------------------------------------------- Context Methods
+
+
+    /**
+     * Retrieves the named object. If name is empty, returns a new instance 
+     * of this context (which represents the same naming context as this 
+     * context, but its environment may be modified independently and it may 
+     * be accessed concurrently).
+     * 
+     * @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(Name name)
+        throws NamingException {
+        return lookup(name, true);
+    }
+
+
+    /**
+     * 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 {
+        return lookup(new CompositeName(name), true);
+    }
+
+
+    /**
+     * Binds a name to an object. All intermediate contexts and the target 
+     * context (that named by all but terminal atomic component of the name) 
+     * must already exist.
+     * 
+     * @param name the name to bind; may not be empty
+     * @param obj the object to bind; possibly null
+     * @exception NameAlreadyBoundException if name is already bound
+     * @exception InvalidAttributesException if object did not supply all 
+     * mandatory attributes
+     * @exception NamingException if a naming exception is encountered
+     */
+    public void bind(Name name, Object obj)
+        throws NamingException {
+        bind(name, obj, false);
+    }
+
+
+    /**
+     * Binds a name to an object.
+     * 
+     * @param name the name to bind; may not be empty
+     * @param obj the object to bind; possibly null
+     * @exception NameAlreadyBoundException if name is already bound
+     * @exception InvalidAttributesException if object did not supply all 
+     * mandatory attributes
+     * @exception NamingException if a naming exception is encountered
+     */
+    public void bind(String name, Object obj)
+        throws NamingException {
+        bind(new CompositeName(name), obj);
+    }
+
+
+    /**
+     * Binds a name to an object, overwriting any existing binding. All 
+     * intermediate contexts and the target context (that named by all but 
+     * terminal atomic component of the name) must already exist.
+     * <p>
+     * If the object is a DirContext, any existing attributes associated with 
+     * the name are replaced with those of the object. Otherwise, any 
+     * existing attributes associated with the name remain unchanged.
+     * 
+     * @param name the name to bind; may not be empty
+     * @param obj the object to bind; possibly null
+     * @exception InvalidAttributesException if object did not supply all 
+     * mandatory attributes
+     * @exception NamingException if a naming exception is encountered
+     */
+    public void rebind(Name name, Object obj)
+        throws NamingException {
+        bind(name, obj, true);
+    }
+
+
+    /**
+     * Binds a name to an object, overwriting any existing binding.
+     * 
+     * @param name the name to bind; may not be empty
+     * @param obj the object to bind; possibly null
+     * @exception InvalidAttributesException if object did not supply all 
+     * mandatory attributes
+     * @exception NamingException if a naming exception is encountered
+     */
+    public void rebind(String name, Object obj)
+        throws NamingException {
+        rebind(new CompositeName(name), obj);
+    }
+
+
+    /**
+     * Unbinds the named object. Removes the terminal atomic name in name 
+     * from the target context--that named by all but the terminal atomic 
+     * part of name.
+     * <p>
+     * This method is idempotent. It succeeds even if the terminal atomic 
+     * name is not bound in the target context, but throws 
+     * NameNotFoundException if any of the intermediate contexts do not exist. 
+     * 
+     * @param name the name to bind; may not be empty
+     * @exception NameNotFoundException if an intermediate context does not 
+     * exist
+     * @exception NamingException if a naming exception is encountered
+     */
+    public void unbind(Name name)
+        throws NamingException {
+        checkWritable();
+        
+	while ((!name.isEmpty()) && (name.get(0).length() == 0))
+	    name = name.getSuffix(1);
+        if (name.isEmpty())
+            throw new NamingException
+                (sm.getString("namingContext.invalidName"));
+        
+        NamingEntry entry = (NamingEntry) bindings.get(name.get(0));
+        
+        if (entry == null) {
+            throw new NameNotFoundException
+                (sm.getString("namingContext.nameNotBound", name.get(0)));
+        }
+        
+        if (name.size() > 1) {
+            if (entry.type == NamingEntry.CONTEXT) {
+                ((Context) entry.value).unbind(name.getSuffix(1));
+            } else {
+                throw new NamingException
+                    (sm.getString("namingContext.contextExpected"));
+            }
+        } else {
+            bindings.remove(name.get(0));
+        }
+        
+    }
+
+
+    /**
+     * Unbinds the named object.
+     * 
+     * @param name the name to bind; may not be empty
+     * @exception NameNotFoundException if an intermediate context does not 
+     * exist
+     * @exception NamingException if a naming exception is encountered
+     */
+    public void unbind(String name)
+        throws NamingException {
+        unbind(new CompositeName(name));
+    }
+
+
+    /**
+     * Binds a new name to the object bound to an old name, and unbinds the 
+     * old name. Both names are relative to this context. Any attributes 
+     * associated with the old name become associated with the new name. 
+     * Intermediate contexts of the old name are not changed.
+     * 
+     * @param oldName the name of the existing binding; may not be empty
+     * @param newName the name of the new binding; may not be empty
+     * @exception NameAlreadyBoundException if newName is already bound
+     * @exception NamingException if a naming exception is encountered
+     */
+    public void rename(Name oldName, Name newName)
+        throws NamingException {
+        Object value = lookup(oldName);
+        bind(newName, value);
+        unbind(oldName);
+    }
+
+
+    /**
+     * Binds a new name to the object bound to an old name, and unbinds the 
+     * old name.
+     * 
+     * @param oldName the name of the existing binding; may not be empty
+     * @param newName the name of the new binding; may not be empty
+     * @exception NameAlreadyBoundException if newName is already bound
+     * @exception NamingException if a naming exception is encountered
+     */
+    public void rename(String oldName, String newName)
+        throws NamingException {
+        rename(new CompositeName(oldName), new CompositeName(newName));
+    }
+
+
+    /**
+     * Enumerates the names bound in the named context, along with the class 
+     * names of objects bound to them. The contents of any subcontexts are 
+     * not included.
+     * <p>
+     * If a binding is added to or removed from this context, its effect on 
+     * an enumeration previously returned is undefined.
+     * 
+     * @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(Name name)
+        throws NamingException {
+        // Removing empty parts
+        while ((!name.isEmpty()) && (name.get(0).length() == 0))
+            name = name.getSuffix(1);
+        if (name.isEmpty()) {
+            return new NamingContextEnumeration(bindings.elements());
+        }
+        
+        NamingEntry entry = (NamingEntry) bindings.get(name.get(0));
+        
+        if (entry == null) {
+            throw new NameNotFoundException
+                (sm.getString("namingContext.nameNotBound", name.get(0)));
+        }
+        
+        if (entry.type != NamingEntry.CONTEXT) {
+            throw new NamingException
+                (sm.getString("namingContext.contextExpected"));
+        }
+        return ((Context) entry.value).list(name.getSuffix(1));
+    }
+
+
+    /**
+     * 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 {
+        return list(new CompositeName(name));
+    }
+
+
+    /**
+     * Enumerates the names bound in the named context, along with the 
+     * objects bound to them. The contents of any subcontexts are not 
+     * included.
+     * <p>
+     * If a binding is added to or removed from this context, its effect on 
+     * an enumeration previously returned is undefined.
+     * 
+     * @param name the name of the context to list
+     * @return an enumeration of the bindings in this context. 
+     * Each element of the enumeration is of type Binding.
+     * @exception NamingException if a naming exception is encountered
+     */
+    public NamingEnumeration listBindings(Name name)
+        throws NamingException {
+        // Removing empty parts
+        while ((!name.isEmpty()) && (name.get(0).length() == 0))
+            name = name.getSuffix(1);
+        if (name.isEmpty()) {
+            return new NamingContextBindingsEnumeration(bindings.elements());
+        }
+        
+        NamingEntry entry = (NamingEntry) bindings.get(name.get(0));
+        
+        if (entry == null) {
+            throw new NameNotFoundException
+                (sm.getString("namingContext.nameNotBound", name.get(0)));
+        }
+        
+        if (entry.type != NamingEntry.CONTEXT) {
+            throw new NamingException
+                (sm.getString("namingContext.contextExpected"));
+        }
+        return ((Context) entry.value).listBindings(name.getSuffix(1));
+    }
+
+
+    /**
+     * Enumerates the names bound in the named context, along with the 
+     * objects bound to them.
+     * 
+     * @param name the name of the context to list
+     * @return an enumeration of the bindings in this context. 
+     * Each element of the enumeration is of type Binding.
+     * @exception NamingException if a naming exception is encountered
+     */
+    public NamingEnumeration listBindings(String name)
+        throws NamingException {
+        return listBindings(new CompositeName(name));
+    }
+
+
+    /**
+     * Destroys the named context and removes it from the namespace. Any 
+     * attributes associated with the name are also removed. Intermediate 
+     * contexts are not destroyed.
+     * <p>
+     * This method is idempotent. It succeeds even if the terminal atomic 
+     * name is not bound in the target context, but throws 
+     * NameNotFoundException if any of the intermediate contexts do not exist. 
+     * 
+     * In a federated naming system, a context from one naming system may be 
+     * bound to a name in another. One can subsequently look up and perform 
+     * operations on the foreign context using a composite name. However, an 
+     * attempt destroy the context using this composite name will fail with 
+     * NotContextException, because the foreign context is not a "subcontext" 
+     * of the context in which it is bound. Instead, use unbind() to remove 
+     * the binding of the foreign context. Destroying the foreign context 
+     * requires that the destroySubcontext() be performed on a context from 
+     * the foreign context's "native" naming system.
+     * 
+     * @param name the name of the context to be destroyed; may not be empty
+     * @exception NameNotFoundException if an intermediate context does not 
+     * exist
+     * @exception NotContextException if the name is bound but does not name 
+     * a context, or does not name a context of the appropriate type
+     */
+    public void destroySubcontext(Name name)
+        throws NamingException {
+        
+        checkWritable();
+        
+	while ((!name.isEmpty()) && (name.get(0).length() == 0))
+	    name = name.getSuffix(1);
+        if (name.isEmpty())
+            throw new NamingException
+                (sm.getString("namingContext.invalidName"));
+        
+        NamingEntry entry = (NamingEntry) bindings.get(name.get(0));
+        
+        if (entry == null) {
+            throw new NameNotFoundException
+                (sm.getString("namingContext.nameNotBound", name.get(0)));
+        }
+        
+        if (name.size() > 1) {
+            if (entry.type == NamingEntry.CONTEXT) {
+                ((Context) entry.value).unbind(name.getSuffix(1));
+            } else {
+                throw new NamingException
+                    (sm.getString("namingContext.contextExpected"));
+            }
+        } else {
+            if (entry.type == NamingEntry.CONTEXT) {
+                ((Context) entry.value).close();
+                bindings.remove(name.get(0));
+            } else {
+                throw new NotContextException
+                    (sm.getString("namingContext.contextExpected"));
+            }
+        }
+        
+    }
+
+
+    /**
+     * Destroys the named context and removes it from the namespace.
+     * 
+     * @param name the name of the context to be destroyed; may not be empty
+     * @exception NameNotFoundException if an intermediate context does not 
+     * exist
+     * @exception NotContextException if the name is bound but does not name 
+     * a context, or does not name a context of the appropriate type
+     */
+    public void destroySubcontext(String name)
+        throws NamingException {
+        destroySubcontext(new CompositeName(name));
+    }
+
+
+    /**
+     * Creates and binds a new context. Creates a new context with the given 
+     * name and binds it in the target context (that named by all but 
+     * terminal atomic component of the name). All intermediate contexts and 
+     * the target context must already exist.
+     * 
+     * @param name the name of the context to create; may not be empty
+     * @return the newly created context
+     * @exception NameAlreadyBoundException if name is already bound
+     * @exception InvalidAttributesException if creation of the subcontext 
+     * requires specification of mandatory attributes
+     * @exception NamingException if a naming exception is encountered
+     */
+    public Context createSubcontext(Name name)
+        throws NamingException {
+        checkWritable();
+        
+        Context newContext = new NamingContext(env, this.name);
+        bind(name, newContext);
+        
+        return newContext;
+    }
+
+
+    /**
+     * Creates and binds a new context.
+     * 
+     * @param name the name of the context to create; may not be empty
+     * @return the newly created context
+     * @exception NameAlreadyBoundException if name is already bound
+     * @exception InvalidAttributesException if creation of the subcontext 
+     * requires specification of mandatory attributes
+     * @exception NamingException if a naming exception is encountered
+     */
+    public Context createSubcontext(String name)
+        throws NamingException {
+        return createSubcontext(new CompositeName(name));
+    }
+
+
+    /**
+     * Retrieves the named object, following links except for the terminal 
+     * atomic component of the name. If the object bound to name is not a 
+     * link, returns the object itself.
+     * 
+     * @param name the name of the object to look up
+     * @return the object bound to name, not following the terminal link 
+     * (if any).
+     * @exception NamingException if a naming exception is encountered
+     */
+    public Object lookupLink(Name name)
+        throws NamingException {
+        return lookup(name, false);
+    }
+
+
+    /**
+     * Retrieves the named object, following links except for the terminal 
+     * atomic component of the name.
+     * 
+     * @param name the name of the object to look up
+     * @return the object bound to name, not following the terminal link 
+     * (if any).
+     * @exception NamingException if a naming exception is encountered
+     */
+    public Object lookupLink(String name)
+        throws NamingException {
+        return lookup(new CompositeName(name), false);
+    }
+
+
+    /**
+     * Retrieves the parser associated with the named context. In a 
+     * federation of namespaces, different naming systems will parse names 
+     * differently. This method allows an application to get a parser for 
+     * parsing names into their atomic components using the naming convention 
+     * of a particular naming system. Within any single naming system, 
+     * NameParser objects returned by this method must be equal (using the 
+     * equals() test).
+     * 
+     * @param name the name of the context from which to get the parser
+     * @return a name parser that can parse compound names into their atomic 
+     * components
+     * @exception NamingException if a naming exception is encountered
+     */
+    public NameParser getNameParser(Name name)
+        throws NamingException {
+
+	while ((!name.isEmpty()) && (name.get(0).length() == 0))
+	    name = name.getSuffix(1);
+        if (name.isEmpty())
+            return nameParser;
+
+        if (name.size() > 1) {
+            Object obj = bindings.get(name.get(0));
+            if (obj instanceof Context) {
+                return ((Context) obj).getNameParser(name.getSuffix(1));
+            } else {
+                throw new NotContextException
+                    (sm.getString("namingContext.contextExpected"));
+            }
+        }
+
+        return nameParser;
+
+    }
+
+
+    /**
+     * Retrieves the parser associated with the named context.
+     * 
+     * @param name the name of the context from which to get the parser
+     * @return a name parser that can parse compound names into their atomic 
+     * components
+     * @exception NamingException if a naming exception is encountered
+     */
+    public NameParser getNameParser(String name)
+        throws NamingException {
+        return getNameParser(new CompositeName(name));
+    }
+
+
+    /**
+     * Composes the name of this context with a name relative to this context.
+     * <p>
+     * Given a name (name) relative to this context, and the name (prefix) 
+     * of this context relative to one of its ancestors, this method returns 
+     * the composition of the two names using the syntax appropriate for the 
+     * naming system(s) involved. That is, if name names an object relative 
+     * to this context, the result is the name of the same object, but 
+     * relative to the ancestor context. None of the names may be null.
+     * 
+     * @param name a name relative to this context
+     * @param prefix the name of this context relative to one of its ancestors
+     * @return the composition of prefix and name
+     * @exception NamingException if a naming exception is encountered
+     */
+    public Name composeName(Name name, Name prefix)
+        throws NamingException {
+	Name result = (Name) prefix.clone();
+	return result.addAll(name);
+    }
+
+
+    /**
+     * Composes the name of this context with a name relative to this context.
+     * 
+     * @param name a name relative to this context
+     * @param prefix the name of this context relative to one of its ancestors
+     * @return the composition of prefix and name
+     * @exception NamingException if a naming exception is encountered
+     */
+    public String composeName(String name, String prefix)
+        throws NamingException {
+        return prefix + "/" + name;
+    }
+
+
+    /**
+     * Adds a new environment property to the environment of this context. If 
+     * the property already exists, its value is overwritten.
+     * 
+     * @param propName the name of the environment property to add; may not 
+     * be null
+     * @param propVal the value of the property to add; may not be null
+     * @exception NamingException if a naming exception is encountered
+     */
+    public Object addToEnvironment(String propName, Object propVal)
+        throws NamingException {
+        return env.put(propName, propVal);
+    }
+
+
+    /**
+     * Removes an environment property from the environment of this context. 
+     * 
+     * @param propName the name of the environment property to remove; 
+     * may not be null
+     * @exception NamingException if a naming exception is encountered
+     */
+    public Object removeFromEnvironment(String propName)
+        throws NamingException {
+        return env.remove(propName);
+    }
+
+
+    /**
+     * Retrieves the environment in effect for this context. See class 
+     * description for more details on environment properties. 
+     * The caller should not make any changes to the object returned: their 
+     * effect on the context is undefined. The environment of this context 
+     * may be changed using addToEnvironment() and removeFromEnvironment().
+     * 
+     * @return the environment of this context; never null
+     * @exception NamingException if a naming exception is encountered
+     */
+    public Hashtable getEnvironment()
+        throws NamingException {
+        return env;
+    }
+
+
+    /**
+     * Closes this context. This method releases this context's resources 
+     * immediately, instead of waiting for them to be released automatically 
+     * by the garbage collector.
+     * This method is idempotent: invoking it on a context that has already 
+     * been closed has no effect. Invoking any other method on a closed 
+     * context is not allowed, and results in undefined behaviour.
+     * 
+     * @exception NamingException if a naming exception is encountered
+     */
+    public void close()
+        throws NamingException {
+        env.clear();
+    }
+
+
+    /**
+     * Retrieves the full name of this context within its own namespace.
+     * <p>
+     * Many naming services have a notion of a "full name" for objects in 
+     * their respective namespaces. For example, an LDAP entry has a 
+     * distinguished name, and a DNS record has a fully qualified name. This 
+     * method allows the client application to retrieve this name. The string 
+     * returned by this method is not a JNDI composite name and should not be 
+     * passed directly to context methods. In naming systems for which the 
+     * notion of full name does not make sense, 
+     * OperationNotSupportedException is thrown.
+     * 
+     * @return this context's name in its own namespace; never null
+     * @exception OperationNotSupportedException if the naming system does 
+     * not have the notion of a full name
+     * @exception NamingException if a naming exception is encountered
+     */
+    public String getNameInNamespace()
+        throws NamingException {
+        throw  new OperationNotSupportedException
+            (sm.getString("namingContext.noAbsoluteName"));
+        //FIXME ?
+    }
+
+
+    // ------------------------------------------------------ Protected Methods
+
+
+    /**
+     * Retrieves the named object.
+     * 
+     * @param name the name of the object to look up
+     * @param resolveLinks If true, the links will be resolved
+     * @return the object bound to name
+     * @exception NamingException if a naming exception is encountered
+     */
+    protected Object lookup(Name name, boolean resolveLinks)
+        throws NamingException {
+
+        // Removing empty parts
+        while ((!name.isEmpty()) && (name.get(0).length() == 0))
+            name = name.getSuffix(1);
+        if (name.isEmpty()) {
+            // If name is empty, a newly allocated naming context is returned
+            return new NamingContext(env, this.name, bindings);
+        }
+        
+        NamingEntry entry = (NamingEntry) bindings.get(name.get(0));
+        
+        if (entry == null) {
+            throw new NameNotFoundException
+                (sm.getString("namingContext.nameNotBound", name.get(0)));
+        }
+        
+        if (name.size() > 1) {
+            // If the size of the name is greater that 1, then we go through a
+            // number of subcontexts.
+            if (entry.type != NamingEntry.CONTEXT) {
+                throw new NamingException
+                    (sm.getString("namingContext.contextExpected"));
+            }
+            return ((Context) entry.value).lookup(name.getSuffix(1));
+        } else {
+            if ((resolveLinks) && (entry.type == NamingEntry.LINK_REF)) {
+                String link = ((LinkRef) entry.value).getLinkName();
+                if (link.startsWith(".")) {
+                    // Link relative to this context
+                    return lookup(link.substring(1));
+                } else {
+                    return (new InitialContext(env)).lookup(link);
+                }
+            } else if (entry.type == NamingEntry.REFERENCE) {
+                try {
+                    Object obj = NamingManager.getObjectInstance
+                        (entry.value, name, this, env);
+                    if (obj != null) {
+                        entry.value = obj;
+                        entry.type = NamingEntry.ENTRY;
+                    }
+                    return obj;
+                } catch (NamingException e) {
+                    throw e;
+                } catch (Exception e) {
+                    throw new NamingException(e.getMessage());
+                }
+            } else {
+                return entry.value;
+            }
+        }
+        
+    }
+
+
+    /**
+     * Binds a name to an object. All intermediate contexts and the target 
+     * context (that named by all but terminal atomic component of the name) 
+     * must already exist.
+     * 
+     * @param name the name to bind; may not be empty
+     * @param obj the object to bind; possibly null
+     * @param rebind if true, then perform a rebind (ie, overwrite)
+     * @exception NameAlreadyBoundException if name is already bound
+     * @exception InvalidAttributesException if object did not supply all 
+     * mandatory attributes
+     * @exception NamingException if a naming exception is encountered
+     */
+    protected void bind(Name name, Object obj, boolean rebind)
+        throws NamingException {
+        
+        checkWritable();
+        
+	while ((!name.isEmpty()) && (name.get(0).length() == 0))
+	    name = name.getSuffix(1);
+        if (name.isEmpty())
+            throw new NamingException
+                (sm.getString("namingContext.invalidName"));
+        
+        NamingEntry entry = (NamingEntry) bindings.get(name.get(0));
+        
+        if (name.size() > 1) {
+            if (entry == null) {
+                throw new NameNotFoundException
+                    (sm.getString("namingContext.nameNotBound", name.get(0)));
+            }
+            if (entry.type == NamingEntry.CONTEXT) {
+                if (rebind) {
+                    ((Context) entry.value).rebind(name.getSuffix(1), obj);
+                } else {
+                    ((Context) entry.value).bind(name.getSuffix(1), obj);
+                }
+            } else {
+                throw new NamingException
+                    (sm.getString("namingContext.contextExpected"));
+            }
+        } else {
+            if ((!rebind) && (entry != null)) {
+                throw new NamingException
+                    (sm.getString("namingContext.alreadyBound", name.get(0)));
+            } else {
+                // Getting the type of the object and wrapping it within a new
+                // NamingEntry
+                Object toBind = 
+                    NamingManager.getStateToBind(obj, name, this, env);
+                if (toBind instanceof Context) {
+                    entry = new NamingEntry(name.get(0), toBind, 
+                                            NamingEntry.CONTEXT);
+                } else if (toBind instanceof LinkRef) {
+                    entry = new NamingEntry(name.get(0), toBind, 
+                                            NamingEntry.LINK_REF);
+                } else if (toBind instanceof Reference) {
+                    entry = new NamingEntry(name.get(0), toBind, 
+                                            NamingEntry.REFERENCE);
+                } else if (toBind instanceof Referenceable) {
+                    toBind = ((Referenceable) toBind).getReference();
+                    entry = new NamingEntry(name.get(0), toBind, 
+                                            NamingEntry.REFERENCE);
+                } else {
+                    entry = new NamingEntry(name.get(0), toBind, 
+                                            NamingEntry.ENTRY);
+                }
+                bindings.put(name.get(0), entry);
+            }
+        }
+        
+    }
+
+
+    /**
+     * Returns true if writing is allowed on this context.
+     */
+    protected boolean isWritable() {
+        return ContextAccessController.isWritable(name);
+    }
+
+
+    /**
+     * Throws a naming exception is Context is not writable.
+     */
+    protected void checkWritable() 
+        throws NamingException {
+        if (!isWritable())
+            throw new NamingException(sm.getString("namingContext.readOnly"));
+    }
+
+
+}
+

Added: incubator/directory/naming/trunk/core/src/java/org/apache/directory/naming/NamingContextBindingsEnumeration.java
==============================================================================
--- (empty file)
+++ incubator/directory/naming/trunk/core/src/java/org/apache/directory/naming/NamingContextBindingsEnumeration.java	Sun Dec  7 13:00:05 2003
@@ -0,0 +1,149 @@
+/*
+ * $Header: /home/cvs/jakarta-commons-sandbox/naming/core/src/java/org/apache/commons/naming/NamingContextBindingsEnumeration.java,v 1.2 2003/10/13 08:16:47 rdonkin Exp $
+ * $Revision: 1.2 $
+ * $Date: 2003/10/13 08:16:47 $
+ *
+ * ====================================================================
+ *
+ * The Apache Software License, Version 1.1
+ *
+ * Copyright (c) 1999 The Apache Software Foundation.  All rights 
+ * reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. The end-user documentation included with the redistribution, if
+ *    any, must include the following acknowledgement:
+ *       "This product includes software developed by the 
+ *        Apache Software Foundation (http://www.apache.org/)."
+ *    Alternately, this acknowledgement may appear in the software itself,
+ *    if and wherever such third-party acknowledgements normally appear.
+ *
+ * 4. The names "The Jakarta Project", "Tomcat", and "Apache Software
+ *    Foundation" must not be used to endorse or promote products derived
+ *    from this software without prior written permission. For written 
+ *    permission, please contact apache@apache.org.
+ *
+ * 5. Products derived from this software may not be called "Apache"
+ *    nor may "Apache" appear in their names without prior written
+ *    permission of the Apache Software Foundation.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation.  For more
+ * information on the Apache Software Foundation, please see
+ * <http://www.apache.org/>.
+ *
+ * [Additional notices, if required by prior licensing conditions]
+ *
+ */ 
+
+
+package org.apache.directory.naming;
+
+import java.util.Hashtable;
+import java.util.Vector;
+import java.util.Enumeration;
+import javax.naming.NamingException;
+import javax.naming.NamingEnumeration;
+import javax.naming.Binding;
+
+/**
+ * Naming enumeration implementation.
+ *
+ * @author Remy Maucherat
+ * @version $Revision: 1.2 $ $Date: 2003/10/13 08:16:47 $
+ */
+
+public class NamingContextBindingsEnumeration 
+    implements NamingEnumeration {
+
+
+    // ----------------------------------------------------------- Constructors
+
+
+    public NamingContextBindingsEnumeration(Vector entries) {
+        enum = entries.elements();
+    }
+
+
+    public NamingContextBindingsEnumeration(Enumeration enum) {
+        this.enum = enum;
+    }
+
+
+    // -------------------------------------------------------------- Variables
+
+
+    /**
+     * Underlying enumeration.
+     */
+    protected Enumeration enum;
+
+
+    // --------------------------------------------------------- Public Methods
+
+
+    /**
+     * Retrieves the next element in the enumeration.
+     */
+    public Object next()
+        throws NamingException {
+        return nextElement();
+    }
+
+
+    /**
+     * Determines whether there are any more elements in the enumeration.
+     */
+    public boolean hasMore()
+        throws NamingException {
+        return enum.hasMoreElements();
+    }
+
+
+    /**
+     * Closes this enumeration.
+     */
+    public void close()
+        throws NamingException {
+    }
+
+
+    public boolean hasMoreElements() {
+        return enum.hasMoreElements();
+    }
+
+
+    public Object nextElement() {
+        NamingEntry entry = (NamingEntry) enum.nextElement();
+        return new Binding(entry.name, entry.value.getClass().getName(), 
+                           entry.value, true);
+    }
+
+
+}
+

Added: incubator/directory/naming/trunk/core/src/java/org/apache/directory/naming/NamingContextEnumeration.java
==============================================================================
--- (empty file)
+++ incubator/directory/naming/trunk/core/src/java/org/apache/directory/naming/NamingContextEnumeration.java	Sun Dec  7 13:00:05 2003
@@ -0,0 +1,148 @@
+/*
+ * $Header: /home/cvs/jakarta-commons-sandbox/naming/core/src/java/org/apache/commons/naming/NamingContextEnumeration.java,v 1.2 2003/10/13 08:16:47 rdonkin Exp $
+ * $Revision: 1.2 $
+ * $Date: 2003/10/13 08:16:47 $
+ *
+ * ====================================================================
+ *
+ * The Apache Software License, Version 1.1
+ *
+ * Copyright (c) 1999 The Apache Software Foundation.  All rights 
+ * reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. The end-user documentation included with the redistribution, if
+ *    any, must include the following acknowledgement:
+ *       "This product includes software developed by the 
+ *        Apache Software Foundation (http://www.apache.org/)."
+ *    Alternately, this acknowledgement may appear in the software itself,
+ *    if and wherever such third-party acknowledgements normally appear.
+ *
+ * 4. The names "The Jakarta Project", "Tomcat", and "Apache Software
+ *    Foundation" must not be used to endorse or promote products derived
+ *    from this software without prior written permission. For written 
+ *    permission, please contact apache@apache.org.
+ *
+ * 5. Products derived from this software may not be called "Apache"
+ *    nor may "Apache" appear in their names without prior written
+ *    permission of the Apache Software Foundation.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation.  For more
+ * information on the Apache Software Foundation, please see
+ * <http://www.apache.org/>.
+ *
+ * [Additional notices, if required by prior licensing conditions]
+ *
+ */ 
+
+
+package org.apache.directory.naming;
+
+import java.util.Hashtable;
+import java.util.Vector;
+import java.util.Enumeration;
+import javax.naming.NamingException;
+import javax.naming.NamingEnumeration;
+import javax.naming.NameClassPair;
+
+/**
+ * Naming enumeration implementation.
+ *
+ * @author Remy Maucherat
+ * @version $Revision: 1.2 $ $Date: 2003/10/13 08:16:47 $
+ */
+
+public class NamingContextEnumeration 
+    implements NamingEnumeration {
+
+
+    // ----------------------------------------------------------- Constructors
+
+
+    public NamingContextEnumeration(Vector entries) {
+        enum = entries.elements();
+    }
+
+
+    public NamingContextEnumeration(Enumeration enum) {
+        this.enum = enum;
+    }
+
+
+    // -------------------------------------------------------------- Variables
+
+
+    /**
+     * Underlying enumeration.
+     */
+    protected Enumeration enum;
+
+
+    // --------------------------------------------------------- Public Methods
+
+
+    /**
+     * Retrieves the next element in the enumeration.
+     */
+    public Object next()
+        throws NamingException {
+        return nextElement();
+    }
+
+
+    /**
+     * Determines whether there are any more elements in the enumeration.
+     */
+    public boolean hasMore()
+        throws NamingException {
+        return enum.hasMoreElements();
+    }
+
+
+    /**
+     * Closes this enumeration.
+     */
+    public void close()
+        throws NamingException {
+    }
+
+
+    public boolean hasMoreElements() {
+        return enum.hasMoreElements();
+    }
+
+
+    public Object nextElement() {
+        NamingEntry entry = (NamingEntry) enum.nextElement();
+        return new NameClassPair(entry.name, entry.value.getClass().getName());
+    }
+
+
+}
+

Added: incubator/directory/naming/trunk/core/src/java/org/apache/directory/naming/NamingEntry.java
==============================================================================
--- (empty file)
+++ incubator/directory/naming/trunk/core/src/java/org/apache/directory/naming/NamingEntry.java	Sun Dec  7 13:00:05 2003
@@ -0,0 +1,127 @@
+/*
+ * $Header: /home/cvs/jakarta-commons-sandbox/naming/core/src/java/org/apache/commons/naming/NamingEntry.java,v 1.2 2003/10/13 08:16:47 rdonkin Exp $
+ * $Revision: 1.2 $
+ * $Date: 2003/10/13 08:16:47 $
+ *
+ * ====================================================================
+ *
+ * The Apache Software License, Version 1.1
+ *
+ * Copyright (c) 1999 The Apache Software Foundation.  All rights 
+ * reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. The end-user documentation included with the redistribution, if
+ *    any, must include the following acknowledgement:
+ *       "This product includes software developed by the 
+ *        Apache Software Foundation (http://www.apache.org/)."
+ *    Alternately, this acknowledgement may appear in the software itself,
+ *    if and wherever such third-party acknowledgements normally appear.
+ *
+ * 4. The names "The Jakarta Project", "Tomcat", and "Apache Software
+ *    Foundation" must not be used to endorse or promote products derived
+ *    from this software without prior written permission. For written 
+ *    permission, please contact apache@apache.org.
+ *
+ * 5. Products derived from this software may not be called "Apache"
+ *    nor may "Apache" appear in their names without prior written
+ *    permission of the Apache Software Foundation.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation.  For more
+ * information on the Apache Software Foundation, please see
+ * <http://www.apache.org/>.
+ *
+ * [Additional notices, if required by prior licensing conditions]
+ *
+ */ 
+
+
+package org.apache.directory.naming;
+
+
+/**
+ * Represents a binding in a NamingContext.
+ *
+ * @author Remy Maucherat
+ * @version $Revision: 1.2 $ $Date: 2003/10/13 08:16:47 $
+ */
+
+public class NamingEntry {
+
+
+    // -------------------------------------------------------------- Constants
+
+
+    public static final int ENTRY = 0;
+    public static final int LINK_REF = 1;
+    public static final int REFERENCE = 2;
+    
+    public static final int CONTEXT = 10;
+
+
+    // ----------------------------------------------------------- Constructors
+
+
+    public NamingEntry(String name, Object value, int type) {
+        this.name = name;
+        this.value = value;
+        this.type = type;
+    }
+
+
+    // ----------------------------------------------------- Instance Variables
+
+
+    /**
+     * The type instance variable is used to avoid unsing RTTI when doing
+     * lookups.
+     */
+    public int type;
+    public String name;
+    public Object value;
+
+
+    // --------------------------------------------------------- Object Methods
+
+
+    public boolean equals(Object obj) {
+        if ((obj != null) && (obj instanceof NamingEntry)) {
+            return name.equals(((NamingEntry) obj).name);
+        } else {
+            return false;
+        }
+    }
+
+
+    public int hashCode() {
+        return name.hashCode();
+    }
+
+
+}

Added: incubator/directory/naming/trunk/core/src/java/org/apache/directory/naming/NamingService.java
==============================================================================
--- (empty file)
+++ incubator/directory/naming/trunk/core/src/java/org/apache/directory/naming/NamingService.java	Sun Dec  7 13:00:05 2003
@@ -0,0 +1,276 @@
+/*
+ * $Header: /home/cvs/jakarta-commons-sandbox/naming/core/src/java/org/apache/commons/naming/NamingService.java,v 1.2 2003/10/13 08:16:47 rdonkin Exp $
+ * $Revision: 1.2 $
+ * $Date: 2003/10/13 08:16:47 $
+ *
+ * ====================================================================
+ *
+ * The Apache Software License, Version 1.1
+ *
+ * Copyright (c) 1999 The Apache Software Foundation.  All rights 
+ * reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. The end-user documentation included with the redistribution, if
+ *    any, must include the following acknowledgement:
+ *       "This product includes software developed by the 
+ *        Apache Software Foundation (http://www.apache.org/)."
+ *    Alternately, this acknowledgement may appear in the software itself,
+ *    if and wherever such third-party acknowledgements normally appear.
+ *
+ * 4. The names "The Jakarta Project", "Tomcat", and "Apache Software
+ *    Foundation" must not be used to endorse or promote products derived
+ *    from this software without prior written permission. For written 
+ *    permission, please contact apache@apache.org.
+ *
+ * 5. Products derived from this software may not be called "Apache"
+ *    nor may "Apache" appear in their names without prior written
+ *    permission of the Apache Software Foundation.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation.  For more
+ * information on the Apache Software Foundation, please see
+ * <http://www.apache.org/>.
+ *
+ * [Additional notices, if required by prior licensing conditions]
+ *
+ */ 
+
+package org.apache.directory.naming;
+
+import javax.naming.Context;
+import javax.management.NotificationBroadcasterSupport;
+import javax.management.ObjectName;
+import javax.management.MBeanServer;
+import javax.management.MBeanRegistration;
+import javax.management.AttributeChangeNotification;
+import javax.management.Notification;
+
+/**
+ * Implementation of the NamingService JMX MBean.
+ * 
+ * @author <a href="mailto:remm@apache.org">Remy Maucherat</a>
+ * @version $Revision: 1.2 $
+ */
+
+public final class NamingService
+    extends NotificationBroadcasterSupport
+    implements NamingServiceMBean, MBeanRegistration {
+    
+    
+    // ----------------------------------------------------- Instance Variables
+    
+    
+    /**
+     * Status of the Slide domain.
+     */
+    private int state = STOPPED;
+    
+    
+    /**
+     * Notification sequence number.
+     */
+    private long sequenceNumber = 0;
+    
+    
+    /**
+     * Old URL packages value.
+     */
+    private String oldUrlValue = "";
+    
+    
+    /**
+     * Old initial context value.
+     */
+    private String oldIcValue = "";
+    
+    
+    // ---------------------------------------------- MBeanRegistration Methods
+    
+    
+    public ObjectName preRegister(MBeanServer server, ObjectName name)
+        throws Exception {
+        return new ObjectName(OBJECT_NAME);
+    }
+    
+    
+    public void postRegister(Boolean registrationDone) {
+        if (!registrationDone.booleanValue())
+            destroy();
+    }
+    
+    
+    public void preDeregister()
+        throws Exception {
+    }
+    
+    
+    public void postDeregister() {
+        destroy();
+    }
+    
+    
+    // ----------------------------------------------------- SlideMBean Methods
+    
+    
+    /**
+     * Retruns the Catalina component name.
+     */
+    public String getName() {
+        return NAME;
+    }
+    
+    
+    /**
+     * Returns the state.
+     */
+    public int getState() {
+        return state;
+    }
+    
+    
+    /**
+     * Returns a String representation of the state.
+     */
+    public String getStateString() {
+        return states[state];
+    }
+    
+    
+    /**
+     * Start the servlet container.
+     */
+    public void start()
+        throws Exception {
+        
+        Notification notification = null;
+        
+        if (state != STOPPED)
+            return;
+        
+        state = STARTING;
+        
+        // Notifying the MBEan server that we're starting
+        
+        notification = new AttributeChangeNotification
+            (this, sequenceNumber++, System.currentTimeMillis(), 
+             "Starting " + NAME, "State", "java.lang.Integer", 
+             new Integer(STOPPED), new Integer(STARTING));
+        sendNotification(notification);
+        
+        try {
+            
+            String value = "org.apache.naming";
+            String oldValue = System.getProperty(Context.URL_PKG_PREFIXES);
+            if (oldValue != null) {
+                oldUrlValue = oldValue;
+                value = oldValue + ":" + value;
+            }
+            System.setProperty(Context.URL_PKG_PREFIXES, value);
+            
+            oldValue = System.getProperty(Context.INITIAL_CONTEXT_FACTORY);
+            if (oldValue != null) {
+                oldIcValue = oldValue;
+            } else {
+                System.setProperty(Context.INITIAL_CONTEXT_FACTORY,
+                                   Constants.Package 
+                                   + ".java.javaURLContextFactory");
+            }
+            
+        } catch (Throwable t) {
+            state = STOPPED;
+            notification = new AttributeChangeNotification
+                (this, sequenceNumber++, System.currentTimeMillis(), 
+                 "Stopped " + NAME, "State", "java.lang.Integer", 
+                 new Integer(STARTING), new Integer(STOPPED));
+            sendNotification(notification);
+        }
+        
+        state = STARTED;
+        notification = new AttributeChangeNotification
+            (this, sequenceNumber++, System.currentTimeMillis(), 
+             "Started " + NAME, "State", "java.lang.Integer", 
+             new Integer(STARTING), new Integer(STARTED));
+        sendNotification(notification);
+        
+    }
+    
+    
+    /**
+     * Stop the servlet container.
+     */
+    public void stop() {
+        
+        Notification notification = null;
+        
+        if (state != STARTED)
+            return;
+        
+        state = STOPPING;
+        
+        notification = new AttributeChangeNotification
+            (this, sequenceNumber++, System.currentTimeMillis(), 
+             "Stopping " + NAME, "State", "java.lang.Integer", 
+             new Integer(STARTED), new Integer(STOPPING));
+        sendNotification(notification);
+        
+        try {
+            
+            System.setProperty(Context.URL_PKG_PREFIXES, oldUrlValue);
+            System.setProperty(Context.INITIAL_CONTEXT_FACTORY, oldIcValue);
+            
+        } catch (Throwable t) {
+            
+            // FIXME
+            t.printStackTrace();
+            
+        }
+        
+        state = STOPPED;
+        
+        notification = new AttributeChangeNotification
+            (this, sequenceNumber++, System.currentTimeMillis(), 
+             "Stopped " + NAME, "State", "java.lang.Integer", 
+             new Integer(STOPPING), new Integer(STOPPED));
+        sendNotification(notification);
+        
+    }
+    
+    
+    /**
+     * Destroy servlet container (if any is running).
+     */
+    public void destroy() {
+        
+        if (getState() != STOPPED)
+            stop();
+        
+    }
+    
+    
+}

Added: incubator/directory/naming/trunk/core/src/java/org/apache/directory/naming/NamingServiceMBean.java
==============================================================================
--- (empty file)
+++ incubator/directory/naming/trunk/core/src/java/org/apache/directory/naming/NamingServiceMBean.java	Sun Dec  7 13:00:05 2003
@@ -0,0 +1,144 @@
+/*
+ * $Header: /home/cvs/jakarta-commons-sandbox/naming/core/src/java/org/apache/commons/naming/NamingServiceMBean.java,v 1.2 2003/10/13 08:16:47 rdonkin Exp $
+ * $Revision: 1.2 $
+ * $Date: 2003/10/13 08:16:47 $
+ *
+ * ====================================================================
+ *
+ * The Apache Software License, Version 1.1
+ *
+ * Copyright (c) 1999 The Apache Software Foundation.  All rights 
+ * reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. The end-user documentation included with the redistribution, if
+ *    any, must include the following acknowledgement:
+ *       "This product includes software developed by the 
+ *        Apache Software Foundation (http://www.apache.org/)."
+ *    Alternately, this acknowledgement may appear in the software itself,
+ *    if and wherever such third-party acknowledgements normally appear.
+ *
+ * 4. The names "The Jakarta Project", "Tomcat", and "Apache Software
+ *    Foundation" must not be used to endorse or promote products derived
+ *    from this software without prior written permission. For written 
+ *    permission, please contact apache@apache.org.
+ *
+ * 5. Products derived from this software may not be called "Apache"
+ *    nor may "Apache" appear in their names without prior written
+ *    permission of the Apache Software Foundation.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation.  For more
+ * information on the Apache Software Foundation, please see
+ * <http://www.apache.org/>.
+ *
+ * [Additional notices, if required by prior licensing conditions]
+ *
+ */ 
+
+package org.apache.directory.naming;
+
+/**
+ * Naming MBean interface.
+ * 
+ * @author <a href="mailto:remm@apache.org">Remy Maucherat</a>
+ * @version $Revision: 1.2 $
+ */
+
+public interface NamingServiceMBean {
+    
+    
+    // -------------------------------------------------------------- Constants
+    
+    
+    /**
+     * Status constants.
+     */
+    public static final String[] states = 
+    {"Stopped", "Stopping", "Starting", "Started"};
+    
+    
+    public static final int STOPPED  = 0;
+    public static final int STOPPING = 1;
+    public static final int STARTING = 2;
+    public static final int STARTED  = 3;
+    
+    
+    /**
+     * Component name.
+     */
+    public static final String NAME = "Apache JNDI Naming Service";
+    
+    
+    /**
+     * Object name.
+     */
+    public static final String OBJECT_NAME = ":service=Naming";
+    
+    
+    // ------------------------------------------------------ Interface Methods
+    
+    
+    /**
+     * Retruns the JNDI component name.
+     */
+    public String getName();
+    
+    
+    /**
+     * Returns the state.
+     */
+    public int getState();
+    
+    
+    /**
+     * Returns a String representation of the state.
+     */
+    public String getStateString();
+    
+    
+    /**
+     * Start the servlet container.
+     */
+    public void start()
+        throws Exception;
+    
+    
+    /**
+     * Stop the servlet container.
+     */
+    public void stop();
+    
+    
+    /**
+     * Destroy servlet container (if any is running).
+     */
+    public void destroy();
+    
+    
+}

Added: incubator/directory/naming/trunk/core/src/java/org/apache/directory/naming/ResourceEnvRef.java
==============================================================================
--- (empty file)
+++ incubator/directory/naming/trunk/core/src/java/org/apache/directory/naming/ResourceEnvRef.java	Sun Dec  7 13:00:05 2003
@@ -0,0 +1,146 @@
+/*
+ * $Header: /home/cvs/jakarta-commons-sandbox/naming/core/src/java/org/apache/commons/naming/ResourceEnvRef.java,v 1.3 2003/11/30 05:15:06 psteitz Exp $
+ * $Revision: 1.3 $
+ * $Date: 2003/11/30 05:15:06 $
+ *
+ * ====================================================================
+ *
+ * The Apache Software License, Version 1.1
+ *
+ * Copyright (c) 1999 The Apache Software Foundation.  All rights 
+ * reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. The end-user documentation included with the redistribution, if
+ *    any, must include the following acknowledgement:
+ *       "This product includes software developed by the 
+ *        Apache Software Foundation (http://www.apache.org/)."
+ *    Alternately, this acknowledgement may appear in the software itself,
+ *    if and wherever such third-party acknowledgements normally appear.
+ *
+ * 4. The names "The Jakarta Project", "Tomcat", and "Apache Software
+ *    Foundation" must not be used to endorse or promote products derived
+ *    from this software without prior written permission. For written 
+ *    permission, please contact apache@apache.org.
+ *
+ * 5. Products derived from this software may not be called "Apache"
+ *    nor may "Apache" appear in their names without prior written
+ *    permission of the Apache Software Foundation.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation.  For more
+ * information on the Apache Software Foundation, please see
+ * <http://www.apache.org/>.
+ *
+ * [Additional notices, if required by prior licensing conditions]
+ *
+ */ 
+
+
+package org.apache.directory.naming;
+
+import java.util.Hashtable;
+import javax.naming.Reference;
+import javax.naming.Context;
+import javax.naming.StringRefAddr;
+
+/**
+ * Represents a reference address to a resource environment.
+ *
+ * @author Remy Maucherat
+ * @version $Revision: 1.3 $ $Date: 2003/11/30 05:15:06 $
+ */
+
+public class ResourceEnvRef
+    extends Reference {
+
+
+    // -------------------------------------------------------------- Constants
+
+
+    /**
+     * Default factory for this reference.
+     */
+    public static final String DEFAULT_FACTORY = Constants.DEFAULT_RESOURCE_ENV_FACTORY;
+
+
+    // ----------------------------------------------------------- Constructors
+
+
+    /**
+     * Resource env reference.
+     * 
+     * @param resourceType Type
+     */
+    public ResourceEnvRef(String resourceType) {
+        super(resourceType);
+    }
+
+
+    /**
+     * Resource env reference.
+     * 
+     * @param resourceType Type
+     * @param factory Resource Factory
+     * @param factoryLocation Factory location
+     */
+    public ResourceEnvRef(String resourceType, String factory,
+                          String factoryLocation) {
+        super(resourceType, factory, factoryLocation);
+    }
+
+
+    // ----------------------------------------------------- Instance Variables
+
+
+    // ------------------------------------------------------ Reference Methods
+
+
+    /**
+     * Retrieves the class name of the factory of the object to which this 
+     * reference refers.
+     */
+    public String getFactoryClassName() {
+        String factory = super.getFactoryClassName();
+        if (factory != null) {
+            return factory;
+        } else {
+            factory = System.getProperty(Context.OBJECT_FACTORIES);
+            if (factory != null) {
+                return null;
+            } else {
+                return DEFAULT_FACTORY;
+            }
+        }
+    }
+
+
+    // ------------------------------------------------------------- Properties
+
+
+}

Added: incubator/directory/naming/trunk/core/src/java/org/apache/directory/naming/ResourceLinkRef.java
==============================================================================
--- (empty file)
+++ incubator/directory/naming/trunk/core/src/java/org/apache/directory/naming/ResourceLinkRef.java	Sun Dec  7 13:00:05 2003
@@ -0,0 +1,158 @@
+/*
+ * $Header: /home/cvs/jakarta-commons-sandbox/naming/core/src/java/org/apache/commons/naming/ResourceLinkRef.java,v 1.2 2003/10/13 08:16:47 rdonkin Exp $
+ * $Revision: 1.2 $
+ * $Date: 2003/10/13 08:16:47 $
+ *
+ * ====================================================================
+ *
+ * The Apache Software License, Version 1.1
+ *
+ * Copyright (c) 1999 The Apache Software Foundation.  All rights 
+ * reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. The end-user documentation included with the redistribution, if
+ *    any, must include the following acknowledgement:
+ *       "This product includes software developed by the 
+ *        Apache Software Foundation (http://www.apache.org/)."
+ *    Alternately, this acknowledgement may appear in the software itself,
+ *    if and wherever such third-party acknowledgements normally appear.
+ *
+ * 4. The names "The Jakarta Project", "Tomcat", and "Apache Software
+ *    Foundation" must not be used to endorse or promote products derived
+ *    from this software without prior written permission. For written 
+ *    permission, please contact apache@apache.org.
+ *
+ * 5. Products derived from this software may not be called "Apache"
+ *    nor may "Apache" appear in their names without prior written
+ *    permission of the Apache Software Foundation.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation.  For more
+ * information on the Apache Software Foundation, please see
+ * <http://www.apache.org/>.
+ *
+ * [Additional notices, if required by prior licensing conditions]
+ *
+ */ 
+
+
+package org.apache.directory.naming;
+
+import java.util.Hashtable;
+import javax.naming.Reference;
+import javax.naming.Context;
+import javax.naming.StringRefAddr;
+
+/**
+ * Represents a reference address to a resource.
+ *
+ * @author Remy Maucherat
+ * @version $Revision: 1.2 $ $Date: 2003/10/13 08:16:47 $
+ */
+
+public class ResourceLinkRef
+    extends Reference {
+
+
+    // -------------------------------------------------------------- Constants
+
+
+    /**
+     * Default factory for this reference.
+     */
+    public static final String DEFAULT_FACTORY = 
+        Constants.DEFAULT_RESOURCE_LINK_FACTORY;
+
+
+    /**
+     * Description address type.
+     */
+    public static final String GLOBALNAME = "globalName";
+
+
+    // ----------------------------------------------------------- Constructors
+
+
+    /**
+     * ResourceLink Reference.
+     * 
+     * @param resourceClass Resource class
+     * @param globalName Global name
+     */
+    public ResourceLinkRef(String resourceClass, String globalName) {
+        this(resourceClass, globalName, null, null);
+    }
+
+
+    /**
+     * ResourceLink Reference.
+     * 
+     * @param resourceClass Resource class
+     * @param globalName Global name
+     */
+    public ResourceLinkRef(String resourceClass, String globalName, 
+                           String factory, String factoryLocation) {
+        super(resourceClass, factory, factoryLocation);
+        StringRefAddr refAddr = null;
+        if (globalName != null) {
+            refAddr = new StringRefAddr(GLOBALNAME, globalName);
+            add(refAddr);
+        }
+    }
+
+
+    // ----------------------------------------------------- Instance Variables
+
+
+    // ------------------------------------------------------ Reference Methods
+
+
+    /**
+     * Retrieves the class name of the factory of the object to which this 
+     * reference refers.
+     */
+    public String getFactoryClassName() {
+        String factory = super.getFactoryClassName();
+        if (factory != null) {
+            return factory;
+        } else {
+            factory = System.getProperty(Context.OBJECT_FACTORIES);
+            if (factory != null) {
+                return null;
+            } else {
+                return DEFAULT_FACTORY;
+            }
+        }
+    }
+
+
+    // ------------------------------------------------------------- Properties
+
+
+}

Added: incubator/directory/naming/trunk/core/src/java/org/apache/directory/naming/ResourceRef.java
==============================================================================
--- (empty file)
+++ incubator/directory/naming/trunk/core/src/java/org/apache/directory/naming/ResourceRef.java	Sun Dec  7 13:00:05 2003
@@ -0,0 +1,214 @@
+/*
+ * $Header: /home/cvs/jakarta-commons-sandbox/naming/core/src/java/org/apache/commons/naming/ResourceRef.java,v 1.2 2003/10/13 08:16:47 rdonkin Exp $
+ * $Revision: 1.2 $
+ * $Date: 2003/10/13 08:16:47 $
+ *
+ * ====================================================================
+ *
+ * The Apache Software License, Version 1.1
+ *
+ * Copyright (c) 1999 The Apache Software Foundation.  All rights 
+ * reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. The end-user documentation included with the redistribution, if
+ *    any, must include the following acknowledgement:
+ *       "This product includes software developed by the 
+ *        Apache Software Foundation (http://www.apache.org/)."
+ *    Alternately, this acknowledgement may appear in the software itself,
+ *    if and wherever such third-party acknowledgements normally appear.
+ *
+ * 4. The names "The Jakarta Project", "Tomcat", and "Apache Software
+ *    Foundation" must not be used to endorse or promote products derived
+ *    from this software without prior written permission. For written 
+ *    permission, please contact apache@apache.org.
+ *
+ * 5. Products derived from this software may not be called "Apache"
+ *    nor may "Apache" appear in their names without prior written
+ *    permission of the Apache Software Foundation.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation.  For more
+ * information on the Apache Software Foundation, please see
+ * <http://www.apache.org/>.
+ *
+ * [Additional notices, if required by prior licensing conditions]
+ *
+ */ 
+
+
+package org.apache.directory.naming;
+
+import java.util.Enumeration;
+import java.util.Hashtable;
+import javax.naming.RefAddr;
+import javax.naming.Reference;
+import javax.naming.Context;
+import javax.naming.StringRefAddr;
+
+/**
+ * Represents a reference address to a resource.
+ *
+ * @author Remy Maucherat
+ * @version $Revision: 1.2 $ $Date: 2003/10/13 08:16:47 $
+ */
+
+public class ResourceRef
+    extends Reference {
+
+
+    // -------------------------------------------------------------- Constants
+
+
+    /**
+     * Default factory for this reference.
+     */
+    public static final String DEFAULT_FACTORY = 
+        Constants.DEFAULT_RESOURCE_FACTORY;
+
+
+    /**
+     * Description address type.
+     */
+    public static final String DESCRIPTION = "description";
+
+
+    /**
+     * Scope address type.
+     */
+    public static final String SCOPE = "scope";
+
+
+    /**
+     * Auth address type.
+     */
+    public static final String AUTH = "auth";
+
+
+    // ----------------------------------------------------------- Constructors
+
+
+    /**
+     * Resource Reference.
+     * 
+     * @param resourceClass Resource class
+     * @param scope Resource scope
+     * @param auth Resource authetication
+     */
+    public ResourceRef(String resourceClass, String description, 
+                       String scope, String auth) {
+        this(resourceClass, description, scope, auth, null, null);
+    }
+
+
+    /**
+     * Resource Reference.
+     * 
+     * @param resourceClass Resource class
+     * @param scope Resource scope
+     * @param auth Resource authetication
+     */
+    public ResourceRef(String resourceClass, String description, 
+                       String scope, String auth, String factory,
+                       String factoryLocation) {
+        super(resourceClass, factory, factoryLocation);
+        StringRefAddr refAddr = null;
+        if (description != null) {
+            refAddr = new StringRefAddr(DESCRIPTION, description);
+            add(refAddr);
+        }
+        if (scope != null) {
+            refAddr = new StringRefAddr(SCOPE, scope);
+            add(refAddr);
+        }
+        if (auth != null) {
+            refAddr = new StringRefAddr(AUTH, auth);
+            add(refAddr);
+        }
+    }
+
+
+    // ----------------------------------------------------- Instance Variables
+
+
+    // ------------------------------------------------------ Reference Methods
+
+
+    /**
+     * Retrieves the class name of the factory of the object to which this 
+     * reference refers.
+     */
+    public String getFactoryClassName() {
+        String factory = super.getFactoryClassName();
+        if (factory != null) {
+            return factory;
+        } else {
+            factory = System.getProperty(Context.OBJECT_FACTORIES);
+            if (factory != null) {
+                return null;
+            } else {
+                return DEFAULT_FACTORY;
+            }
+        }
+    }
+
+
+    // --------------------------------------------------------- Public Methods
+
+
+    /**
+     * Return a String rendering of this object.
+     */
+    public String toString() {
+
+        StringBuffer sb = new StringBuffer("ResourceRef[");
+        sb.append("className=");
+        sb.append(getClassName());
+        sb.append(",factoryClassLocation=");
+        sb.append(getFactoryClassLocation());
+        sb.append(",factoryClassName=");
+        sb.append(getFactoryClassName());
+        Enumeration refAddrs = getAll();
+        while (refAddrs.hasMoreElements()) {
+            RefAddr refAddr = (RefAddr) refAddrs.nextElement();
+            sb.append(",{type=");
+            sb.append(refAddr.getType());
+            sb.append(",content=");
+            sb.append(refAddr.getContent());
+            sb.append("}");
+        }
+        sb.append("]");
+        return (sb.toString());
+
+    }
+
+
+    // ------------------------------------------------------------- Properties
+
+
+}

Added: incubator/directory/naming/trunk/core/src/java/org/apache/directory/naming/SelectorContext.java
==============================================================================
--- (empty file)
+++ incubator/directory/naming/trunk/core/src/java/org/apache/directory/naming/SelectorContext.java	Sun Dec  7 13:00:05 2003
@@ -0,0 +1,741 @@
+/*
+ * $Header: /home/cvs/jakarta-commons-sandbox/naming/core/src/java/org/apache/commons/naming/SelectorContext.java,v 1.3 2003/11/30 05:22:15 psteitz Exp $
+ * $Revision: 1.3 $
+ * $Date: 2003/11/30 05:22:15 $
+ *
+ * ====================================================================
+ *
+ * The Apache Software License, Version 1.1
+ *
+ * Copyright (c) 1999 The Apache Software Foundation.  All rights 
+ * reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. The end-user documentation included with the redistribution, if
+ *    any, must include the following acknowledgement:
+ *       "This product includes software developed by the 
+ *        Apache Software Foundation (http://www.apache.org/)."
+ *    Alternately, this acknowledgement may appear in the software itself,
+ *    if and wherever such third-party acknowledgements normally appear.
+ *
+ * 4. The names "The Jakarta Project", "Tomcat", and "Apache Software
+ *    Foundation" must not be used to endorse or promote products derived
+ *    from this software without prior written permission. For written 
+ *    permission, please contact apache@apache.org.
+ *
+ * 5. Products derived from this software may not be called "Apache"
+ *    nor may "Apache" appear in their names without prior written
+ *    permission of the Apache Software Foundation.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation.  For more
+ * information on the Apache Software Foundation, please see
+ * <http://www.apache.org/>.
+ *
+ * [Additional notices, if required by prior licensing conditions]
+ *
+ */ 
+
+
+package org.apache.directory.naming;
+
+import java.util.Hashtable;
+import javax.naming.Context;
+import javax.naming.Name;
+import javax.naming.NameParser;
+import javax.naming.NamingEnumeration;
+import javax.naming.NamingException;
+
+/**
+ * Catalina JNDI Context implementation.
+ *
+ * @author Remy Maucherat
+ * @version $Revision: 1.3 $ $Date: 2003/11/30 05:22:15 $
+ */
+
+public class SelectorContext implements Context {
+
+
+    // -------------------------------------------------------------- Constants
+
+
+    /**
+     * Namespace URL.
+     */
+    public static final String prefix = "java:";
+
+
+    /**
+     * Namespace URL length.
+     */
+    public static final int prefixLength = prefix.length();
+
+
+    /**
+     * Initial context prefix.
+     */
+    public static final String IC_PREFIX = "IC_";
+
+
+    // ----------------------------------------------------------- Constructors
+
+
+    /**
+     * Builds a Catalina selector context using the given environment.
+     */
+    public SelectorContext(Hashtable env) {
+        this.env = env;
+    }
+
+
+    /**
+     * Builds a Catalina selector context using the given environment.
+     */
+    public SelectorContext(Hashtable env, boolean initialContext) {
+        this(env);
+        this.initialContext = initialContext;
+    }
+
+
+    // ----------------------------------------------------- Instance Variables
+
+
+    /**
+     * Environment.
+     */
+    protected Hashtable env;
+
+
+    /**
+     * The string manager for this package.
+     */
+    protected StringManager sm = StringManager.getManager(Constants.Package);
+
+
+    /**
+     * Request for an initial context.
+     */
+    protected boolean initialContext = false;
+
+
+    // --------------------------------------------------------- Public Methods
+
+
+    // -------------------------------------------------------- Context Methods
+
+
+    /**
+     * Retrieves the named object. If name is empty, returns a new instance 
+     * of this context (which represents the same naming context as this 
+     * context, but its environment may be modified independently and it may 
+     * be accessed concurrently).
+     * 
+     * @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(Name name)
+        throws NamingException {
+        // Strip the URL header
+        // Find the appropriate NamingContext according to the current bindings
+        // Execute the lookup on that context
+        return getBoundContext().lookup(parseName(name));
+    }
+
+
+    /**
+     * 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 {
+        // Strip the URL header
+        // Find the appropriate NamingContext according to the current bindings
+        // Execute the lookup on that context
+        return getBoundContext().lookup(parseName(name));
+    }
+
+
+    /**
+     * Binds a name to an object. All intermediate contexts and the target 
+     * context (that named by all but terminal atomic component of the name) 
+     * must already exist.
+     * 
+     * @param name the name to bind; may not be empty
+     * @param obj the object to bind; possibly null
+     * @exception NameAlreadyBoundException if name is already bound
+     * @exception InvalidAttributesException if object did not supply all 
+     * mandatory attributes
+     * @exception NamingException if a naming exception is encountered
+     */
+    public void bind(Name name, Object obj)
+        throws NamingException {
+        getBoundContext().bind(parseName(name), obj);
+    }
+
+
+    /**
+     * Binds a name to an object.
+     * 
+     * @param name the name to bind; may not be empty
+     * @param obj the object to bind; possibly null
+     * @exception NameAlreadyBoundException if name is already bound
+     * @exception InvalidAttributesException if object did not supply all 
+     * mandatory attributes
+     * @exception NamingException if a naming exception is encountered
+     */
+    public void bind(String name, Object obj)
+        throws NamingException {
+        getBoundContext().bind(parseName(name), obj);
+    }
+
+
+    /**
+     * Binds a name to an object, overwriting any existing binding. All 
+     * intermediate contexts and the target context (that named by all but 
+     * terminal atomic component of the name) must already exist.
+     * <p>
+     * If the object is a DirContext, any existing attributes associated with 
+     * the name are replaced with those of the object. Otherwise, any 
+     * existing attributes associated with the name remain unchanged.
+     * 
+     * @param name the name to bind; may not be empty
+     * @param obj the object to bind; possibly null
+     * @exception InvalidAttributesException if object did not supply all 
+     * mandatory attributes
+     * @exception NamingException if a naming exception is encountered
+     */
+    public void rebind(Name name, Object obj)
+        throws NamingException {
+        getBoundContext().rebind(parseName(name), obj);
+    }
+
+
+    /**
+     * Binds a name to an object, overwriting any existing binding.
+     * 
+     * @param name the name to bind; may not be empty
+     * @param obj the object to bind; possibly null
+     * @exception InvalidAttributesException if object did not supply all 
+     * mandatory attributes
+     * @exception NamingException if a naming exception is encountered
+     */
+    public void rebind(String name, Object obj)
+        throws NamingException {
+        getBoundContext().rebind(parseName(name), obj);
+    }
+
+
+    /**
+     * Unbinds the named object. Removes the terminal atomic name in name 
+     * from the target context--that named by all but the terminal atomic 
+     * part of name.
+     * <p>
+     * This method is idempotent. It succeeds even if the terminal atomic 
+     * name is not bound in the target context, but throws 
+     * NameNotFoundException if any of the intermediate contexts do not exist. 
+     * 
+     * @param name the name to bind; may not be empty
+     * @exception NameNotFoundException if an intermediate context does not 
+     * exist
+     * @exception NamingException if a naming exception is encountered
+     */
+    public void unbind(Name name)
+        throws NamingException {
+        getBoundContext().unbind(parseName(name));
+    }
+
+
+    /**
+     * Unbinds the named object.
+     * 
+     * @param name the name to bind; may not be empty
+     * @exception NameNotFoundException if an intermediate context does not 
+     * exist
+     * @exception NamingException if a naming exception is encountered
+     */
+    public void unbind(String name)
+        throws NamingException {
+        getBoundContext().unbind(parseName(name));
+    }
+
+
+    /**
+     * Binds a new name to the object bound to an old name, and unbinds the 
+     * old name. Both names are relative to this context. Any attributes 
+     * associated with the old name become associated with the new name. 
+     * Intermediate contexts of the old name are not changed.
+     * 
+     * @param oldName the name of the existing binding; may not be empty
+     * @param newName the name of the new binding; may not be empty
+     * @exception NameAlreadyBoundException if newName is already bound
+     * @exception NamingException if a naming exception is encountered
+     */
+    public void rename(Name oldName, Name newName)
+        throws NamingException {
+        getBoundContext().rename(parseName(oldName), parseName(newName));
+    }
+
+
+    /**
+     * Binds a new name to the object bound to an old name, and unbinds the 
+     * old name.
+     * 
+     * @param oldName the name of the existing binding; may not be empty
+     * @param newName the name of the new binding; may not be empty
+     * @exception NameAlreadyBoundException if newName is already bound
+     * @exception NamingException if a naming exception is encountered
+     */
+    public void rename(String oldName, String newName)
+        throws NamingException {
+        getBoundContext().rename(parseName(oldName), parseName(newName));
+    }
+
+
+    /**
+     * Enumerates the names bound in the named context, along with the class 
+     * names of objects bound to them. The contents of any subcontexts are 
+     * not included.
+     * <p>
+     * If a binding is added to or removed from this context, its effect on 
+     * an enumeration previously returned is undefined.
+     * 
+     * @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(Name name)
+        throws NamingException {
+        return getBoundContext().list(parseName(name));
+    }
+
+
+    /**
+     * 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 {
+        return getBoundContext().list(parseName(name));
+    }
+
+
+    /**
+     * Enumerates the names bound in the named context, along with the 
+     * objects bound to them. The contents of any subcontexts are not 
+     * included.
+     * <p>
+     * If a binding is added to or removed from this context, its effect on 
+     * an enumeration previously returned is undefined.
+     * 
+     * @param name the name of the context to list
+     * @return an enumeration of the bindings in this context. 
+     * Each element of the enumeration is of type Binding.
+     * @exception NamingException if a naming exception is encountered
+     */
+    public NamingEnumeration listBindings(Name name)
+        throws NamingException {
+        return getBoundContext().listBindings(parseName(name));
+    }
+
+
+    /**
+     * Enumerates the names bound in the named context, along with the 
+     * objects bound to them.
+     * 
+     * @param name the name of the context to list
+     * @return an enumeration of the bindings in this context. 
+     * Each element of the enumeration is of type Binding.
+     * @exception NamingException if a naming exception is encountered
+     */
+    public NamingEnumeration listBindings(String name)
+        throws NamingException {
+        return getBoundContext().listBindings(parseName(name));
+    }
+
+
+    /**
+     * Destroys the named context and removes it from the namespace. Any 
+     * attributes associated with the name are also removed. Intermediate 
+     * contexts are not destroyed.
+     * <p>
+     * This method is idempotent. It succeeds even if the terminal atomic 
+     * name is not bound in the target context, but throws 
+     * NameNotFoundException if any of the intermediate contexts do not exist. 
+     * 
+     * In a federated naming system, a context from one naming system may be 
+     * bound to a name in another. One can subsequently look up and perform 
+     * operations on the foreign context using a composite name. However, an 
+     * attempt destroy the context using this composite name will fail with 
+     * NotContextException, because the foreign context is not a "subcontext" 
+     * of the context in which it is bound. Instead, use unbind() to remove 
+     * the binding of the foreign context. Destroying the foreign context 
+     * requires that the destroySubcontext() be performed on a context from 
+     * the foreign context's "native" naming system.
+     * 
+     * @param name the name of the context to be destroyed; may not be empty
+     * @exception NameNotFoundException if an intermediate context does not 
+     * exist
+     * @exception NotContextException if the name is bound but does not name 
+     * a context, or does not name a context of the appropriate type
+     */
+    public void destroySubcontext(Name name)
+        throws NamingException {
+        getBoundContext().destroySubcontext(parseName(name));
+    }
+
+
+    /**
+     * Destroys the named context and removes it from the namespace.
+     * 
+     * @param name the name of the context to be destroyed; may not be empty
+     * @exception NameNotFoundException if an intermediate context does not 
+     * exist
+     * @exception NotContextException if the name is bound but does not name 
+     * a context, or does not name a context of the appropriate type
+     */
+    public void destroySubcontext(String name)
+        throws NamingException {
+        getBoundContext().destroySubcontext(parseName(name));
+    }
+
+
+    /**
+     * Creates and binds a new context. Creates a new context with the given 
+     * name and binds it in the target context (that named by all but 
+     * terminal atomic component of the name). All intermediate contexts and 
+     * the target context must already exist.
+     * 
+     * @param name the name of the context to create; may not be empty
+     * @return the newly created context
+     * @exception NameAlreadyBoundException if name is already bound
+     * @exception InvalidAttributesException if creation of the subcontext 
+     * requires specification of mandatory attributes
+     * @exception NamingException if a naming exception is encountered
+     */
+    public Context createSubcontext(Name name)
+        throws NamingException {
+        return getBoundContext().createSubcontext(parseName(name));
+    }
+
+
+    /**
+     * Creates and binds a new context.
+     * 
+     * @param name the name of the context to create; may not be empty
+     * @return the newly created context
+     * @exception NameAlreadyBoundException if name is already bound
+     * @exception InvalidAttributesException if creation of the subcontext 
+     * requires specification of mandatory attributes
+     * @exception NamingException if a naming exception is encountered
+     */
+    public Context createSubcontext(String name)
+        throws NamingException {
+        return getBoundContext().createSubcontext(parseName(name));
+    }
+
+
+    /**
+     * Retrieves the named object, following links except for the terminal 
+     * atomic component of the name. If the object bound to name is not a 
+     * link, returns the object itself.
+     * 
+     * @param name the name of the object to look up
+     * @return the object bound to name, not following the terminal link 
+     * (if any).
+     * @exception NamingException if a naming exception is encountered
+     */
+    public Object lookupLink(Name name)
+        throws NamingException {
+        return getBoundContext().lookupLink(parseName(name));
+    }
+
+
+    /**
+     * Retrieves the named object, following links except for the terminal 
+     * atomic component of the name.
+     * 
+     * @param name the name of the object to look up
+     * @return the object bound to name, not following the terminal link 
+     * (if any).
+     * @exception NamingException if a naming exception is encountered
+     */
+    public Object lookupLink(String name)
+        throws NamingException {
+        return getBoundContext().lookupLink(parseName(name));
+    }
+
+
+    /**
+     * Retrieves the parser associated with the named context. In a 
+     * federation of namespaces, different naming systems will parse names 
+     * differently. This method allows an application to get a parser for 
+     * parsing names into their atomic components using the naming convention 
+     * of a particular naming system. Within any single naming system, 
+     * NameParser objects returned by this method must be equal (using the 
+     * equals() test).
+     * 
+     * @param name the name of the context from which to get the parser
+     * @return a name parser that can parse compound names into their atomic 
+     * components
+     * @exception NamingException if a naming exception is encountered
+     */
+    public NameParser getNameParser(Name name)
+        throws NamingException {
+        return getBoundContext().getNameParser(parseName(name));
+    }
+
+
+    /**
+     * Retrieves the parser associated with the named context.
+     * 
+     * @param name the name of the context from which to get the parser
+     * @return a name parser that can parse compound names into their atomic 
+     * components
+     * @exception NamingException if a naming exception is encountered
+     */
+    public NameParser getNameParser(String name)
+        throws NamingException {
+        return getBoundContext().getNameParser(parseName(name));
+    }
+
+
+    /**
+     * Composes the name of this context with a name relative to this context.
+     * <p>
+     * Given a name (name) relative to this context, and the name (prefix) 
+     * of this context relative to one of its ancestors, this method returns 
+     * the composition of the two names using the syntax appropriate for the 
+     * naming system(s) involved. That is, if name names an object relative 
+     * to this context, the result is the name of the same object, but 
+     * relative to the ancestor context. None of the names may be null.
+     * 
+     * @param name a name relative to this context
+     * @param prefix the name of this context relative to one of its ancestors
+     * @return the composition of prefix and name
+     * @exception NamingException if a naming exception is encountered
+     */
+    public Name composeName(Name name, Name prefix)
+        throws NamingException {
+	Name result = (Name) prefix.clone();
+	return result.addAll(name);
+    }
+
+
+    /**
+     * Composes the name of this context with a name relative to this context.
+     * 
+     * @param name a name relative to this context
+     * @param prefix the name of this context relative to one of its ancestors
+     * @return the composition of prefix and name
+     * @exception NamingException if a naming exception is encountered
+     */
+    public String composeName(String name, String prefix)
+        throws NamingException {
+        return prefix + "/" + name;
+    }
+
+
+    /**
+     * Adds a new environment property to the environment of this context. If 
+     * the property already exists, its value is overwritten.
+     * 
+     * @param propName the name of the environment property to add; may not 
+     * be null
+     * @param propVal the value of the property to add; may not be null
+     * @exception NamingException if a naming exception is encountered
+     */
+    public Object addToEnvironment(String propName, Object propVal)
+        throws NamingException {
+        return getBoundContext().addToEnvironment(propName, propVal);
+    }
+
+
+    /**
+     * Removes an environment property from the environment of this context. 
+     * 
+     * @param propName the name of the environment property to remove; 
+     * may not be null
+     * @exception NamingException if a naming exception is encountered
+     */
+    public Object removeFromEnvironment(String propName)
+        throws NamingException {
+        return getBoundContext().removeFromEnvironment(propName);
+    }
+
+
+    /**
+     * Retrieves the environment in effect for this context. See class 
+     * description for more details on environment properties. 
+     * The caller should not make any changes to the object returned: their 
+     * effect on the context is undefined. The environment of this context 
+     * may be changed using addToEnvironment() and removeFromEnvironment().
+     * 
+     * @return the environment of this context; never null
+     * @exception NamingException if a naming exception is encountered
+     */
+    public Hashtable getEnvironment()
+        throws NamingException {
+        return getBoundContext().getEnvironment();
+    }
+
+
+    /**
+     * Closes this context. This method releases this context's resources 
+     * immediately, instead of waiting for them to be released automatically 
+     * by the garbage collector.
+     * This method is idempotent: invoking it on a context that has already 
+     * been closed has no effect. Invoking any other method on a closed 
+     * context is not allowed, and results in undefined behaviour.
+     * 
+     * @exception NamingException if a naming exception is encountered
+     */
+    public void close()
+        throws NamingException {
+        getBoundContext().close();
+    }
+
+
+    /**
+     * Retrieves the full name of this context within its own namespace.
+     * <p>
+     * Many naming services have a notion of a "full name" for objects in 
+     * their respective namespaces. For example, an LDAP entry has a 
+     * distinguished name, and a DNS record has a fully qualified name. This 
+     * method allows the client application to retrieve this name. The string 
+     * returned by this method is not a JNDI composite name and should not be 
+     * passed directly to context methods. In naming systems for which the 
+     * notion of full name does not make sense, 
+     * OperationNotSupportedException is thrown.
+     * 
+     * @return this context's name in its own namespace; never null
+     * @exception OperationNotSupportedException if the naming system does 
+     * not have the notion of a full name
+     * @exception NamingException if a naming exception is encountered
+     */
+    public String getNameInNamespace()
+        throws NamingException {
+        return prefix;
+    }
+
+
+    // ------------------------------------------------------ Protected Methods
+
+
+    /**
+     * Get the bound context.
+     */
+    protected Context getBoundContext()
+        throws NamingException {
+
+        if (initialContext) {
+            String ICName = IC_PREFIX;
+            if (ContextBindings.isThreadBound()) {
+                ICName += ContextBindings.getThreadName();
+            } else if (ContextBindings.isClassLoaderBound()) {
+                ICName += ContextBindings.getClassLoaderName();
+            }
+            Context initialContext = ContextBindings.getContext(ICName);
+            if (initialContext == null) {
+                // Allocating a new context and binding it to the appropriate 
+                // name
+                initialContext = new NamingContext(env, ICName);
+                ContextBindings.bindContext(ICName, initialContext);
+            }
+            return initialContext;
+        } else {
+            if (ContextBindings.isThreadBound()) {
+                return ContextBindings.getThread();
+            } else {
+                return ContextBindings.getClassLoader();
+            }
+        }
+
+    }
+
+
+    /**
+     * Strips the URL header.
+     * 
+     * @return the parsed name
+     * @exception NamingException if there is no "java:" header or if no 
+     * naming context has been bound to this thread
+     */
+    protected String parseName(String name) 
+        throws NamingException {
+        
+	if ((!initialContext) && (name.startsWith(prefix))) {
+            return (name.substring(prefixLength));
+        } else {
+            if (initialContext) {
+                return (name);
+            } else {
+                throw new NamingException
+                    (sm.getString("selectorContext.noJavaUrl"));
+            }
+        }
+        
+    }
+
+
+    /**
+     * Strips the URL header.
+     * 
+     * @return the parsed name
+     * @exception NamingException if there is no "java:" header or if no 
+     * naming context has been bound to this thread
+     */
+    protected Name parseName(Name name) 
+        throws NamingException {
+
+	if ((!initialContext) && (!name.isEmpty()) 
+            && (name.get(0).equals(prefix))) {
+            return (name.getSuffix(1));
+        } else {
+            if (initialContext) {
+                return (name);
+            } else {
+                throw new NamingException
+                    (sm.getString("selectorContext.noJavaUrl"));
+            }
+        }
+
+    }
+
+
+}
+

Added: incubator/directory/naming/trunk/core/src/java/org/apache/directory/naming/StringManager.java
==============================================================================
--- (empty file)
+++ incubator/directory/naming/trunk/core/src/java/org/apache/directory/naming/StringManager.java	Sun Dec  7 13:00:05 2003
@@ -0,0 +1,265 @@
+/*
+ * $Header: /home/cvs/jakarta-commons-sandbox/naming/core/src/java/org/apache/commons/naming/StringManager.java,v 1.2 2003/10/13 08:16:47 rdonkin Exp $
+ * $Revision: 1.2 $
+ * $Date: 2003/10/13 08:16:47 $
+ *
+ * ====================================================================
+ *
+ * The Apache Software License, Version 1.1
+ *
+ * Copyright (c) 1999 The Apache Software Foundation.  All rights 
+ * reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. The end-user documentation included with the redistribution, if
+ *    any, must include the following acknowledgement:
+ *       "This product includes software developed by the 
+ *        Apache Software Foundation (http://www.apache.org/)."
+ *    Alternately, this acknowledgement may appear in the software itself,
+ *    if and wherever such third-party acknowledgements normally appear.
+ *
+ * 4. The names "The Jakarta Project", "Tomcat", and "Apache Software
+ *    Foundation" must not be used to endorse or promote products derived
+ *    from this software without prior written permission. For written 
+ *    permission, please contact apache@apache.org.
+ *
+ * 5. Products derived from this software may not be called "Apache"
+ *    nor may "Apache" appear in their names without prior written
+ *    permission of the Apache Software Foundation.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation.  For more
+ * information on the Apache Software Foundation, please see
+ * <http://www.apache.org/>.
+ *
+ * [Additional notices, if required by prior licensing conditions]
+ *
+ */ 
+
+
+package org.apache.directory.naming;
+
+import java.text.MessageFormat;
+import java.util.Hashtable;
+import java.util.Locale;
+import java.util.MissingResourceException;
+import java.util.ResourceBundle;
+
+/**
+ * An internationalization / localization helper class which reduces
+ * the bother of handling ResourceBundles and takes care of the
+ * common cases of message formating which otherwise require the
+ * creation of Object arrays and such.
+ *
+ * <p>The StringManager operates on a package basis. One StringManager
+ * per package can be created and accessed via the getManager method
+ * call.
+ *
+ * <p>The StringManager will look for a ResourceBundle named by
+ * the package name given plus the suffix of "LocalStrings". In
+ * practice, this means that the localized information will be contained
+ * in a LocalStrings.properties file located in the package
+ * directory of the classpath.
+ *
+ * <p>Please see the documentation for java.util.ResourceBundle for
+ * more information.
+ *
+ * @author James Duncan Davidson [duncan@eng.sun.com]
+ * @author James Todd [gonzo@eng.sun.com]
+ */
+
+public class StringManager {
+
+    /**
+     * The ResourceBundle for this StringManager.
+     */
+    
+    private ResourceBundle bundle;
+
+    /**
+     * Creates a new StringManager for a given package. This is a
+     * private method and all access to it is arbitrated by the
+     * static getManager method call so that only one StringManager
+     * per package will be created.
+     *
+     * @param packageName Name of package to create StringManager for.
+     */
+
+    private StringManager(String packageName) {
+	String bundleName = packageName + ".LocalStrings";
+	bundle = ResourceBundle.getBundle(bundleName);
+    }
+
+    /**
+     * Get a string from the underlying resource bundle.
+     *
+     * @param key 
+     */
+    
+    public String getString(String key) {
+        if (key == null) {
+            String msg = "key is null";
+
+            throw new NullPointerException(msg);
+        }
+
+        String str = null;
+
+        try {
+	    str = bundle.getString(key);
+        } catch (MissingResourceException mre) {
+            str = "Cannot find message associated with key '" + key + "'";
+        }
+
+        return str;
+    }
+
+    /**
+     * Get a string from the underlying resource bundle and format
+     * it with the given set of arguments.
+     *
+     * @param key
+     * @param args
+     */
+
+    public String getString(String key, Object[] args) {
+	String iString = null;
+        String value = getString(key);
+
+	// this check for the runtime exception is some pre 1.1.6
+	// VM's don't do an automatic toString() on the passed in
+	// objects and barf out
+	
+	try {
+            // ensure the arguments are not null so pre 1.2 VM's don't barf
+            Object nonNullArgs[] = args;
+            for (int i=0; i<args.length; i++) {
+		if (args[i] == null) {
+		    if (nonNullArgs==args) nonNullArgs=(Object[])args.clone();
+		    nonNullArgs[i] = "null";
+		}
+	    }
+ 
+            iString = MessageFormat.format(value, nonNullArgs);
+	} catch (IllegalArgumentException iae) {
+	    StringBuffer buf = new StringBuffer();
+	    buf.append(value);
+	    for (int i = 0; i < args.length; i++) {
+		buf.append(" arg[" + i + "]=" + args[i]);
+	    }
+	    iString = buf.toString();
+	}
+	return iString;
+    }
+
+    /**
+     * Get a string from the underlying resource bundle and format it
+     * with the given object argument. This argument can of course be
+     * a String object.
+     *
+     * @param key
+     * @param arg
+     */
+
+    public String getString(String key, Object arg) {
+	Object[] args = new Object[] {arg};
+	return getString(key, args);
+    }
+
+    /**
+     * Get a string from the underlying resource bundle and format it
+     * with the given object arguments. These arguments can of course
+     * be String objects.
+     *
+     * @param key
+     * @param arg1
+     * @param arg2
+     */
+
+    public String getString(String key, Object arg1, Object arg2) {
+	Object[] args = new Object[] {arg1, arg2};
+	return getString(key, args);
+    }
+    
+    /**
+     * Get a string from the underlying resource bundle and format it
+     * with the given object arguments. These arguments can of course
+     * be String objects.
+     *
+     * @param key
+     * @param arg1
+     * @param arg2
+     * @param arg3
+     */
+
+    public String getString(String key, Object arg1, Object arg2,
+			    Object arg3) {
+	Object[] args = new Object[] {arg1, arg2, arg3};
+	return getString(key, args);
+    }
+    
+    /**
+     * Get a string from the underlying resource bundle and format it
+     * with the given object arguments. These arguments can of course
+     * be String objects.
+     *
+     * @param key
+     * @param arg1
+     * @param arg2
+     * @param arg3
+     * @param arg4
+     */
+
+    public String getString(String key, Object arg1, Object arg2,
+			    Object arg3, Object arg4) {
+	Object[] args = new Object[] {arg1, arg2, arg3, arg4};
+	return getString(key, args);
+    }   
+    // --------------------------------------------------------------
+    // STATIC SUPPORT METHODS
+    // --------------------------------------------------------------
+
+    private static Hashtable managers = new Hashtable();
+
+    /**
+     * Get the StringManager for a particular package. If a manager for
+     * a package already exists, it will be reused, else a new
+     * StringManager will be created and returned.
+     *
+     * @param packageName
+     */
+
+    public synchronized static StringManager getManager(String packageName) {
+	StringManager mgr = (StringManager)managers.get(packageName);
+	if (mgr == null) {
+	    mgr = new StringManager(packageName);
+	    managers.put(packageName, mgr);
+	}
+	return mgr;
+    }
+}

Added: incubator/directory/naming/trunk/core/src/java/org/apache/directory/naming/TransactionRef.java
==============================================================================
--- (empty file)
+++ incubator/directory/naming/trunk/core/src/java/org/apache/directory/naming/TransactionRef.java	Sun Dec  7 13:00:05 2003
@@ -0,0 +1,143 @@
+/*
+ * $Header: /home/cvs/jakarta-commons-sandbox/naming/core/src/java/org/apache/commons/naming/TransactionRef.java,v 1.3 2003/11/30 05:15:06 psteitz Exp $
+ * $Revision: 1.3 $
+ * $Date: 2003/11/30 05:15:06 $
+ *
+ * ====================================================================
+ *
+ * The Apache Software License, Version 1.1
+ *
+ * Copyright (c) 1999 The Apache Software Foundation.  All rights 
+ * reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. The end-user documentation included with the redistribution, if
+ *    any, must include the following acknowledgement:
+ *       "This product includes software developed by the 
+ *        Apache Software Foundation (http://www.apache.org/)."
+ *    Alternately, this acknowledgement may appear in the software itself,
+ *    if and wherever such third-party acknowledgements normally appear.
+ *
+ * 4. The names "The Jakarta Project", "Tomcat", and "Apache Software
+ *    Foundation" must not be used to endorse or promote products derived
+ *    from this software without prior written permission. For written 
+ *    permission, please contact apache@apache.org.
+ *
+ * 5. Products derived from this software may not be called "Apache"
+ *    nor may "Apache" appear in their names without prior written
+ *    permission of the Apache Software Foundation.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation.  For more
+ * information on the Apache Software Foundation, please see
+ * <http://www.apache.org/>.
+ *
+ * [Additional notices, if required by prior licensing conditions]
+ *
+ */ 
+
+
+package org.apache.directory.naming;
+
+import java.util.Hashtable;
+import javax.naming.Reference;
+import javax.naming.Context;
+import javax.naming.StringRefAddr;
+
+/**
+ * Represents a reference address to a transaction.
+ *
+ * @author Remy Maucherat
+ * @version $Revision: 1.3 $ $Date: 2003/11/30 05:15:06 $
+ */
+
+public class TransactionRef
+    extends Reference {
+
+
+    // -------------------------------------------------------------- Constants
+
+
+    /**
+     * Default factory for this reference.
+     */
+    public static final String DEFAULT_FACTORY = 
+        Constants.DEFAULT_TRANSACTION_FACTORY;
+
+
+    // ----------------------------------------------------------- Constructors
+
+
+    /**
+     * Resource Reference.
+     */
+    public TransactionRef() {
+        this(null, null);
+    }
+
+
+    /**
+     * Resource Reference.
+     * 
+     * @param factory Resource factory
+     * @param factoryLocation Factory location
+     */
+    public TransactionRef(String factory, String factoryLocation) {
+        super("javax.transaction.UserTransaction", factory, factoryLocation);
+    }
+
+
+    // ----------------------------------------------------- Instance Variables
+
+
+    // ------------------------------------------------------ Reference Methods
+
+
+    /**
+     * Retrieves the class name of the factory of the object to which this 
+     * reference refers.
+     */
+    public String getFactoryClassName() {
+        String factory = super.getFactoryClassName();
+        if (factory != null) {
+            return factory;
+        } else {
+            factory = System.getProperty(Context.OBJECT_FACTORIES);
+            if (factory != null) {
+                return null;
+            } else {
+                return DEFAULT_FACTORY;
+            }
+        }
+    }
+
+
+    // ------------------------------------------------------------- Properties
+
+
+}

Added: incubator/directory/naming/trunk/core/src/java/org/apache/directory/naming/java/javaURLContextFactory.java
==============================================================================
--- (empty file)
+++ incubator/directory/naming/trunk/core/src/java/org/apache/directory/naming/java/javaURLContextFactory.java	Sun Dec  7 13:00:05 2003
@@ -0,0 +1,158 @@
+/*
+ * $Header: /home/cvs/jakarta-commons-sandbox/naming/core/src/java/org/apache/commons/naming/java/javaURLContextFactory.java,v 1.2 2003/10/13 08:16:48 rdonkin Exp $
+ * $Revision: 1.2 $
+ * $Date: 2003/10/13 08:16:48 $
+ *
+ * ====================================================================
+ *
+ * The Apache Software License, Version 1.1
+ *
+ * Copyright (c) 1999 The Apache Software Foundation.  All rights 
+ * reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. The end-user documentation included with the redistribution, if
+ *    any, must include the following acknowledgement:
+ *       "This product includes software developed by the 
+ *        Apache Software Foundation (http://www.apache.org/)."
+ *    Alternately, this acknowledgement may appear in the software itself,
+ *    if and wherever such third-party acknowledgements normally appear.
+ *
+ * 4. The names "The Jakarta Project", "Tomcat", and "Apache Software
+ *    Foundation" must not be used to endorse or promote products derived
+ *    from this software without prior written permission. For written 
+ *    permission, please contact apache@apache.org.
+ *
+ * 5. Products derived from this software may not be called "Apache"
+ *    nor may "Apache" appear in their names without prior written
+ *    permission of the Apache Software Foundation.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation.  For more
+ * information on the Apache Software Foundation, please see
+ * <http://www.apache.org/>.
+ *
+ * [Additional notices, if required by prior licensing conditions]
+ *
+ */ 
+
+
+package org.apache.directory.naming.java;
+
+import java.util.Hashtable;
+import javax.naming.Name;
+import javax.naming.Context;
+import javax.naming.NamingException;
+import javax.naming.spi.ObjectFactory;
+import javax.naming.spi.InitialContextFactory;
+import org.apache.directory.naming.SelectorContext;
+import org.apache.directory.naming.NamingContext;
+import org.apache.directory.naming.ContextBindings;
+
+/**
+ * Context factory for the "java:" namespace.
+ * <p>
+ * <b>Important note</b> : This factory MUST be associated with the "java" URL
+ * prefix, which can be done by either :
+ * <ul>
+ * <li>Adding a 
+ * java.naming.factory.url.pkgs=org.apache.catalina.util.naming property
+ * to the JNDI properties file</li>
+ * <li>Setting an environment variable named Context.URL_PKG_PREFIXES with 
+ * its value including the org.apache.catalina.util.naming package name. 
+ * More detail about this can be found in the JNDI documentation : 
+ * {@link javax.naming.spi.NamingManager#getURLContext(java.lang.String, java.util.Hashtable)}.</li>
+ * </ul>
+ * 
+ * @author Remy Maucherat
+ * @version $Revision: 1.2 $ $Date: 2003/10/13 08:16:48 $
+ */
+
+public class javaURLContextFactory
+    implements ObjectFactory, InitialContextFactory {
+
+
+    // ----------------------------------------------------------- Constructors
+
+
+    // -------------------------------------------------------------- Constants
+
+
+    public static final String MAIN = "initialContext";
+
+
+    // ----------------------------------------------------- Instance Variables
+
+
+    /**
+     * Initial context.
+     */
+    protected static Context initialContext = null;
+
+
+    // --------------------------------------------------------- Public Methods
+
+
+    // -------------------------------------------------- ObjectFactory Methods
+
+
+    /**
+     * Crete a new Context's instance.
+     */
+    public Object getObjectInstance(Object obj, Name name, Context nameCtx,
+                                    Hashtable environment)
+        throws NamingException {
+        if ((ContextBindings.isThreadBound()) || 
+            (ContextBindings.isClassLoaderBound())) {
+            return new SelectorContext(environment);
+        } else {
+            return null;
+        }
+    }
+
+
+    /**
+     * Get a new (writable) initial context.
+     */
+    public Context getInitialContext(Hashtable environment)
+        throws NamingException {
+        if (ContextBindings.isThreadBound() || 
+            (ContextBindings.isClassLoaderBound())) {
+            // Redirect the request to the bound initial context
+            return new SelectorContext(environment, true);
+        } else {
+            // If the thread is not bound, return a shared writable context
+            if (initialContext == null)
+                initialContext = new NamingContext(environment, MAIN);
+            return initialContext;
+        }
+    }
+
+
+}
+

Added: incubator/directory/naming/trunk/core/src/java/org/apache/directory/naming/java/package.html
==============================================================================
--- (empty file)
+++ incubator/directory/naming/trunk/core/src/java/org/apache/directory/naming/java/package.html	Sun Dec  7 13:00:05 2003
@@ -0,0 +1,7 @@
+<body>
+
+<p>This package contains the URL context factory for the "java" namespace.</p>
+
+<p></p>
+
+</body>

Added: incubator/directory/naming/trunk/core/src/java/org/apache/directory/naming/package.html
==============================================================================
--- (empty file)
+++ incubator/directory/naming/trunk/core/src/java/org/apache/directory/naming/package.html	Sun Dec  7 13:00:05 2003
@@ -0,0 +1,7 @@
+<body>
+
+<p>This package contains a memory based naming service provider.</p>
+
+<p></p>
+
+</body>

Added: incubator/directory/naming/trunk/core/src/java/org/apache/directory/naming/resources/BaseDirContext.java
==============================================================================
--- (empty file)
+++ incubator/directory/naming/trunk/core/src/java/org/apache/directory/naming/resources/BaseDirContext.java	Sun Dec  7 13:00:05 2003
@@ -0,0 +1,1281 @@
+/*
+ * $Header: /home/cvs/jakarta-commons-sandbox/naming/core/src/java/org/apache/commons/naming/resources/BaseDirContext.java,v 1.3 2003/11/30 05:22:15 psteitz Exp $
+ * $Revision: 1.3 $
+ * $Date: 2003/11/30 05:22:15 $
+ *
+ * ====================================================================
+ *
+ * The Apache Software License, Version 1.1
+ *
+ * Copyright (c) 1999 The Apache Software Foundation.  All rights 
+ * reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. The end-user documentation included with the redistribution, if
+ *    any, must include the following acknowledgement:
+ *       "This product includes software developed by the 
+ *        Apache Software Foundation (http://www.apache.org/)."
+ *    Alternately, this acknowledgement may appear in the software itself,
+ *    if and wherever such third-party acknowledgements normally appear.
+ *
+ * 4. The names "The Jakarta Project", "Tomcat", and "Apache Software
+ *    Foundation" must not be used to endorse or promote products derived
+ *    from this software without prior written permission. For written 
+ *    permission, please contact apache@apache.org.
+ *
+ * 5. Products derived from this software may not be called "Apache"
+ *    nor may "Apache" appear in their names without prior written
+ *    permission of the Apache Software Foundation.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation.  For more
+ * information on the Apache Software Foundation, please see
+ * <http://www.apache.org/>.
+ *
+ * [Additional notices, if required by prior licensing conditions]
+ *
+ */ 
+
+
+package org.apache.directory.naming.resources;
+
+import java.util.Hashtable;
+import java.util.HashMap;
+import javax.naming.Context;
+import javax.naming.Name;
+import javax.naming.NameParser;
+import javax.naming.NamingEnumeration;
+import javax.naming.NamingException;
+import javax.naming.CompositeName;
+import javax.naming.NameParser;
+import javax.naming.directory.DirContext;
+import javax.naming.directory.Attributes;
+import javax.naming.directory.Attribute;
+import javax.naming.directory.ModificationItem;
+import javax.naming.directory.SearchControls;
+import org.apache.directory.naming.StringManager;
+import org.apache.directory.naming.NameParserImpl;
+
+/**
+ * Directory Context implementation helper class.
+ *
+ * @author Remy Maucherat
+ * @version $Revision: 1.3 $ $Date: 2003/11/30 05:22:15 $
+ */
+
+public abstract class BaseDirContext implements DirContext {
+
+
+    // -------------------------------------------------------------- Constants
+
+
+    // ----------------------------------------------------------- Constructors
+
+
+    /**
+     * Builds a base directory context.
+     */
+    public BaseDirContext() {
+        this.env = new Hashtable();
+    }
+
+
+    /**
+     * Builds a base directory context using the given environment.
+     */
+    public BaseDirContext(Hashtable env) {
+        this.env = env;
+    }
+
+
+    // ----------------------------------------------------- Instance Variables
+
+
+    /**
+     * The debugging detail level for this component.
+     */
+    protected int debug = 0;
+
+
+    /**
+     * The document base path.
+     */
+    protected String docBase = null;
+
+
+    /**
+     * Environment.
+     */
+    protected Hashtable env;
+
+
+    /**
+     * The string manager for this package.
+     */
+    protected StringManager sm = StringManager.getManager(Constants.Package);
+
+
+    /**
+     * Name parser for this context.
+     */
+    protected final NameParser nameParser = new NameParserImpl();
+
+
+    /**
+     * Cached.
+     */
+    protected boolean cached = true;
+
+
+    /**
+     * Cache TTL.
+     */
+    protected int cacheTTL = 5000; // 5s
+
+
+    /**
+     * Max size of resources which will have their content cached.
+     */
+    protected int cacheObjectMaxSize = 32768; // 32 KB
+
+
+    // ------------------------------------------------------------- Properties
+
+
+    /**
+     * Return the debugging detail level for this component.
+     */
+    public int getDebug() {
+	return (this.debug);
+    }
+
+
+    /**
+     * Set the debugging detail level for this component.
+     *
+     * @param debug The new debugging detail level
+     */
+    public void setDebug(int debug) {
+	this.debug = debug;
+    }
+
+
+    /**
+     * Return the document root for this component.
+     */
+    public String getDocBase() {
+	return (this.docBase);
+    }
+
+
+    /**
+     * Set the document root for this component.
+     *
+     * @param docBase The new document root
+     *
+     * @exception IllegalArgumentException if the specified value is not
+     *  supported by this implementation
+     * @exception IllegalArgumentException if this would create a
+     *  malformed URL
+     */
+    public void setDocBase(String docBase) {
+
+	// Validate the format of the proposed document root
+	if (docBase == null)
+	    throw new IllegalArgumentException
+		(sm.getString("resources.null"));
+
+	// Change the document root property
+	this.docBase = docBase;
+
+    }
+
+
+    /**
+     * Set cached.
+     */
+    public void setCached(boolean cached) {
+        this.cached = cached;
+    }
+
+
+    /**
+     * Is cached ?
+     */
+    public boolean isCached() {
+        return cached;
+    }
+
+
+    /**
+     * Set cache TTL.
+     */
+    public void setCacheTTL(int cacheTTL) {
+        this.cacheTTL = cacheTTL;
+    }
+
+
+    /**
+     * Get cache TTL.
+     */
+    public int getCacheTTL() {
+        return cacheTTL;
+    }
+
+
+    /**
+     * Set cacheObjectMaxSize.
+     */
+    public void setCacheObjectMaxSize(int cacheObjectMaxSize) {
+        this.cacheObjectMaxSize = cacheObjectMaxSize;
+    }
+
+
+    /**
+     * Get cacheObjectMaxSize.
+     */
+    public int getCacheObjectMaxSize() {
+        return cacheObjectMaxSize;
+    }
+
+
+    // --------------------------------------------------------- Public Methods
+
+
+    /**
+     * Allocate resources for this directory context.
+     */
+    public void allocate() {
+        ; // No action taken by the default implementation
+    }
+
+
+    /**
+     * Release any resources allocated for this directory context.
+     */
+    public void release() {
+        ; // No action taken by the default implementation
+    }
+
+
+    // -------------------------------------------------------- Context Methods
+
+
+    /**
+     * Retrieves the named object. If name is empty, returns a new instance 
+     * of this context (which represents the same naming context as this 
+     * context, but its environment may be modified independently and it may 
+     * be accessed concurrently).
+     * 
+     * @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(Name name)
+        throws NamingException {
+        return lookup(name.toString());
+    }
+
+
+    /**
+     * 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 abstract Object lookup(String name)
+        throws NamingException;
+
+
+    /**
+     * Binds a name to an object. All intermediate contexts and the target 
+     * context (that named by all but terminal atomic component of the name) 
+     * must already exist.
+     * 
+     * @param name the name to bind; may not be empty
+     * @param obj the object to bind; possibly null
+     * @exception NameAlreadyBoundException if name is already bound
+     * @exception InvalidAttributesException if object did not supply all 
+     * mandatory attributes
+     * @exception NamingException if a naming exception is encountered
+     */
+    public void bind(Name name, Object obj)
+        throws NamingException {
+        bind(name.toString(), obj);
+    }
+
+
+    /**
+     * Binds a name to an object.
+     * 
+     * @param name the name to bind; may not be empty
+     * @param obj the object to bind; possibly null
+     * @exception NameAlreadyBoundException if name is already bound
+     * @exception InvalidAttributesException if object did not supply all 
+     * mandatory attributes
+     * @exception NamingException if a naming exception is encountered
+     */
+    public void bind(String name, Object obj)
+        throws NamingException {
+        bind(name, obj, null);
+    }
+
+
+    /**
+     * Binds a name to an object, overwriting any existing binding. All 
+     * intermediate contexts and the target context (that named by all but 
+     * terminal atomic component of the name) must already exist.
+     * <p>
+     * If the object is a DirContext, any existing attributes associated with 
+     * the name are replaced with those of the object. Otherwise, any 
+     * existing attributes associated with the name remain unchanged.
+     * 
+     * @param name the name to bind; may not be empty
+     * @param obj the object to bind; possibly null
+     * @exception InvalidAttributesException if object did not supply all 
+     * mandatory attributes
+     * @exception NamingException if a naming exception is encountered
+     */
+    public void rebind(Name name, Object obj)
+        throws NamingException {
+        rebind(name.toString(), obj);
+    }
+
+
+    /**
+     * Binds a name to an object, overwriting any existing binding.
+     * 
+     * @param name the name to bind; may not be empty
+     * @param obj the object to bind; possibly null
+     * @exception InvalidAttributesException if object did not supply all 
+     * mandatory attributes
+     * @exception NamingException if a naming exception is encountered
+     */
+    public void rebind(String name, Object obj)
+        throws NamingException {
+        rebind(name, obj, null);
+    }
+
+
+    /**
+     * Unbinds the named object. Removes the terminal atomic name in name 
+     * from the target context--that named by all but the terminal atomic 
+     * part of name.
+     * <p>
+     * This method is idempotent. It succeeds even if the terminal atomic 
+     * name is not bound in the target context, but throws 
+     * NameNotFoundException if any of the intermediate contexts do not exist. 
+     * 
+     * @param name the name to bind; may not be empty
+     * @exception NameNotFoundException if an intermediate context does not 
+     * exist
+     * @exception NamingException if a naming exception is encountered
+     */
+    public void unbind(Name name)
+        throws NamingException {
+        unbind(name.toString());
+    }
+
+
+    /**
+     * Unbinds the named object.
+     * 
+     * @param name the name to bind; may not be empty
+     * @exception NameNotFoundException if an intermediate context does not 
+     * exist
+     * @exception NamingException if a naming exception is encountered
+     */
+    public abstract void unbind(String name)
+        throws NamingException;
+
+
+    /**
+     * Binds a new name to the object bound to an old name, and unbinds the 
+     * old name. Both names are relative to this context. Any attributes 
+     * associated with the old name become associated with the new name. 
+     * Intermediate contexts of the old name are not changed.
+     * 
+     * @param oldName the name of the existing binding; may not be empty
+     * @param newName the name of the new binding; may not be empty
+     * @exception NameAlreadyBoundException if newName is already bound
+     * @exception NamingException if a naming exception is encountered
+     */
+    public void rename(Name oldName, Name newName)
+        throws NamingException {
+        rename(oldName.toString(), newName.toString());
+    }
+
+
+    /**
+     * Binds a new name to the object bound to an old name, and unbinds the 
+     * old name.
+     * 
+     * @param oldName the name of the existing binding; may not be empty
+     * @param newName the name of the new binding; may not be empty
+     * @exception NameAlreadyBoundException if newName is already bound
+     * @exception NamingException if a naming exception is encountered
+     */
+    public abstract void rename(String oldName, String newName)
+        throws NamingException;
+
+
+    /**
+     * Enumerates the names bound in the named context, along with the class 
+     * names of objects bound to them. The contents of any subcontexts are 
+     * not included.
+     * <p>
+     * If a binding is added to or removed from this context, its effect on 
+     * an enumeration previously returned is undefined.
+     * 
+     * @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(Name name)
+        throws NamingException {
+        return list(name.toString());
+    }
+
+
+    /**
+     * 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 abstract NamingEnumeration list(String name)
+        throws NamingException;
+
+
+    /**
+     * Enumerates the names bound in the named context, along with the 
+     * objects bound to them. The contents of any subcontexts are not 
+     * included.
+     * <p>
+     * If a binding is added to or removed from this context, its effect on 
+     * an enumeration previously returned is undefined.
+     * 
+     * @param name the name of the context to list
+     * @return an enumeration of the bindings in this context. 
+     * Each element of the enumeration is of type Binding.
+     * @exception NamingException if a naming exception is encountered
+     */
+    public NamingEnumeration listBindings(Name name)
+        throws NamingException {
+        return listBindings(name.toString());
+    }
+
+
+    /**
+     * Enumerates the names bound in the named context, along with the 
+     * objects bound to them.
+     * 
+     * @param name the name of the context to list
+     * @return an enumeration of the bindings in this context. 
+     * Each element of the enumeration is of type Binding.
+     * @exception NamingException if a naming exception is encountered
+     */
+    public abstract NamingEnumeration listBindings(String name)
+        throws NamingException;
+
+
+    /**
+     * Destroys the named context and removes it from the namespace. Any 
+     * attributes associated with the name are also removed. Intermediate 
+     * contexts are not destroyed.
+     * <p>
+     * This method is idempotent. It succeeds even if the terminal atomic 
+     * name is not bound in the target context, but throws 
+     * NameNotFoundException if any of the intermediate contexts do not exist. 
+     * 
+     * In a federated naming system, a context from one naming system may be 
+     * bound to a name in another. One can subsequently look up and perform 
+     * operations on the foreign context using a composite name. However, an 
+     * attempt destroy the context using this composite name will fail with 
+     * NotContextException, because the foreign context is not a "subcontext" 
+     * of the context in which it is bound. Instead, use unbind() to remove 
+     * the binding of the foreign context. Destroying the foreign context 
+     * requires that the destroySubcontext() be performed on a context from 
+     * the foreign context's "native" naming system.
+     * 
+     * @param name the name of the context to be destroyed; may not be empty
+     * @exception NameNotFoundException if an intermediate context does not 
+     * exist
+     * @exception NotContextException if the name is bound but does not name 
+     * a context, or does not name a context of the appropriate type
+     */
+    public void destroySubcontext(Name name)
+        throws NamingException {
+        destroySubcontext(name.toString());
+    }
+
+
+    /**
+     * Destroys the named context and removes it from the namespace.
+     * 
+     * @param name the name of the context to be destroyed; may not be empty
+     * @exception NameNotFoundException if an intermediate context does not 
+     * exist
+     * @exception NotContextException if the name is bound but does not name 
+     * a context, or does not name a context of the appropriate type
+     */
+    public abstract void destroySubcontext(String name)
+        throws NamingException;
+
+
+    /**
+     * Creates and binds a new context. Creates a new context with the given 
+     * name and binds it in the target context (that named by all but 
+     * terminal atomic component of the name). All intermediate contexts and 
+     * the target context must already exist.
+     * 
+     * @param name the name of the context to create; may not be empty
+     * @return the newly created context
+     * @exception NameAlreadyBoundException if name is already bound
+     * @exception InvalidAttributesException if creation of the subcontext 
+     * requires specification of mandatory attributes
+     * @exception NamingException if a naming exception is encountered
+     */
+    public Context createSubcontext(Name name)
+        throws NamingException {
+        return createSubcontext(name.toString());
+    }
+
+
+    /**
+     * Creates and binds a new context.
+     * 
+     * @param name the name of the context to create; may not be empty
+     * @return the newly created context
+     * @exception NameAlreadyBoundException if name is already bound
+     * @exception InvalidAttributesException if creation of the subcontext 
+     * requires specification of mandatory attributes
+     * @exception NamingException if a naming exception is encountered
+     */
+    public Context createSubcontext(String name)
+        throws NamingException {
+        return createSubcontext(name, null);
+    }
+
+
+    /**
+     * Retrieves the named object, following links except for the terminal 
+     * atomic component of the name. If the object bound to name is not a 
+     * link, returns the object itself.
+     * 
+     * @param name the name of the object to look up
+     * @return the object bound to name, not following the terminal link 
+     * (if any).
+     * @exception NamingException if a naming exception is encountered
+     */
+    public Object lookupLink(Name name)
+        throws NamingException {
+        return lookupLink(name.toString());
+    }
+
+
+    /**
+     * Retrieves the named object, following links except for the terminal 
+     * atomic component of the name.
+     * 
+     * @param name the name of the object to look up
+     * @return the object bound to name, not following the terminal link 
+     * (if any).
+     * @exception NamingException if a naming exception is encountered
+     */
+    public abstract Object lookupLink(String name)
+        throws NamingException;
+
+
+    /**
+     * Retrieves the parser associated with the named context. In a 
+     * federation of namespaces, different naming systems will parse names 
+     * differently. This method allows an application to get a parser for 
+     * parsing names into their atomic components using the naming convention 
+     * of a particular naming system. Within any single naming system, 
+     * NameParser objects returned by this method must be equal (using the 
+     * equals() test).
+     * 
+     * @param name the name of the context from which to get the parser
+     * @return a name parser that can parse compound names into their atomic 
+     * components
+     * @exception NamingException if a naming exception is encountered
+     */
+    public NameParser getNameParser(Name name)
+        throws NamingException {
+        return new NameParserImpl();
+    }
+
+
+    /**
+     * Retrieves the parser associated with the named context.
+     * 
+     * @param name the name of the context from which to get the parser
+     * @return a name parser that can parse compound names into their atomic 
+     * components
+     * @exception NamingException if a naming exception is encountered
+     */
+    public NameParser getNameParser(String name)
+        throws NamingException {
+        return new NameParserImpl();
+    }
+
+
+    /**
+     * Composes the name of this context with a name relative to this context.
+     * <p>
+     * Given a name (name) relative to this context, and the name (prefix) 
+     * of this context relative to one of its ancestors, this method returns 
+     * the composition of the two names using the syntax appropriate for the 
+     * naming system(s) involved. That is, if name names an object relative 
+     * to this context, the result is the name of the same object, but 
+     * relative to the ancestor context. None of the names may be null.
+     * 
+     * @param name a name relative to this context
+     * @param prefix the name of this context relative to one of its ancestors
+     * @return the composition of prefix and name
+     * @exception NamingException if a naming exception is encountered
+     */
+    public Name composeName(Name name, Name prefix)
+        throws NamingException {
+	Name result = (Name) prefix.clone();
+	return result.addAll(name);
+    }
+
+
+    /**
+     * Composes the name of this context with a name relative to this context.
+     * 
+     * @param name a name relative to this context
+     * @param prefix the name of this context relative to one of its ancestors
+     * @return the composition of prefix and name
+     * @exception NamingException if a naming exception is encountered
+     */
+    public String composeName(String name, String prefix)
+        throws NamingException {
+        return prefix + "/" + name;
+    }
+
+
+    /**
+     * Adds a new environment property to the environment of this context. If 
+     * the property already exists, its value is overwritten.
+     * 
+     * @param propName the name of the environment property to add; may not 
+     * be null
+     * @param propVal the value of the property to add; may not be null
+     * @exception NamingException if a naming exception is encountered
+     */
+    public Object addToEnvironment(String propName, Object propVal)
+        throws NamingException {
+        return env.put(propName, propVal);
+    }
+
+
+    /**
+     * Removes an environment property from the environment of this context. 
+     * 
+     * @param propName the name of the environment property to remove; 
+     * may not be null
+     * @exception NamingException if a naming exception is encountered
+     */
+    public Object removeFromEnvironment(String propName)
+        throws NamingException {
+        return env.remove(propName);
+    }
+
+
+    /**
+     * Retrieves the environment in effect for this context. See class 
+     * description for more details on environment properties. 
+     * The caller should not make any changes to the object returned: their 
+     * effect on the context is undefined. The environment of this context 
+     * may be changed using addToEnvironment() and removeFromEnvironment().
+     * 
+     * @return the environment of this context; never null
+     * @exception NamingException if a naming exception is encountered
+     */
+    public Hashtable getEnvironment()
+        throws NamingException {
+        return env;
+    }
+
+
+    /**
+     * Closes this context. This method releases this context's resources 
+     * immediately, instead of waiting for them to be released automatically 
+     * by the garbage collector.
+     * This method is idempotent: invoking it on a context that has already 
+     * been closed has no effect. Invoking any other method on a closed 
+     * context is not allowed, and results in undefined behaviour.
+     * 
+     * @exception NamingException if a naming exception is encountered
+     */
+    public void close()
+        throws NamingException {
+        env.clear();
+    }
+
+
+    /**
+     * Retrieves the full name of this context within its own namespace.
+     * <p>
+     * Many naming services have a notion of a "full name" for objects in 
+     * their respective namespaces. For example, an LDAP entry has a 
+     * distinguished name, and a DNS record has a fully qualified name. This 
+     * method allows the client application to retrieve this name. The string 
+     * returned by this method is not a JNDI composite name and should not be 
+     * passed directly to context methods. In naming systems for which the 
+     * notion of full name does not make sense, 
+     * OperationNotSupportedException is thrown.
+     * 
+     * @return this context's name in its own namespace; never null
+     * @exception OperationNotSupportedException if the naming system does 
+     * not have the notion of a full name
+     * @exception NamingException if a naming exception is encountered
+     */
+    public abstract String getNameInNamespace()
+        throws NamingException;
+
+
+    // ----------------------------------------------------- DirContext Methods
+
+
+    /**
+     * Retrieves all of the attributes associated with a named object. 
+     * 
+     * @return the set of attributes associated with name. 
+     * Returns an empty attribute set if name has no attributes; never null.
+     * @param name the name of the object from which to retrieve attributes
+     * @exception NamingException if a naming exception is encountered
+     */
+    public Attributes getAttributes(Name name)
+        throws NamingException {
+        return getAttributes(name.toString());
+    }
+
+
+    /**
+     * Retrieves all of the attributes associated with a named object.
+     * 
+     * @return the set of attributes associated with name
+     * @param name the name of the object from which to retrieve attributes
+     * @exception NamingException if a naming exception is encountered
+     */
+    public Attributes getAttributes(String name)
+        throws NamingException {
+        return getAttributes(name, null);
+    }
+
+
+    /**
+     * Retrieves selected attributes associated with a named object. 
+     * See the class description regarding attribute models, attribute type 
+     * names, and operational attributes.
+     * 
+     * @return the requested attributes; never null
+     * @param name the name of the object from which to retrieve attributes
+     * @param attrIds the identifiers of the attributes to retrieve. null 
+     * indicates that all attributes should be retrieved; an empty array 
+     * indicates that none should be retrieved
+     * @exception NamingException if a naming exception is encountered
+     */
+    public Attributes getAttributes(Name name, String[] attrIds)
+        throws NamingException {
+        return getAttributes(name.toString(), attrIds);
+    }
+    
+    
+    /**
+     * Retrieves selected attributes associated with a named object.
+     * 
+     * @return the requested attributes; never null
+     * @param name the name of the object from which to retrieve attributes
+     * @param attrIds the identifiers of the attributes to retrieve. null 
+     * indicates that all attributes should be retrieved; an empty array 
+     * indicates that none should be retrieved
+     * @exception NamingException if a naming exception is encountered
+     */
+    public abstract Attributes getAttributes(String name, String[] attrIds)
+        throws NamingException;
+
+
+    /**
+     * Modifies the attributes associated with a named object. The order of 
+     * the modifications is not specified. Where possible, the modifications 
+     * are performed atomically.
+     * 
+     * @param name the name of the object whose attributes will be updated
+     * @param mod_op the modification operation, one of: ADD_ATTRIBUTE, 
+     * REPLACE_ATTRIBUTE, REMOVE_ATTRIBUTE
+     * @param attrs the attributes to be used for the modification; may not 
+     * be null
+     * @exception AttributeModificationException if the modification cannot be
+     * completed successfully
+     * @exception NamingException if a naming exception is encountered
+     */
+    public void modifyAttributes(Name name, int mod_op, Attributes attrs)
+        throws NamingException {
+        modifyAttributes(name.toString(), mod_op, attrs);
+    }
+
+
+    /**
+     * Modifies the attributes associated with a named object.
+     * 
+     * @param name the name of the object whose attributes will be updated
+     * @param mod_op the modification operation, one of: ADD_ATTRIBUTE, 
+     * REPLACE_ATTRIBUTE, REMOVE_ATTRIBUTE
+     * @param attrs the attributes to be used for the modification; may not 
+     * be null
+     * @exception AttributeModificationException if the modification cannot be
+     * completed successfully
+     * @exception NamingException if a naming exception is encountered
+     */
+    public abstract void modifyAttributes
+        (String name, int mod_op, Attributes attrs)
+        throws NamingException;
+
+
+    /**
+     * Modifies the attributes associated with a named object using an an 
+     * ordered list of modifications. The modifications are performed in the 
+     * order specified. Each modification specifies a modification operation 
+     * code and an attribute on which to operate. Where possible, the 
+     * modifications are performed atomically.
+     * 
+     * @param name the name of the object whose attributes will be updated
+     * @param mods an ordered sequence of modifications to be performed; may 
+     * not be null
+     * @exception AttributeModificationException if the modification cannot be
+     * completed successfully
+     * @exception NamingException if a naming exception is encountered
+     */
+    public void modifyAttributes(Name name, ModificationItem[] mods)
+        throws NamingException {
+        modifyAttributes(name.toString(), mods);
+    }
+
+
+    /**
+     * Modifies the attributes associated with a named object using an an 
+     * ordered list of modifications.
+     * 
+     * @param name the name of the object whose attributes will be updated
+     * @param mods an ordered sequence of modifications to be performed; may 
+     * not be null
+     * @exception AttributeModificationException if the modification cannot be
+     * completed successfully
+     * @exception NamingException if a naming exception is encountered
+     */
+    public abstract void modifyAttributes(String name, ModificationItem[] mods)
+        throws NamingException;
+
+
+    /**
+     * Binds a name to an object, along with associated attributes. If attrs 
+     * is null, the resulting binding will have the attributes associated 
+     * with obj if obj is a DirContext, and no attributes otherwise. If attrs 
+     * is non-null, the resulting binding will have attrs as its attributes; 
+     * any attributes associated with obj are ignored.
+     * 
+     * @param name the name to bind; may not be empty
+     * @param obj the object to bind; possibly null
+     * @param attrs the attributes to associate with the binding
+     * @exception NameAlreadyBoundException if name is already bound
+     * @exception InvalidAttributesException if some "mandatory" attributes 
+     * of the binding are not supplied
+     * @exception NamingException if a naming exception is encountered
+     */
+    public void bind(Name name, Object obj, Attributes attrs)
+        throws NamingException {
+        bind(name.toString(), obj, attrs);
+    }
+
+
+    /**
+     * Binds a name to an object, along with associated attributes.
+     * 
+     * @param name the name to bind; may not be empty
+     * @param obj the object to bind; possibly null
+     * @param attrs the attributes to associate with the binding
+     * @exception NameAlreadyBoundException if name is already bound
+     * @exception InvalidAttributesException if some "mandatory" attributes 
+     * of the binding are not supplied
+     * @exception NamingException if a naming exception is encountered
+     */
+    public abstract void bind(String name, Object obj, Attributes attrs)
+        throws NamingException;
+
+
+    /**
+     * Binds a name to an object, along with associated attributes, 
+     * overwriting any existing binding. If attrs is null and obj is a 
+     * DirContext, the attributes from obj are used. If attrs is null and obj 
+     * is not a DirContext, any existing attributes associated with the object
+     * already bound in the directory remain unchanged. If attrs is non-null, 
+     * any existing attributes associated with the object already bound in 
+     * the directory are removed and attrs is associated with the named 
+     * object. If obj is a DirContext and attrs is non-null, the attributes 
+     * of obj are ignored.
+     * 
+     * @param name the name to bind; may not be empty
+     * @param obj the object to bind; possibly null
+     * @param attrs the attributes to associate with the binding
+     * @exception InvalidAttributesException if some "mandatory" attributes 
+     * of the binding are not supplied
+     * @exception NamingException if a naming exception is encountered
+     */
+    public void rebind(Name name, Object obj, Attributes attrs)
+        throws NamingException {
+        rebind(name.toString(), obj, attrs);
+    }
+
+
+    /**
+     * Binds a name to an object, along with associated attributes, 
+     * overwriting any existing binding.
+     * 
+     * @param name the name to bind; may not be empty
+     * @param obj the object to bind; possibly null
+     * @param attrs the attributes to associate with the binding
+     * @exception InvalidAttributesException if some "mandatory" attributes 
+     * of the binding are not supplied
+     * @exception NamingException if a naming exception is encountered
+     */
+    public abstract void rebind(String name, Object obj, Attributes attrs)
+        throws NamingException;
+
+
+    /**
+     * Creates and binds a new context, along with associated attributes. 
+     * This method creates a new subcontext with the given name, binds it in 
+     * the target context (that named by all but terminal atomic component of 
+     * the name), and associates the supplied attributes with the newly 
+     * created object. All intermediate and target contexts must already 
+     * exist. If attrs is null, this method is equivalent to 
+     * Context.createSubcontext().
+     * 
+     * @param name the name of the context to create; may not be empty
+     * @param attrs the attributes to associate with the newly created context
+     * @return the newly created context
+     * @exception NameAlreadyBoundException if the name is already bound
+     * @exception InvalidAttributesException if attrs does not contain all 
+     * the mandatory attributes required for creation
+     * @exception NamingException if a naming exception is encountered
+     */
+    public DirContext createSubcontext(Name name, Attributes attrs)
+        throws NamingException {
+        return createSubcontext(name.toString(), attrs);
+    }
+
+
+    /**
+     * Creates and binds a new context, along with associated attributes.
+     * 
+     * @param name the name of the context to create; may not be empty
+     * @param attrs the attributes to associate with the newly created context
+     * @return the newly created context
+     * @exception NameAlreadyBoundException if the name is already bound
+     * @exception InvalidAttributesException if attrs does not contain all 
+     * the mandatory attributes required for creation
+     * @exception NamingException if a naming exception is encountered
+     */
+    public abstract DirContext createSubcontext(String name, Attributes attrs)
+        throws NamingException;
+
+
+    /**
+     * Retrieves the schema associated with the named object. The schema 
+     * describes rules regarding the structure of the namespace and the 
+     * attributes stored within it. The schema specifies what types of 
+     * objects can be added to the directory and where they can be added; 
+     * what mandatory and optional attributes an object can have. The range 
+     * of support for schemas is directory-specific.
+     * 
+     * @param name the name of the object whose schema is to be retrieved
+     * @return the schema associated with the context; never null
+     * @exception OperationNotSupportedException if schema not supported
+     * @exception NamingException if a naming exception is encountered
+     */
+    public DirContext getSchema(Name name)
+        throws NamingException {
+        return getSchema(name.toString());
+    }
+
+
+    /**
+     * Retrieves the schema associated with the named object.
+     * 
+     * @param name the name of the object whose schema is to be retrieved
+     * @return the schema associated with the context; never null
+     * @exception OperationNotSupportedException if schema not supported
+     * @exception NamingException if a naming exception is encountered
+     */
+    public abstract DirContext getSchema(String name)
+        throws NamingException;
+
+
+    /**
+     * Retrieves a context containing the schema objects of the named 
+     * object's class definitions.
+     * 
+     * @param name the name of the object whose object class definition is to 
+     * be retrieved
+     * @return the DirContext containing the named object's class 
+     * definitions; never null
+     * @exception OperationNotSupportedException if schema not supported
+     * @exception NamingException if a naming exception is encountered
+     */
+    public DirContext getSchemaClassDefinition(Name name)
+        throws NamingException {
+        return getSchemaClassDefinition(name.toString());
+    }
+
+
+    /**
+     * Retrieves a context containing the schema objects of the named 
+     * object's class definitions.
+     * 
+     * @param name the name of the object whose object class definition is to 
+     * be retrieved
+     * @return the DirContext containing the named object's class 
+     * definitions; never null
+     * @exception OperationNotSupportedException if schema not supported
+     * @exception NamingException if a naming exception is encountered
+     */
+    public abstract DirContext getSchemaClassDefinition(String name)
+        throws NamingException;
+
+
+    /**
+     * Searches in a single context for objects that contain a specified set 
+     * of attributes, and retrieves selected attributes. The search is 
+     * performed using the default SearchControls settings.
+     * 
+     * @param name the name of the context to search
+     * @param matchingAttributes the attributes to search for. If empty or 
+     * null, all objects in the target context are returned.
+     * @param attributesToReturn the attributes to return. null indicates 
+     * that all attributes are to be returned; an empty array indicates that 
+     * none are to be returned.
+     * @return a non-null enumeration of SearchResult objects. Each 
+     * SearchResult contains the attributes identified by attributesToReturn 
+     * and the name of the corresponding object, named relative to the 
+     * context named by name.
+     * @exception NamingException if a naming exception is encountered
+     */
+    public NamingEnumeration search(Name name, Attributes matchingAttributes,
+                                    String[] attributesToReturn)
+        throws NamingException {
+        return search(name.toString(), matchingAttributes, attributesToReturn);
+    }
+
+
+    /**
+     * Searches in a single context for objects that contain a specified set 
+     * of attributes, and retrieves selected attributes.
+     * 
+     * @param name the name of the context to search
+     * @param matchingAttributes the attributes to search for. If empty or 
+     * null, all objects in the target context are returned.
+     * @param attributesToReturn the attributes to return. null indicates 
+     * that all attributes are to be returned; an empty array indicates that 
+     * none are to be returned.
+     * @return a non-null enumeration of SearchResult objects. Each 
+     * SearchResult contains the attributes identified by attributesToReturn 
+     * and the name of the corresponding object, named relative to the 
+     * context named by name.
+     * @exception NamingException if a naming exception is encountered
+     */
+    public abstract NamingEnumeration search
+        (String name, Attributes matchingAttributes,
+         String[] attributesToReturn)
+        throws NamingException;
+
+
+    /**
+     * Searches in a single context for objects that contain a specified set 
+     * of attributes. This method returns all the attributes of such objects. 
+     * It is equivalent to supplying null as the atributesToReturn parameter 
+     * to the method search(Name, Attributes, String[]).
+     * 
+     * @param name the name of the context to search
+     * @param matchingAttributes the attributes to search for. If empty or 
+     * null, all objects in the target context are returned.
+     * @return a non-null enumeration of SearchResult objects. Each 
+     * SearchResult contains the attributes identified by attributesToReturn 
+     * and the name of the corresponding object, named relative to the 
+     * context named by name.
+     * @exception NamingException if a naming exception is encountered
+     */
+    public NamingEnumeration search(Name name, Attributes matchingAttributes)
+        throws NamingException {
+        return search(name.toString(), matchingAttributes);
+    }
+
+
+    /**
+     * Searches in a single context for objects that contain a specified set 
+     * of attributes.
+     * 
+     * @param name the name of the context to search
+     * @param matchingAttributes the attributes to search for. If empty or 
+     * null, all objects in the target context are returned.
+     * @return a non-null enumeration of SearchResult objects. Each 
+     * SearchResult contains the attributes identified by attributesToReturn 
+     * and the name of the corresponding object, named relative to the 
+     * context named by name.
+     * @exception NamingException if a naming exception is encountered
+     */
+    public abstract NamingEnumeration search
+        (String name, Attributes matchingAttributes)
+        throws NamingException;
+
+
+    /**
+     * Searches in the named context or object for entries that satisfy the 
+     * given search filter. Performs the search as specified by the search 
+     * controls.
+     * 
+     * @param name the name of the context or object to search
+     * @param filter the filter expression to use for the search; may not be 
+     * null
+     * @param cons the search controls that control the search. If null, 
+     * the default search controls are used (equivalent to 
+     * (new SearchControls())).
+     * @return an enumeration of SearchResults of the objects that satisfy 
+     * the filter; never null
+     * @exception InvalidSearchFilterException if the search filter specified 
+     * is not supported or understood by the underlying directory
+     * @exception InvalidSearchControlsException if the search controls 
+     * contain invalid settings
+     * @exception NamingException if a naming exception is encountered
+     */
+    public NamingEnumeration search
+        (Name name, String filter, SearchControls cons)
+        throws NamingException {
+        return search(name.toString(), filter, cons);
+    }
+
+
+    /**
+     * Searches in the named context or object for entries that satisfy the 
+     * given search filter. Performs the search as specified by the search 
+     * controls.
+     * 
+     * @param name the name of the context or object to search
+     * @param filter the filter expression to use for the search; may not be 
+     * null
+     * @param cons the search controls that control the search. If null, 
+     * the default search controls are used (equivalent to 
+     * (new SearchControls())).
+     * @return an enumeration of SearchResults of the objects that satisfy 
+     * the filter; never null
+     * @exception InvalidSearchFilterException if the search filter 
+     * specified is not supported or understood by the underlying directory
+     * @exception InvalidSearchControlsException if the search controls 
+     * contain invalid settings
+     * @exception NamingException if a naming exception is encountered
+     */
+    public abstract NamingEnumeration search(String name, String filter, 
+                                             SearchControls cons)
+        throws NamingException;
+
+
+    /**
+     * Searches in the named context or object for entries that satisfy the 
+     * given search filter. Performs the search as specified by the search 
+     * controls.
+     * 
+     * @param name the name of the context or object to search
+     * @param filterExpr the filter expression to use for the search. 
+     * The expression may contain variables of the form "{i}" where i is a 
+     * nonnegative integer. May not be null.
+     * @param filterArgs the array of arguments to substitute for the 
+     * variables in filterExpr. The value of filterArgs[i] will replace each 
+     * occurrence of "{i}". If null, equivalent to an empty array.
+     * @param cons the search controls that control the search. If null, the 
+     * default search controls are used (equivalent to (new SearchControls())).
+     * @return an enumeration of SearchResults of the objects that satisy the 
+     * filter; never null
+     * @exception ArrayIndexOutOfBoundsException if filterExpr contains {i} 
+     * expressions where i is outside the bounds of the array filterArgs
+     * @exception InvalidSearchControlsException if cons contains invalid 
+     * settings
+     * @exception InvalidSearchFilterException if filterExpr with filterArgs 
+     * represents an invalid search filter
+     * @exception NamingException if a naming exception is encountered
+     */
+    public NamingEnumeration search(Name name, String filterExpr, 
+                                    Object[] filterArgs, SearchControls cons)
+        throws NamingException {
+        return search(name.toString(), filterExpr, filterArgs, cons);
+    }
+
+
+    /**
+     * Searches in the named context or object for entries that satisfy the 
+     * given search filter. Performs the search as specified by the search 
+     * controls.
+     * 
+     * @param name the name of the context or object to search
+     * @param filterExpr the filter expression to use for the search. 
+     * The expression may contain variables of the form "{i}" where i is a 
+     * nonnegative integer. May not be null.
+     * @param filterArgs the array of arguments to substitute for the 
+     * variables in filterExpr. The value of filterArgs[i] will replace each 
+     * occurrence of "{i}". If null, equivalent to an empty array.
+     * @param cons the search controls that control the search. If null, the 
+     * default search controls are used (equivalent to (new SearchControls())).
+     * @return an enumeration of SearchResults of the objects that satisy the 
+     * filter; never null
+     * @exception ArrayIndexOutOfBoundsException if filterExpr contains {i} 
+     * expressions where i is outside the bounds of the array filterArgs
+     * @exception InvalidSearchControlsException if cons contains invalid 
+     * settings
+     * @exception InvalidSearchFilterException if filterExpr with filterArgs 
+     * represents an invalid search filter
+     * @exception NamingException if a naming exception is encountered
+     */
+    public abstract NamingEnumeration search
+        (String name, String filterExpr, 
+         Object[] filterArgs, SearchControls cons)
+        throws NamingException;
+
+
+    // ------------------------------------------------------ Protected Methods
+
+
+}
+

Added: incubator/directory/naming/trunk/core/src/java/org/apache/directory/naming/resources/Constants.java
==============================================================================
--- (empty file)
+++ incubator/directory/naming/trunk/core/src/java/org/apache/directory/naming/resources/Constants.java	Sun Dec  7 13:00:05 2003
@@ -0,0 +1,79 @@
+/*
+ * $Header: /home/cvs/jakarta-commons-sandbox/naming/core/src/java/org/apache/commons/naming/resources/Constants.java,v 1.2 2003/10/13 08:15:54 rdonkin Exp $
+ * $Revision: 1.2 $
+ * $Date: 2003/10/13 08:15:54 $
+ *
+ * ====================================================================
+ *
+ * The Apache Software License, Version 1.1
+ *
+ * Copyright (c) 1999 The Apache Software Foundation.  All rights 
+ * reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. The end-user documentation included with the redistribution, if
+ *    any, must include the following acknowledgement:
+ *       "This product includes software developed by the 
+ *        Apache Software Foundation (http://www.apache.org/)."
+ *    Alternately, this acknowledgement may appear in the software itself,
+ *    if and wherever such third-party acknowledgements normally appear.
+ *
+ * 4. The names "The Jakarta Project", "Tomcat", and "Apache Software
+ *    Foundation" must not be used to endorse or promote products derived
+ *    from this software without prior written permission. For written 
+ *    permission, please contact apache@apache.org.
+ *
+ * 5. Products derived from this software may not be called "Apache"
+ *    nor may "Apache" appear in their names without prior written
+ *    permission of the Apache Software Foundation.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation.  For more
+ * information on the Apache Software Foundation, please see
+ * <http://www.apache.org/>.
+ *
+ * [Additional notices, if required by prior licensing conditions]
+ *
+ */ 
+
+
+package org.apache.directory.naming.resources;
+
+
+/**
+ * Static constants for this package.
+ */
+
+public final class Constants {
+
+    public static final String PROTOCOL_HANDLER_VARIABLE = 
+        "java.protocol.handler.pkgs";
+
+    public static final String Package = "org.apache.directory.naming.resources";
+
+}

Added: incubator/directory/naming/trunk/core/src/java/org/apache/directory/naming/resources/DirContextURLConnection.java
==============================================================================
--- (empty file)
+++ incubator/directory/naming/trunk/core/src/java/org/apache/directory/naming/resources/DirContextURLConnection.java	Sun Dec  7 13:00:05 2003
@@ -0,0 +1,405 @@
+/*
+ * $Header: /home/cvs/jakarta-commons-sandbox/naming/core/src/java/org/apache/commons/naming/resources/DirContextURLConnection.java,v 1.2 2003/10/13 08:15:54 rdonkin Exp $
+ * $Revision: 1.2 $
+ * $Date: 2003/10/13 08:15:54 $
+ *
+ * ====================================================================
+ *
+ * The Apache Software License, Version 1.1
+ *
+ * Copyright (c) 1999 The Apache Software Foundation.  All rights 
+ * reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. The end-user documentation included with the redistribution, if
+ *    any, must include the following acknowledgement:
+ *       "This product includes software developed by the 
+ *        Apache Software Foundation (http://www.apache.org/)."
+ *    Alternately, this acknowledgement may appear in the software itself,
+ *    if and wherever such third-party acknowledgements normally appear.
+ *
+ * 4. The names "The Jakarta Project", "Tomcat", and "Apache Software
+ *    Foundation" must not be used to endorse or promote products derived
+ *    from this software without prior written permission. For written 
+ *    permission, please contact apache@apache.org.
+ *
+ * 5. Products derived from this software may not be called "Apache"
+ *    nor may "Apache" appear in their names without prior written
+ *    permission of the Apache Software Foundation.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation.  For more
+ * information on the Apache Software Foundation, please see
+ * <http://www.apache.org/>.
+ *
+ * [Additional notices, if required by prior licensing conditions]
+ *
+ */ 
+
+package org.apache.directory.naming.resources;
+
+import java.net.URL;
+import java.net.URLConnection;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.FileNotFoundException;
+import java.security.Permission;
+import java.util.Date;
+import java.util.Enumeration;
+import java.util.Vector;
+import javax.naming.NamingException;
+import javax.naming.NamingEnumeration;
+import javax.naming.NameClassPair;
+import javax.naming.directory.DirContext;
+import javax.naming.directory.Attribute;
+import javax.naming.directory.Attributes;
+import org.apache.directory.naming.JndiPermission;
+import org.apache.directory.naming.resources.Resource;
+import org.apache.directory.naming.resources.ResourceAttributes;
+
+/**
+ * Connection to a JNDI directory context.
+ * <p/>
+ * Note: All the object attribute names are the WebDAV names, not the HTTP 
+ * names, so this class overrides some methods from URLConnection to do the
+ * queries using the right names. Content handler is also not used; the 
+ * content is directly returned.
+ * 
+ * @author <a href="mailto:remm@apache.org">Remy Maucherat</a>
+ * @version $Revision: 1.2 $
+ */
+public class DirContextURLConnection 
+    extends URLConnection {
+    
+    
+    // ----------------------------------------------------------- Constructors
+    
+    
+    public DirContextURLConnection(DirContext context, URL url) {
+        super(url);
+        if (context == null)
+            throw new IllegalArgumentException
+                ("Directory context can't be null");
+        if (System.getSecurityManager() != null) {
+            this.permission = new JndiPermission(url.toString());
+	}
+        this.context = context;
+    }
+    
+    
+    // ----------------------------------------------------- Instance Variables
+    
+    
+    /**
+     * Directory context.
+     */
+    protected DirContext context;
+    
+    
+    /**
+     * Associated resource.
+     */
+    protected Resource resource;
+    
+    
+    /**
+     * Associated DirContext.
+     */
+    protected DirContext collection;
+    
+    
+    /**
+     * Other unknown object.
+     */
+    protected Object object;
+    
+    
+    /**
+     * Attributes.
+     */
+    protected Attributes attributes;
+    
+    
+    /**
+     * Date.
+     */
+    protected long date;
+    
+    
+    /**
+     * Permission
+     */
+    protected Permission permission;
+
+
+    // ------------------------------------------------------------- Properties
+    
+    
+    /**
+     * Connect to the DirContext, and retrive the bound object, as well as
+     * its attributes. If no object is bound with the name specified in the
+     * URL, then an IOException is thrown.
+     * 
+     * @throws IOException Object not found
+     */
+    public void connect()
+        throws IOException {
+        
+        if (!connected) {
+            
+            try {
+                date = System.currentTimeMillis();
+                String path = getURL().getFile();
+                if (context instanceof ProxyDirContext) {
+                    ProxyDirContext proxyDirContext = 
+                        (ProxyDirContext) context;
+                    String hostName = proxyDirContext.getHostName();
+                    String contextName = proxyDirContext.getContextName();
+                    if (hostName != null) {
+                        if (!path.startsWith("/" + hostName + "/"))
+                            return;
+                        path = path.substring(hostName.length()+ 1);
+                    }
+                    if (contextName != null) {
+                        if (!path.startsWith(contextName + "/")) {
+                            return;
+                        } else {
+                            path = path.substring(contextName.length());
+                        }
+                    }
+                }
+                object = context.lookup(path);
+                attributes = context.getAttributes(path);
+                if (object instanceof Resource)
+                    resource = (Resource) object;
+                if (object instanceof DirContext)
+                    collection = (DirContext) object;
+            } catch (NamingException e) {
+                // Object not found
+            }
+            
+            connected = true;
+            
+        }
+        
+    }
+    
+    
+    /**
+     * Return the content length value.
+     */
+    public int getContentLength() {
+        return getHeaderFieldInt(ResourceAttributes.CONTENT_LENGTH, -1);
+    }
+    
+    
+    /**
+     * Return the content type value.
+     */
+    public String getContentType() {
+        return getHeaderField(ResourceAttributes.CONTENT_TYPE);
+    }
+    
+    
+    /**
+     * Return the last modified date.
+     */
+    public long getDate() {
+        return date;
+    }
+    
+    
+    /**
+     * Return the last modified date.
+     */
+    public long getLastModified() {
+
+        if (!connected) {
+            // Try to connect (silently)
+            try {
+                connect();
+            } catch (IOException e) {
+            }
+        }
+
+        if (attributes == null)
+            return 0;
+
+        Attribute lastModified = 
+            attributes.get(ResourceAttributes.LAST_MODIFIED);
+        if (lastModified != null) {
+            try {
+                Date lmDate = (Date) lastModified.get();
+                return lmDate.getTime();
+            } catch (Exception e) {
+            }
+        }
+
+        return 0;
+    }
+    
+    
+    /**
+     * Returns the name of the specified header field.
+     */
+    public String getHeaderField(String name) {
+
+        if (!connected) {
+            // Try to connect (silently)
+            try {
+                connect();
+            } catch (IOException e) {
+            }
+        }
+        
+        if (attributes == null)
+            return (null);
+
+        Attribute attribute = attributes.get(name);
+        try {
+            return attribute.get().toString();
+        } catch (Exception e) {
+            // Shouldn't happen, unless the attribute has no value
+        }
+
+        return (null);
+        
+    }
+    
+    
+    /**
+     * Get object content.
+     */
+    public Object getContent()
+        throws IOException {
+        
+        if (!connected)
+            connect();
+        
+        if (resource != null)
+            return getInputStream();
+        if (collection != null)
+            return collection;
+        if (object != null)
+            return object;
+        
+        throw new FileNotFoundException();
+        
+    }
+    
+    
+    /**
+     * Get object content.
+     */
+    public Object getContent(Class[] classes)
+        throws IOException {
+        
+        Object object = getContent();
+        
+        for (int i = 0; i < classes.length; i++) {
+            if (classes[i].isInstance(object))
+                return object;
+        }
+        
+        return null;
+        
+    }
+    
+    
+    /**
+     * Get input stream.
+     */
+    public InputStream getInputStream() 
+        throws IOException {
+        
+        if (!connected)
+            connect();
+        
+        if (resource == null) {
+            throw new FileNotFoundException();
+        } else {
+            // Reopen resource
+            try {
+                resource = (Resource) context.lookup(getURL().getFile());
+            } catch (NamingException e) {
+            }
+        }
+        
+        return (resource.streamContent());
+        
+    }
+    
+    
+    /**
+     * Get the Permission for this URL
+     */
+    public Permission getPermission() {
+
+        return permission;
+    }
+
+
+    // --------------------------------------------------------- Public Methods
+    
+    
+    /**
+     * List children of this collection. The names given are relative to this
+     * URI's path. The full uri of the children is then : path + "/" + name.
+     */
+    public Enumeration list()
+        throws IOException {
+        
+        if (!connected) {
+            connect();
+        }
+        
+        if ((resource == null) && (collection == null)) {
+            throw new FileNotFoundException();
+        }
+        
+        Vector result = new Vector();
+        
+        if (collection != null) {
+            try {
+                NamingEnumeration enum = context.list(getURL().getFile());
+                while (enum.hasMoreElements()) {
+                    NameClassPair ncp = (NameClassPair) enum.nextElement();
+                    result.addElement(ncp.getName());
+                }
+            } catch (NamingException e) {
+                // Unexpected exception
+                throw new FileNotFoundException();
+            }
+        }
+        
+        return result.elements();
+        
+    }
+    
+    
+}

Added: incubator/directory/naming/trunk/core/src/java/org/apache/directory/naming/resources/DirContextURLStreamHandler.java
==============================================================================
--- (empty file)
+++ incubator/directory/naming/trunk/core/src/java/org/apache/directory/naming/resources/DirContextURLStreamHandler.java	Sun Dec  7 13:00:05 2003
@@ -0,0 +1,273 @@
+/*
+ * $Header: /home/cvs/jakarta-commons-sandbox/naming/core/src/java/org/apache/commons/naming/resources/DirContextURLStreamHandler.java,v 1.2 2003/10/13 08:15:54 rdonkin Exp $
+ * $Revision: 1.2 $
+ * $Date: 2003/10/13 08:15:54 $
+ *
+ * ====================================================================
+ *
+ * The Apache Software License, Version 1.1
+ *
+ * Copyright (c) 1999 The Apache Software Foundation.  All rights 
+ * reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. The end-user documentation included with the redistribution, if
+ *    any, must include the following acknowledgement:
+ *       "This product includes software developed by the 
+ *        Apache Software Foundation (http://www.apache.org/)."
+ *    Alternately, this acknowledgement may appear in the software itself,
+ *    if and wherever such third-party acknowledgements normally appear.
+ *
+ * 4. The names "The Jakarta Project", "Tomcat", and "Apache Software
+ *    Foundation" must not be used to endorse or promote products derived
+ *    from this software without prior written permission. For written 
+ *    permission, please contact apache@apache.org.
+ *
+ * 5. Products derived from this software may not be called "Apache"
+ *    nor may "Apache" appear in their names without prior written
+ *    permission of the Apache Software Foundation.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation.  For more
+ * information on the Apache Software Foundation, please see
+ * <http://www.apache.org/>.
+ *
+ * [Additional notices, if required by prior licensing conditions]
+ *
+ */ 
+
+package org.apache.directory.naming.resources;
+
+import java.net.URL;
+import java.net.URLConnection;
+import java.net.URLStreamHandler;
+import java.io.IOException;
+import java.util.Hashtable;
+import javax.naming.NamingException;
+import javax.naming.directory.DirContext;
+
+/**
+ * Stream handler to a JNDI directory context.
+ * 
+ * @author <a href="mailto:remm@apache.org">Remy Maucherat</a>
+ * @version $Revision: 1.2 $
+ */
+public class DirContextURLStreamHandler 
+    extends URLStreamHandler {
+    
+    
+    // ----------------------------------------------------------- Constructors
+    
+    
+    public DirContextURLStreamHandler() {
+    }
+    
+    
+    public DirContextURLStreamHandler(DirContext context) {
+        this.context = context;
+    }
+    
+    
+    // -------------------------------------------------------------- Variables
+    
+    
+    /**
+     * Bindings class loader - directory context. Keyed by CL id.
+     */
+    private static Hashtable clBindings = new Hashtable();
+    
+    
+    /**
+     * Bindings thread - directory context. Keyed by thread id.
+     */
+    private static Hashtable threadBindings = new Hashtable();
+    
+    
+    // ----------------------------------------------------- Instance Variables
+    
+    
+    /**
+     * Directory context.
+     */
+    protected DirContext context = null;
+    
+    
+    // ------------------------------------------------------------- Properties
+    
+    
+    // ----------------------------------------------- URLStreamHandler Methods
+    
+    
+    /**
+     * Opens a connection to the object referenced by the <code>URL</code> 
+     * argument.
+     */
+    protected URLConnection openConnection(URL u) 
+        throws IOException {
+        DirContext currentContext = this.context;
+        if (currentContext == null)
+            currentContext = get();
+        return new DirContextURLConnection(currentContext, u);
+    }
+    
+    
+    // --------------------------------------------------------- Public Methods
+    
+    
+    /**
+     * Set the java.protocol.handler.pkgs system property.
+     */
+    public static void setProtocolHandler() {
+        String value = System.getProperty(Constants.PROTOCOL_HANDLER_VARIABLE);
+        if (value == null) {
+            value = Constants.Package;
+            System.setProperty(Constants.PROTOCOL_HANDLER_VARIABLE, value);
+        } else if (value.indexOf(Constants.Package) == -1) {
+            value += "|" + Constants.Package;
+            System.setProperty(Constants.PROTOCOL_HANDLER_VARIABLE, value);
+        }
+    }
+    
+    
+    /**
+     * Returns true if the thread or the context class loader of the current 
+     * thread is bound.
+     */
+    public static boolean isBound() {
+        return (clBindings.containsKey
+                (Thread.currentThread().getContextClassLoader()))
+            || (threadBindings.containsKey(Thread.currentThread()));
+    }
+    
+    
+    /**
+     * Binds a directory context to a class loader.
+     */
+    public static void bind(DirContext dirContext) {
+        ClassLoader currentCL = 
+            Thread.currentThread().getContextClassLoader();
+        if (currentCL != null)
+            clBindings.put(currentCL, dirContext);
+    }
+    
+    
+    /**
+     * Unbinds a directory context to a class loader.
+     */
+    public static void unbind() {
+        ClassLoader currentCL = 
+            Thread.currentThread().getContextClassLoader();
+        if (currentCL != null)
+            clBindings.remove(currentCL);
+    }
+    
+    
+    /**
+     * Binds a directory context to a thread.
+     */
+    public static void bindThread(DirContext dirContext) {
+        threadBindings.put(Thread.currentThread(), dirContext);
+    }
+    
+    
+    /**
+     * Unbinds a directory context to a thread.
+     */
+    public static void unbindThread() {
+        threadBindings.remove(Thread.currentThread());
+    }
+    
+    
+    /**
+     * Get the bound context.
+     */
+    public static DirContext get() {
+
+        DirContext result = null;
+
+        Thread currentThread = Thread.currentThread();
+        ClassLoader currentCL = currentThread.getContextClassLoader();
+
+        // Checking CL binding
+        result = (DirContext) clBindings.get(currentCL);
+        if (result != null)
+            return result;
+
+        // Checking thread biding
+        result = (DirContext) threadBindings.get(currentThread);
+
+        // Checking parent CL binding
+        currentCL = currentCL.getParent();
+        while (currentCL != null) {
+            result = (DirContext) clBindings.get(currentCL);
+            if (result != null)
+                return result;
+            currentCL = currentCL.getParent();
+        }
+
+        if (result == null)
+            throw new IllegalStateException("Illegal class loader binding");
+
+        return result;
+
+    }
+    
+    
+    /**
+     * Binds a directory context to a class loader.
+     */
+    public static void bind(ClassLoader cl, DirContext dirContext) {
+        clBindings.put(cl, dirContext);
+    }
+    
+    
+    /**
+     * Unbinds a directory context to a class loader.
+     */
+    public static void unbind(ClassLoader cl) {
+        clBindings.remove(cl);
+    }
+    
+    
+    /**
+     * Get the bound context.
+     */
+    public static DirContext get(ClassLoader cl) {
+        return (DirContext) clBindings.get(cl);
+    }
+    
+    
+    /**
+     * Get the bound context.
+     */
+    public static DirContext get(Thread thread) {
+        return (DirContext) threadBindings.get(thread);
+    }
+    
+    
+}

Added: incubator/directory/naming/trunk/core/src/java/org/apache/directory/naming/resources/DirContextURLStreamHandlerFactory.java
==============================================================================
--- (empty file)
+++ incubator/directory/naming/trunk/core/src/java/org/apache/directory/naming/resources/DirContextURLStreamHandlerFactory.java	Sun Dec  7 13:00:05 2003
@@ -0,0 +1,115 @@
+/*
+ * $Header: /home/cvs/jakarta-commons-sandbox/naming/core/src/java/org/apache/commons/naming/resources/DirContextURLStreamHandlerFactory.java,v 1.2 2003/10/13 08:15:54 rdonkin Exp $
+ * $Revision: 1.2 $
+ * $Date: 2003/10/13 08:15:54 $
+ *
+ * ====================================================================
+ *
+ * The Apache Software License, Version 1.1
+ *
+ * Copyright (c) 1999 The Apache Software Foundation.  All rights 
+ * reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. The end-user documentation included with the redistribution, if
+ *    any, must include the following acknowledgement:
+ *       "This product includes software developed by the 
+ *        Apache Software Foundation (http://www.apache.org/)."
+ *    Alternately, this acknowledgement may appear in the software itself,
+ *    if and wherever such third-party acknowledgements normally appear.
+ *
+ * 4. The names "The Jakarta Project", "Tomcat", and "Apache Software
+ *    Foundation" must not be used to endorse or promote products derived
+ *    from this software without prior written permission. For written 
+ *    permission, please contact apache@apache.org.
+ *
+ * 5. Products derived from this software may not be called "Apache"
+ *    nor may "Apache" appear in their names without prior written
+ *    permission of the Apache Software Foundation.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation.  For more
+ * information on the Apache Software Foundation, please see
+ * <http://www.apache.org/>.
+ *
+ * [Additional notices, if required by prior licensing conditions]
+ *
+ */ 
+
+package org.apache.directory.naming.resources;
+
+import java.net.URLStreamHandler;
+import java.net.URLStreamHandlerFactory;
+import java.io.IOException;
+import javax.naming.NamingException;
+import javax.naming.directory.DirContext;
+
+/**
+ * Factory for Stream handlers to a JNDI directory context.
+ * 
+ * @author <a href="mailto:remm@apache.org">Remy Maucherat</a>
+ * @version $Revision: 1.2 $
+ */
+public class DirContextURLStreamHandlerFactory 
+    implements URLStreamHandlerFactory {
+    
+    
+    // ----------------------------------------------------------- Constructors
+    
+    
+    public DirContextURLStreamHandlerFactory() {
+    }
+    
+    
+    // ----------------------------------------------------- Instance Variables
+    
+    
+    // ------------------------------------------------------------- Properties
+    
+    
+    // ---------------------------------------- URLStreamHandlerFactory Methods
+    
+    
+    /**
+     * Creates a new URLStreamHandler instance with the specified protocol.
+     * Will return null if the protocol is not <code>jndi</code>.
+     * 
+     * @param protocol the protocol (must be "jndi" here)
+     * @return a URLStreamHandler for the jndi protocol, or null if the 
+     * protocol is not JNDI
+     */
+    public URLStreamHandler createURLStreamHandler(String protocol) {
+        if (protocol.equals("jndi")) {
+            return new DirContextURLStreamHandler();
+        } else {
+            return null;
+        }
+    }
+    
+    
+}

Added: incubator/directory/naming/trunk/core/src/java/org/apache/directory/naming/resources/FileDirContext.java
==============================================================================
--- (empty file)
+++ incubator/directory/naming/trunk/core/src/java/org/apache/directory/naming/resources/FileDirContext.java	Sun Dec  7 13:00:05 2003
@@ -0,0 +1,1156 @@
+/*
+ * $Header: /home/cvs/jakarta-commons-sandbox/naming/core/src/java/org/apache/commons/naming/resources/FileDirContext.java,v 1.2 2003/10/13 08:15:54 rdonkin Exp $
+ * $Revision: 1.2 $
+ * $Date: 2003/10/13 08:15:54 $
+ *
+ * ====================================================================
+ *
+ * The Apache Software License, Version 1.1
+ *
+ * Copyright (c) 1999 The Apache Software Foundation.  All rights 
+ * reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. The end-user documentation included with the redistribution, if
+ *    any, must include the following acknowledgement:
+ *       "This product includes software developed by the 
+ *        Apache Software Foundation (http://www.apache.org/)."
+ *    Alternately, this acknowledgement may appear in the software itself,
+ *    if and wherever such third-party acknowledgements normally appear.
+ *
+ * 4. The names "The Jakarta Project", "Tomcat", and "Apache Software
+ *    Foundation" must not be used to endorse or promote products derived
+ *    from this software without prior written permission. For written 
+ *    permission, please contact apache@apache.org.
+ *
+ * 5. Products derived from this software may not be called "Apache"
+ *    nor may "Apache" appear in their names without prior written
+ *    permission of the Apache Software Foundation.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation.  For more
+ * information on the Apache Software Foundation, please see
+ * <http://www.apache.org/>.
+ *
+ * [Additional notices, if required by prior licensing conditions]
+ *
+ */ 
+
+
+package org.apache.directory.naming.resources;
+
+import java.util.Arrays;
+import java.util.Hashtable;
+import java.util.Vector;
+import java.util.Date;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.InputStream;
+import java.io.FileOutputStream;
+import java.io.FileNotFoundException;
+import java.io.OutputStream;
+import java.io.IOException;
+import javax.naming.Context;
+import javax.naming.Name;
+import javax.naming.NameParser;
+import javax.naming.NamingEnumeration;
+import javax.naming.NamingException;
+import javax.naming.CompositeName;
+import javax.naming.NameParser;
+import javax.naming.OperationNotSupportedException;
+import javax.naming.NameAlreadyBoundException;
+import javax.naming.directory.DirContext;
+import javax.naming.directory.Attributes;
+import javax.naming.directory.Attribute;
+import javax.naming.directory.ModificationItem;
+import javax.naming.directory.SearchControls;
+import org.apache.directory.naming.StringManager;
+import org.apache.directory.naming.NameParserImpl;
+import org.apache.directory.naming.NamingEntry;
+import org.apache.directory.naming.NamingContextBindingsEnumeration;
+import org.apache.directory.naming.NamingContextEnumeration;
+
+/**
+ * Filesystem Directory Context implementation helper class.
+ *
+ * @author Remy Maucherat
+ * @version $Revision: 1.2 $ $Date: 2003/10/13 08:15:54 $
+ */
+
+public class FileDirContext extends BaseDirContext {
+
+
+    // -------------------------------------------------------------- Constants
+
+
+    /**
+     * The descriptive information string for this implementation.
+     */
+    protected static final int BUFFER_SIZE = 2048;
+
+
+    // ----------------------------------------------------------- Constructors
+
+
+    /**
+     * Builds a file directory context using the given environment.
+     */
+    public FileDirContext() {
+        super();
+    }
+
+
+    /**
+     * Builds a file directory context using the given environment.
+     */
+    public FileDirContext(Hashtable env) {
+        super(env);
+    }
+
+
+    // ----------------------------------------------------- Instance Variables
+
+
+    /**
+     * The document base directory.
+     */
+    protected File base = null;
+
+
+    /**
+     * Absolute normalized filename of the base.
+     */
+    protected String absoluteBase = null;
+
+
+    /**
+     * Case sensitivity.
+     */
+    protected boolean caseSensitive = true;
+
+
+    /**
+     * Allow linking.
+     */
+    protected boolean allowLinking = false;
+
+
+    // ------------------------------------------------------------- Properties
+
+
+    /**
+     * Set the document root.
+     * 
+     * @param docBase The new document root
+     * 
+     * @exception IllegalArgumentException if the specified value is not
+     *  supported by this implementation
+     * @exception IllegalArgumentException if this would create a
+     *  malformed URL
+     */
+    public void setDocBase(String docBase) {
+
+	// Validate the format of the proposed document root
+	if (docBase == null)
+	    throw new IllegalArgumentException
+		(sm.getString("resources.null"));
+
+	// Calculate a File object referencing this document base directory
+	base = new File(docBase);
+        try {
+            base = base.getCanonicalFile();
+        } catch (IOException e) {
+            // Ignore
+        }
+
+	// Validate that the document base is an existing directory
+	if (!base.exists() || !base.isDirectory() || !base.canRead())
+	    throw new IllegalArgumentException
+		(sm.getString("fileResources.base", docBase));
+        this.absoluteBase = base.getAbsolutePath();
+        super.setDocBase(docBase);
+
+    }
+
+
+    /**
+     * Set case sensitivity.
+     */
+    public void setCaseSensitive(boolean caseSensitive) {
+        this.caseSensitive = caseSensitive;
+    }
+
+
+    /**
+     * Is case sensitive ?
+     */
+    public boolean isCaseSensitive() {
+        return caseSensitive;
+    }
+
+
+    /**
+     * Set allow linking.
+     */
+    public void setAllowLinking(boolean allowLinking) {
+        this.allowLinking = allowLinking;
+    }
+
+
+    /**
+     * Is linking allowed.
+     */
+    public boolean getAllowLinking() {
+        return allowLinking;
+    }
+
+
+    // --------------------------------------------------------- Public Methods
+
+
+    /**
+     * Release any resources allocated for this directory context.
+     */
+    public void release() {
+
+        caseSensitive = true;
+        allowLinking = false;
+        absoluteBase = null;
+        base = null;
+        super.release();
+
+    }
+
+
+    // -------------------------------------------------------- Context Methods
+
+
+    /**
+     * 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 {
+        Object result = null;
+        File file = file(name);
+        
+        if (file == null)
+            throw new NamingException
+                (sm.getString("resources.notFound", name));
+        
+        if (file.isDirectory()) {
+            FileDirContext tempContext = new FileDirContext(env);
+            tempContext.setDocBase(file.getPath());
+            result = tempContext;
+        } else {
+            result = new FileResource(file);
+        }
+        
+        return result;
+        
+    }
+
+
+    /**
+     * Unbinds the named object. Removes the terminal atomic name in name 
+     * from the target context--that named by all but the terminal atomic 
+     * part of name.
+     * <p>
+     * This method is idempotent. It succeeds even if the terminal atomic 
+     * name is not bound in the target context, but throws 
+     * NameNotFoundException if any of the intermediate contexts do not exist. 
+     * 
+     * @param name the name to bind; may not be empty
+     * @exception NameNotFoundException if an intermediate context does not 
+     * exist
+     * @exception NamingException if a naming exception is encountered
+     */
+    public void unbind(String name)
+        throws NamingException {
+
+        File file = file(name);
+
+        if (file == null)
+            throw new NamingException
+                (sm.getString("resources.notFound", name));
+
+        if (!file.delete())
+            throw new NamingException
+                (sm.getString("resources.unbindFailed", name));
+
+    }
+
+
+    /**
+     * Binds a new name to the object bound to an old name, and unbinds the 
+     * old name. Both names are relative to this context. Any attributes 
+     * associated with the old name become associated with the new name. 
+     * Intermediate contexts of the old name are not changed.
+     * 
+     * @param oldName the name of the existing binding; may not be empty
+     * @param newName the name of the new binding; may not be empty
+     * @exception NameAlreadyBoundException if newName is already bound
+     * @exception NamingException if a naming exception is encountered
+     */
+    public void rename(String oldName, String newName)
+        throws NamingException {
+        
+        File file = file(oldName);
+
+        if (file == null)
+            throw new NamingException
+                (sm.getString("resources.notFound", oldName));
+
+        File newFile = new File(base, newName);
+        
+        file.renameTo(newFile);
+        
+    }
+
+
+    /**
+     * Enumerates the names bound in the named context, along with the class 
+     * names of objects bound to them. The contents of any subcontexts are 
+     * not included.
+     * <p>
+     * If a binding is added to or removed from this context, its effect on 
+     * an enumeration previously returned is undefined.
+     * 
+     * @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 {
+
+        File file = file(name);
+
+        if (file == null)
+            throw new NamingException
+                (sm.getString("resources.notFound", name));
+
+        Vector entries = list(file);
+
+        return new NamingContextEnumeration(entries);
+
+    }
+
+
+    /**
+     * Enumerates the names bound in the named context, along with the 
+     * objects bound to them. The contents of any subcontexts are not 
+     * included.
+     * <p>
+     * If a binding is added to or removed from this context, its effect on 
+     * an enumeration previously returned is undefined.
+     * 
+     * @param name the name of the context to list
+     * @return an enumeration of the bindings in this context. 
+     * Each element of the enumeration is of type Binding.
+     * @exception NamingException if a naming exception is encountered
+     */
+    public NamingEnumeration listBindings(String name)
+        throws NamingException {
+
+        File file = file(name);
+
+        if (file == null)
+            throw new NamingException
+                (sm.getString("resources.notFound", name));
+
+        Vector entries = list(file);
+
+        return new NamingContextBindingsEnumeration(entries);
+
+    }
+
+
+    /**
+     * Destroys the named context and removes it from the namespace. Any 
+     * attributes associated with the name are also removed. Intermediate 
+     * contexts are not destroyed.
+     * <p>
+     * This method is idempotent. It succeeds even if the terminal atomic 
+     * name is not bound in the target context, but throws 
+     * NameNotFoundException if any of the intermediate contexts do not exist. 
+     * 
+     * In a federated naming system, a context from one naming system may be 
+     * bound to a name in another. One can subsequently look up and perform 
+     * operations on the foreign context using a composite name. However, an 
+     * attempt destroy the context using this composite name will fail with 
+     * NotContextException, because the foreign context is not a "subcontext" 
+     * of the context in which it is bound. Instead, use unbind() to remove 
+     * the binding of the foreign context. Destroying the foreign context 
+     * requires that the destroySubcontext() be performed on a context from 
+     * the foreign context's "native" naming system.
+     * 
+     * @param name the name of the context to be destroyed; may not be empty
+     * @exception NameNotFoundException if an intermediate context does not 
+     * exist
+     * @exception NotContextException if the name is bound but does not name 
+     * a context, or does not name a context of the appropriate type
+     */
+    public void destroySubcontext(String name)
+        throws NamingException {
+        unbind(name);
+    }
+
+
+    /**
+     * Retrieves the named object, following links except for the terminal 
+     * atomic component of the name. If the object bound to name is not a 
+     * link, returns the object itself.
+     * 
+     * @param name the name of the object to look up
+     * @return the object bound to name, not following the terminal link 
+     * (if any).
+     * @exception NamingException if a naming exception is encountered
+     */
+    public Object lookupLink(String name)
+        throws NamingException {
+        // Note : Links are not supported
+        return lookup(name);
+    }
+
+
+    /**
+     * Retrieves the full name of this context within its own namespace.
+     * <p>
+     * Many naming services have a notion of a "full name" for objects in 
+     * their respective namespaces. For example, an LDAP entry has a 
+     * distinguished name, and a DNS record has a fully qualified name. This 
+     * method allows the client application to retrieve this name. The string 
+     * returned by this method is not a JNDI composite name and should not be 
+     * passed directly to context methods. In naming systems for which the 
+     * notion of full name does not make sense, 
+     * OperationNotSupportedException is thrown.
+     * 
+     * @return this context's name in its own namespace; never null
+     * @exception OperationNotSupportedException if the naming system does 
+     * not have the notion of a full name
+     * @exception NamingException if a naming exception is encountered
+     */
+    public String getNameInNamespace()
+        throws NamingException {
+        return docBase;
+    }
+
+
+    // ----------------------------------------------------- DirContext Methods
+
+
+    /**
+     * Retrieves selected attributes associated with a named object. 
+     * See the class description regarding attribute models, attribute type 
+     * names, and operational attributes.
+     * 
+     * @return the requested attributes; never null
+     * @param name the name of the object from which to retrieve attributes
+     * @param attrIds the identifiers of the attributes to retrieve. null 
+     * indicates that all attributes should be retrieved; an empty array 
+     * indicates that none should be retrieved
+     * @exception NamingException if a naming exception is encountered
+     */
+    public Attributes getAttributes(String name, String[] attrIds)
+        throws NamingException {
+
+        // Building attribute list
+        File file = file(name);
+
+        if (file == null)
+            throw new NamingException
+                (sm.getString("resources.notFound", name));
+
+        return new FileResourceAttributes(file);
+
+    }
+
+
+    /**
+     * Modifies the attributes associated with a named object. The order of 
+     * the modifications is not specified. Where possible, the modifications 
+     * are performed atomically.
+     * 
+     * @param name the name of the object whose attributes will be updated
+     * @param mod_op the modification operation, one of: ADD_ATTRIBUTE, 
+     * REPLACE_ATTRIBUTE, REMOVE_ATTRIBUTE
+     * @param attrs the attributes to be used for the modification; may not 
+     * be null
+     * @exception AttributeModificationException if the modification cannot be
+     * completed successfully
+     * @exception NamingException if a naming exception is encountered
+     */
+    public void modifyAttributes(String name, int mod_op, Attributes attrs)
+        throws NamingException {
+        
+    }
+
+
+    /**
+     * Modifies the attributes associated with a named object using an an 
+     * ordered list of modifications. The modifications are performed in the 
+     * order specified. Each modification specifies a modification operation 
+     * code and an attribute on which to operate. Where possible, the 
+     * modifications are performed atomically.
+     * 
+     * @param name the name of the object whose attributes will be updated
+     * @param mods an ordered sequence of modifications to be performed; may 
+     * not be null
+     * @exception AttributeModificationException if the modification cannot be
+     * completed successfully
+     * @exception NamingException if a naming exception is encountered
+     */
+    public void modifyAttributes(String name, ModificationItem[] mods)
+        throws NamingException {
+        
+    }
+
+
+    /**
+     * Binds a name to an object, along with associated attributes. If attrs 
+     * is null, the resulting binding will have the attributes associated 
+     * with obj if obj is a DirContext, and no attributes otherwise. If attrs 
+     * is non-null, the resulting binding will have attrs as its attributes; 
+     * any attributes associated with obj are ignored.
+     * 
+     * @param name the name to bind; may not be empty
+     * @param obj the object to bind; possibly null
+     * @param attrs the attributes to associate with the binding
+     * @exception NameAlreadyBoundException if name is already bound
+     * @exception InvalidAttributesException if some "mandatory" attributes 
+     * of the binding are not supplied
+     * @exception NamingException if a naming exception is encountered
+     */
+    public void bind(String name, Object obj, Attributes attrs)
+        throws NamingException {
+        
+        // Note: No custom attributes allowed
+        
+        File file = new File(base, name);
+        if (file.exists())
+            throw new NameAlreadyBoundException
+                (sm.getString("resources.alreadyBound", name));
+        
+        rebind(name, obj, attrs);
+        
+    }
+
+
+    /**
+     * Binds a name to an object, along with associated attributes, 
+     * overwriting any existing binding. If attrs is null and obj is a 
+     * DirContext, the attributes from obj are used. If attrs is null and obj 
+     * is not a DirContext, any existing attributes associated with the object
+     * already bound in the directory remain unchanged. If attrs is non-null, 
+     * any existing attributes associated with the object already bound in 
+     * the directory are removed and attrs is associated with the named 
+     * object. If obj is a DirContext and attrs is non-null, the attributes 
+     * of obj are ignored.
+     * 
+     * @param name the name to bind; may not be empty
+     * @param obj the object to bind; possibly null
+     * @param attrs the attributes to associate with the binding
+     * @exception InvalidAttributesException if some "mandatory" attributes 
+     * of the binding are not supplied
+     * @exception NamingException if a naming exception is encountered
+     */
+    public void rebind(String name, Object obj, Attributes attrs)
+        throws NamingException {
+        
+        // Note: No custom attributes allowed
+        // Check obj type
+        
+        File file = new File(base, name);
+        
+        InputStream is = null;
+        if (obj instanceof Resource) {
+            try {
+                is = ((Resource) obj).streamContent();
+            } catch (IOException e) {
+            }
+        } else if (obj instanceof InputStream) {
+            is = (InputStream) obj;
+        } else if (obj instanceof DirContext) {
+            if (file.exists()) {
+                if (!file.delete())
+                    throw new NamingException
+                        (sm.getString("resources.bindFailed", name));
+            }
+            if (!file.mkdir())
+                throw new NamingException
+                    (sm.getString("resources.bindFailed", name));
+        }
+        if (is == null)
+            throw new NamingException
+                (sm.getString("resources.bindFailed", name));
+        
+        // Open os
+        
+        try {
+            FileOutputStream os = null;
+            byte buffer[] = new byte[BUFFER_SIZE];
+            int len = -1;
+            try {
+                os = new FileOutputStream(file);
+                while (true) {
+                    len = is.read(buffer);
+                    if (len == -1)
+                        break;
+                    os.write(buffer, 0, len);
+                }
+            } finally {
+                if (os != null)
+                    os.close();
+                is.close();
+            }
+        } catch (IOException e) {
+            throw new NamingException
+                (sm.getString("resources.bindFailed", e));
+        }
+        
+    }
+
+
+    /**
+     * Creates and binds a new context, along with associated attributes. 
+     * This method creates a new subcontext with the given name, binds it in 
+     * the target context (that named by all but terminal atomic component of 
+     * the name), and associates the supplied attributes with the newly 
+     * created object. All intermediate and target contexts must already 
+     * exist. If attrs is null, this method is equivalent to 
+     * Context.createSubcontext().
+     * 
+     * @param name the name of the context to create; may not be empty
+     * @param attrs the attributes to associate with the newly created context
+     * @return the newly created context
+     * @exception NameAlreadyBoundException if the name is already bound
+     * @exception InvalidAttributesException if attrs does not contain all 
+     * the mandatory attributes required for creation
+     * @exception NamingException if a naming exception is encountered
+     */
+    public DirContext createSubcontext(String name, Attributes attrs)
+        throws NamingException {
+        
+        File file = new File(base, name);
+        if (file.exists())
+            throw new NameAlreadyBoundException
+                (sm.getString("resources.alreadyBound", name));
+        if (!file.mkdir())
+            throw new NamingException
+                (sm.getString("resources.bindFailed", name));
+        return (DirContext) lookup(name);
+        
+    }
+
+
+    /**
+     * Retrieves the schema associated with the named object. The schema 
+     * describes rules regarding the structure of the namespace and the 
+     * attributes stored within it. The schema specifies what types of 
+     * objects can be added to the directory and where they can be added; 
+     * what mandatory and optional attributes an object can have. The range 
+     * of support for schemas is directory-specific.
+     * 
+     * @param name the name of the object whose schema is to be retrieved
+     * @return the schema associated with the context; never null
+     * @exception OperationNotSupportedException if schema not supported
+     * @exception NamingException if a naming exception is encountered
+     */
+    public DirContext getSchema(String name)
+        throws NamingException {
+        throw new OperationNotSupportedException();
+    }
+
+
+    /**
+     * Retrieves a context containing the schema objects of the named 
+     * object's class definitions.
+     * 
+     * @param name the name of the object whose object class definition is to 
+     * be retrieved
+     * @return the DirContext containing the named object's class 
+     * definitions; never null
+     * @exception OperationNotSupportedException if schema not supported
+     * @exception NamingException if a naming exception is encountered
+     */
+    public DirContext getSchemaClassDefinition(String name)
+        throws NamingException {
+        throw new OperationNotSupportedException();
+    }
+
+
+    /**
+     * Searches in a single context for objects that contain a specified set 
+     * of attributes, and retrieves selected attributes. The search is 
+     * performed using the default SearchControls settings.
+     * 
+     * @param name the name of the context to search
+     * @param matchingAttributes the attributes to search for. If empty or 
+     * null, all objects in the target context are returned.
+     * @param attributesToReturn the attributes to return. null indicates 
+     * that all attributes are to be returned; an empty array indicates that 
+     * none are to be returned.
+     * @return a non-null enumeration of SearchResult objects. Each 
+     * SearchResult contains the attributes identified by attributesToReturn 
+     * and the name of the corresponding object, named relative to the 
+     * context named by name.
+     * @exception NamingException if a naming exception is encountered
+     */
+    public NamingEnumeration search(String name, Attributes matchingAttributes,
+                                    String[] attributesToReturn)
+        throws NamingException {
+        return null;
+    }
+
+
+    /**
+     * Searches in a single context for objects that contain a specified set 
+     * of attributes. This method returns all the attributes of such objects. 
+     * It is equivalent to supplying null as the atributesToReturn parameter 
+     * to the method search(Name, Attributes, String[]).
+     * 
+     * @param name the name of the context to search
+     * @param matchingAttributes the attributes to search for. If empty or 
+     * null, all objects in the target context are returned.
+     * @return a non-null enumeration of SearchResult objects. Each 
+     * SearchResult contains the attributes identified by attributesToReturn 
+     * and the name of the corresponding object, named relative to the 
+     * context named by name.
+     * @exception NamingException if a naming exception is encountered
+     */
+    public NamingEnumeration search(String name, Attributes matchingAttributes)
+        throws NamingException {
+        return null;
+    }
+
+
+    /**
+     * Searches in the named context or object for entries that satisfy the 
+     * given search filter. Performs the search as specified by the search 
+     * controls.
+     * 
+     * @param name the name of the context or object to search
+     * @param filter the filter expression to use for the search; may not be 
+     * null
+     * @param cons the search controls that control the search. If null, 
+     * the default search controls are used (equivalent to 
+     * (new SearchControls())).
+     * @return an enumeration of SearchResults of the objects that satisfy 
+     * the filter; never null
+     * @exception InvalidSearchFilterException if the search filter specified 
+     * is not supported or understood by the underlying directory
+     * @exception InvalidSearchControlsException if the search controls 
+     * contain invalid settings
+     * @exception NamingException if a naming exception is encountered
+     */
+    public NamingEnumeration search(String name, String filter, 
+                                    SearchControls cons)
+        throws NamingException {
+        return null;
+    }
+
+
+    /**
+     * Searches in the named context or object for entries that satisfy the 
+     * given search filter. Performs the search as specified by the search 
+     * controls.
+     * 
+     * @param name the name of the context or object to search
+     * @param filterExpr the filter expression to use for the search. 
+     * The expression may contain variables of the form "{i}" where i is a 
+     * nonnegative integer. May not be null.
+     * @param filterArgs the array of arguments to substitute for the 
+     * variables in filterExpr. The value of filterArgs[i] will replace each 
+     * occurrence of "{i}". If null, equivalent to an empty array.
+     * @param cons the search controls that control the search. If null, the 
+     * default search controls are used (equivalent to (new SearchControls())).
+     * @return an enumeration of SearchResults of the objects that satisy the 
+     * filter; never null
+     * @exception ArrayIndexOutOfBoundsException if filterExpr contains {i} 
+     * expressions where i is outside the bounds of the array filterArgs
+     * @exception InvalidSearchControlsException if cons contains invalid 
+     * settings
+     * @exception InvalidSearchFilterException if filterExpr with filterArgs 
+     * represents an invalid search filter
+     * @exception NamingException if a naming exception is encountered
+     */
+    public NamingEnumeration search(String name, String filterExpr, 
+                                    Object[] filterArgs, SearchControls cons)
+        throws NamingException {
+        return null;
+    }
+
+
+    // ------------------------------------------------------ Protected Methods
+
+
+    /**
+     * Return a context-relative path, beginning with a "/", that represents
+     * the canonical version of the specified path after ".." and "." elements
+     * are resolved out.  If the specified path attempts to go outside the
+     * boundaries of the current context (i.e. too many ".." path elements
+     * are present), return <code>null</code> instead.
+     *
+     * @param path Path to be normalized
+     */
+    protected String normalize(String path) {
+
+	String normalized = path;
+
+	// Normalize the slashes and add leading slash if necessary
+	if (normalized.indexOf('\\') >= 0)
+	    normalized = normalized.replace('\\', '/');
+	if (!normalized.startsWith("/"))
+	    normalized = "/" + normalized;
+
+	// Resolve occurrences of "//" in the normalized path
+	while (true) {
+	    int index = normalized.indexOf("//");
+	    if (index < 0)
+		break;
+	    normalized = normalized.substring(0, index) +
+		normalized.substring(index + 1);
+	}
+
+	// Resolve occurrences of "/./" in the normalized path
+	while (true) {
+	    int index = normalized.indexOf("/./");
+	    if (index < 0)
+		break;
+	    normalized = normalized.substring(0, index) +
+		normalized.substring(index + 2);
+	}
+
+	// Resolve occurrences of "/../" in the normalized path
+	while (true) {
+	    int index = normalized.indexOf("/../");
+	    if (index < 0)
+		break;
+	    if (index == 0)
+		return (null);	// Trying to go outside our context
+	    int index2 = normalized.lastIndexOf('/', index - 1);
+	    normalized = normalized.substring(0, index2) +
+		normalized.substring(index + 3);
+	}
+
+	// Return the normalized path that we have completed
+	return (normalized);
+
+    }
+
+
+    /**
+     * Return a File object representing the specified normalized
+     * context-relative path if it exists and is readable.  Otherwise,
+     * return <code>null</code>.
+     *
+     * @param name Normalized context-relative path (with leading '/')
+     */
+    protected File file(String name) {
+
+        File file = new File(base, name);
+        if (file.exists() && file.canRead()) {
+
+            // Check that this file belongs to our root path
+            String canPath = null;
+            try {
+                canPath = file.getCanonicalPath();
+            } catch (IOException e) {
+            }
+            if (canPath == null)
+                return null;
+
+            // Check to see if going outside of the web application root
+            if ((!allowLinking) && (!canPath.startsWith(absoluteBase))) {
+                return null;
+            }
+
+            // Case sensitivity check
+            if (!allowLinking && caseSensitive) {
+                String fileAbsPath = file.getAbsolutePath();
+                if (fileAbsPath.endsWith("."))
+                    fileAbsPath = fileAbsPath + "/";
+                String absPath = normalize(fileAbsPath);
+                if (canPath != null)
+                    canPath = normalize(canPath);
+                if ((absoluteBase.length() < absPath.length()) 
+                    && (absoluteBase.length() < canPath.length())) {
+                    absPath = absPath.substring(absoluteBase.length() + 1);
+                    if ((canPath == null) || (absPath == null))
+                        return null;
+                    if (absPath.equals(""))
+                        absPath = "/";
+                    canPath = canPath.substring(absoluteBase.length() + 1);
+                    if (canPath.equals(""))
+                        canPath = "/";
+                    if (!canPath.equals(absPath))
+                        return null;
+                }
+            }
+
+        } else {
+            return null;
+        }
+        return file;
+
+    }
+
+
+    /**
+     * List the resources which are members of a collection.
+     * 
+     * @param file Collection
+     * @return Vector containg NamingEntry objects
+     */
+    protected Vector list(File file) {
+
+        Vector entries = new Vector();
+        if (!file.isDirectory())
+            return entries;
+        String[] names = file.list();
+        Arrays.sort(names);             // Sort alphabetically
+        if (names == null)
+            return entries;
+        NamingEntry entry = null;
+
+        for (int i = 0; i < names.length; i++) {
+
+            File currentFile = new File(file, names[i]);
+            Object object = null;
+            if (currentFile.isDirectory()) {
+                FileDirContext tempContext = new FileDirContext(env);
+                tempContext.setDocBase(file.getPath());
+                object = tempContext;
+            } else {
+                object = new FileResource(currentFile);
+            }
+            entry = new NamingEntry(names[i], object, NamingEntry.ENTRY);
+            entries.addElement(entry);
+
+        }
+
+        return entries;
+
+    }
+
+
+    // ----------------------------------------------- FileResource Inner Class
+
+
+    /**
+     * This specialized resource implementation avoids opening the IputStream
+     * to the file right away (which would put a lock on the file).
+     */
+    protected class FileResource extends Resource {
+        
+        
+        // -------------------------------------------------------- Constructor
+
+
+        public FileResource(File file) {
+            this.file = file;
+        }
+        
+        
+        // --------------------------------------------------- Member Variables
+        
+        
+        /**
+         * Associated file object.
+         */
+        protected File file;
+        
+        
+        /**
+         * File length.
+         */
+        protected long length = -1L;
+        
+        
+        // --------------------------------------------------- Resource Methods
+        
+        
+        /**
+         * Content accessor.
+         * 
+         * @return InputStream
+         */
+        public InputStream streamContent()
+            throws IOException {
+            if (binaryContent == null) {
+                inputStream = new FileInputStream(file);
+            }
+            return super.streamContent();
+        }
+        
+        
+    }
+
+
+    // ------------------------------------- FileResourceAttributes Inner Class
+
+
+    /**
+     * This specialized resource attribute implementation does some lazy 
+     * reading (to speed up simple checks, like checking the last modified 
+     * date).
+     */
+    protected class FileResourceAttributes extends ResourceAttributes {
+
+
+        // -------------------------------------------------------- Constructor
+
+
+        public FileResourceAttributes(File file) {
+            this.file = file;
+        }
+        
+        // --------------------------------------------------- Member Variables
+        
+        
+        protected File file;
+        
+        
+        protected boolean accessed = false;
+        
+        
+        // ----------------------------------------- ResourceAttributes Methods
+        
+        
+        /**
+         * Is collection.
+         */
+        public boolean isCollection() {
+            if (!accessed) {
+                collection = file.isDirectory();
+                accessed = true;
+            }
+            return super.isCollection();
+        }
+        
+        
+        /**
+         * Get content length.
+         * 
+         * @return content length value
+         */
+        public long getContentLength() {
+            if (contentLength != -1L)
+                return contentLength;
+            contentLength = file.length();
+            return contentLength;
+        }
+        
+        
+        /**
+         * Get creation time.
+         * 
+         * @return creation time value
+         */
+        public long getCreation() {
+            if (creation != -1L)
+                return creation;
+            creation = file.lastModified();
+            return creation;
+        }
+        
+        
+        /**
+         * Get creation date.
+         * 
+         * @return Creation date value
+         */
+        public Date getCreationDate() {
+            if (creation == -1L) {
+                creation = file.lastModified();
+            }
+            return super.getCreationDate();
+        }
+        
+        
+        /**
+         * Get last modified time.
+         * 
+         * @return lastModified time value
+         */
+        public long getLastModified() {
+            if (lastModified != -1L)
+                return lastModified;
+            lastModified = file.lastModified();
+            return lastModified;
+        }
+        
+        
+        /**
+         * Get lastModified date.
+         * 
+         * @return LastModified date value
+         */
+        public Date getLastModifiedDate() {
+            if (lastModified == -1L) {
+                lastModified = file.lastModified();
+            }
+            return super.getLastModifiedDate();
+        }
+        
+        
+        /**
+         * Get name.
+         * 
+         * @return Name value
+         */
+        public String getName() {
+            if (name == null)
+                name = file.getName();
+            return name;
+        }
+        
+        
+        /**
+         * Get resource type.
+         * 
+         * @return String resource type
+         */
+        public String getResourceType() {
+            if (!accessed) {
+                collection = file.isDirectory();
+                accessed = true;
+            }
+            return super.getResourceType();
+        }
+        
+        
+    }
+
+
+}
+

Added: incubator/directory/naming/trunk/core/src/java/org/apache/directory/naming/resources/ImmutableNameNotFoundException.java
==============================================================================
--- (empty file)
+++ incubator/directory/naming/trunk/core/src/java/org/apache/directory/naming/resources/ImmutableNameNotFoundException.java	Sun Dec  7 13:00:05 2003
@@ -0,0 +1,86 @@
+/*
+ * $Header: /home/cvs/jakarta-commons-sandbox/naming/core/src/java/org/apache/commons/naming/resources/ImmutableNameNotFoundException.java,v 1.2 2003/10/13 08:15:54 rdonkin Exp $
+ * $Revision: 1.2 $
+ * $Date: 2003/10/13 08:15:54 $
+ *
+ * ====================================================================
+ *
+ * The Apache Software License, Version 1.1
+ *
+ * Copyright (c) 1999 The Apache Software Foundation.  All rights 
+ * reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. The end-user documentation included with the redistribution, if
+ *    any, must include the following acknowledgement:
+ *       "This product includes software developed by the 
+ *        Apache Software Foundation (http://www.apache.org/)."
+ *    Alternately, this acknowledgement may appear in the software itself,
+ *    if and wherever such third-party acknowledgements normally appear.
+ *
+ * 4. The names "The Jakarta Project", "Tomcat", and "Apache Software
+ *    Foundation" must not be used to endorse or promote products derived
+ *    from this software without prior written permission. For written 
+ *    permission, please contact apache@apache.org.
+ *
+ * 5. Products derived from this software may not be called "Apache"
+ *    nor may "Apache" appear in their names without prior written
+ *    permission of the Apache Software Foundation.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation.  For more
+ * information on the Apache Software Foundation, please see
+ * <http://www.apache.org/>.
+ *
+ * [Additional notices, if required by prior licensing conditions]
+ *
+ */ 
+
+package org.apache.directory.naming.resources;
+
+import javax.naming.Name;
+import javax.naming.NameNotFoundException;
+
+/**
+ * Immutable exception to avoid useless object creation by the proxy context.
+ * This should be used only by the proxy context. Actual contexts should return
+ * properly populated exceptions.
+ * 
+ * @author <a href="mailto:remm@apache.org">Remy Maucherat</a>
+ * @version $Revision: 1.2 $
+ */
+public class ImmutableNameNotFoundException
+    extends NameNotFoundException {
+
+    public void appendRemainingComponent(String name) {}
+    public void appendRemainingName(Name name) {}
+    public void setRemainingName(Name name) {}
+    public void setResolverName(Name name) {}
+    public void setRootCause(Throwable e) {}
+
+}

Added: incubator/directory/naming/trunk/core/src/java/org/apache/directory/naming/resources/LocalStrings.properties
==============================================================================
--- (empty file)
+++ incubator/directory/naming/trunk/core/src/java/org/apache/directory/naming/resources/LocalStrings.properties	Sun Dec  7 13:00:05 2003
@@ -0,0 +1,20 @@
+fileResources.base=Document base {0} does not exist or is not a readable directory
+warResources.notWar=Doc base must point to a WAR file
+warResources.invalidWar=Invalid or unreadable WAR file : {0}
+jarResources.syntax=Document base {0} must start with 'jar:' and end with '!/'
+resources.alreadyStarted=Resources has already been started
+resources.connect=Cannot connect to document base {0}
+resources.input=Cannot create input stream for resource {0}
+resources.notStarted=Resources has not yet been started
+resources.null=Document base cannot be null
+resources.notFound=Resource {0} not found
+resources.path=Context relative path {0} must start with '/'
+resources.alreadyBound=Name {0} is already bound in this Context
+resources.bindFailed=Bind failed: {0}
+resources.unbindFailed=Unbind failed: {0}
+standardResources.alreadyStarted=Resources has already been started
+standardResources.directory=File base {0} is not a directory
+standardResources.exists=File base {0} does not exist
+standardResources.notStarted=Resources has not yet been started
+standardResources.null=Document base cannot be null
+standardResources.slash=Document base {0} must not end with a slash

Added: incubator/directory/naming/trunk/core/src/java/org/apache/directory/naming/resources/LocalStrings_fr.properties
==============================================================================
--- (empty file)
+++ incubator/directory/naming/trunk/core/src/java/org/apache/directory/naming/resources/LocalStrings_fr.properties	Sun Dec  7 13:00:05 2003
@@ -0,0 +1,20 @@
+fileResources.base=Le "document base" {0} n''existe pas ou n''est pas un r�pertoire lisible
+warResources.notWar=Doc base doit point� vers un fichier WAR
+warResources.invalidWar=Fichier WAR invalide ou illisible  : {0}
+jarResources.syntax=Le document base {0} doit commencer par 'jar:' et finir avec '!/'
+resources.alreadyStarted=Les Ressources ont d�j� �t� d�marr�es
+resources.connect=Impossible de se connecter au document base {0}
+resources.input=Impossible de cr�er le flux d''entr�e (input stream) pour la ressource {0}
+resources.notStarted=Les ressources n''ont pas encore �t� d�marr�es
+resources.null=Le "document base" ne peut �tre nul
+resources.notFound=La ressource {0} est introuvable
+resources.path=Le chemin relatif de context {0} doit commencer par '/'
+resources.alreadyBound=Le nom {0} a d�j� �t� r�f�renc� par ce contexte
+resources.bindFailed=Le liage a �chou�: {0}
+resources.unbindFailed=Le d�liage a �chou�: {0}
+standardResources.alreadyStarted=Les ressources ont d�ja �t� d�marr�es
+standardResources.directory=Le "file base" {0} n''est pas un r�pertoire
+standardResources.exists=Le "file base" {0} n''existe pas
+standardResources.notStarted=Les ressources n''ont pas encore �t� d�marr�es
+standardResources.null=Le document base ne peut �tre nul
+standardResources.slash=Le document base {0} ne doit pas se terminer par un '/'

Added: incubator/directory/naming/trunk/core/src/java/org/apache/directory/naming/resources/LocalStrings_ja.properties
==============================================================================
--- (empty file)
+++ incubator/directory/naming/trunk/core/src/java/org/apache/directory/naming/resources/LocalStrings_ja.properties	Sun Dec  7 13:00:05 2003
@@ -0,0 +1,20 @@
+fileResources.base=\u30c9\u30ad\u30e5\u30e1\u30f3\u30c8\u30d9\u30fc\u30b9 {0} \u304c\u5b58\u5728\u3057\u306a\u3044\u3001\u307e\u305f\u306f\u8aad\u3081\u306a\u3044\u30c7\u30a3\u30ec\u30af\u30c8\u30ea\u3067\u3059
+warResources.notWar=\u30c9\u30ad\u30e5\u30e1\u30f3\u30c8\u30d9\u30fc\u30b9\u306fWAR\u30d5\u30a1\u30a4\u30eb\u3092\u793a\u3055\u306a\u3051\u308c\u3070\u3044\u3051\u307e\u305b\u3093
+warResources.invalidWar=\u7121\u52b9\u307e\u305f\u306f\u8aad\u3081\u306a\u3044WAR\u30d5\u30a1\u30a4\u30eb\u3067\u3059 : {0}
+jarResources.syntax=\u30c9\u30ad\u30e5\u30e1\u30f3\u30c8\u30d9\u30fc\u30b9 {0} \u306f'jar:'\u3067\u59cb\u307e\u308a\u3001'!/'\u3067\u7d42\u3089\u306a\u3051\u308c\u3070\u3044\u3051\u307e\u305b\u3093
+resources.alreadyStarted=\u30ea\u30bd\u30fc\u30b9\u306f\u3059\u3067\u306b\u8d77\u52d5\u3055\u308c\u3066\u3044\u307e\u3059
+resources.connect=\u30c9\u30ad\u30e5\u30e1\u30f3\u30c8\u30d9\u30fc\u30b9 {0} \u306b\u63a5\u7d9a\u3067\u304d\u307e\u305b\u3093
+resources.input=\u30ea\u30bd\u30fc\u30b9 {0} \u306b\u5165\u529b\u30b9\u30c8\u30ea\u30fc\u30e0\u3092\u4f5c\u6210\u3067\u304d\u307e\u305b\u3093
+resources.notStarted=\u30ea\u30bd\u30fc\u30b9\u306f\u307e\u3060\u8d77\u52d5\u3055\u308c\u3066\u3044\u307e\u305b\u3093
+resources.null=\u30c9\u30ad\u30e5\u30e1\u30f3\u30c8\u30d9\u30fc\u30b9\u306fnull\u3067\u3042\u3063\u3066\u306f\u3044\u3051\u307e\u305b\u3093
+resources.notFound=\u30ea\u30bd\u30fc\u30b9 {0} \u304c\u898b\u3064\u304b\u308a\u307e\u305b\u3093
+resources.path=\u30b3\u30f3\u30c6\u30ad\u30b9\u30c8\u76f8\u5bfe\u30d1\u30b9 {0} \u306f'/'\u3067\u59cb\u307e\u3089\u306a\u3051\u308c\u3070\u3044\u3051\u307e\u305b\u3093
+resources.alreadyBound=\u540d\u524d {0} \u306f\u3059\u3067\u306b\u3053\u306e\u30b3\u30f3\u30c6\u30ad\u30b9\u30c8\u306b\u30d0\u30a4\u30f3\u30c9\u3055\u308c\u3066\u3044\u307e\u3059
+resources.bindFailed=\u30d0\u30a4\u30f3\u30c9\u304c\u5931\u6557\u3057\u307e\u3057\u305f: {0}
+resources.unbindFailed=\u30a2\u30f3\u30d0\u30a4\u30f3\u30c9\u304c\u5931\u6557\u3057\u307e\u3057\u305f: {0}
+standardResources.alreadyStarted=\u30ea\u30bd\u30fc\u30b9\u306f\u3059\u3067\u306b\u8d77\u52d5\u3055\u308c\u3066\u3044\u307e\u3059
+standardResources.directory=\u30d5\u30a1\u30a4\u30eb\u30d9\u30fc\u30b9 {0} \u306f\u30c7\u30a3\u30ec\u30af\u30c8\u30ea\u3067\u306f\u3042\u308a\u307e\u305b\u3093
+standardResources.exists=\u30d5\u30a1\u30a4\u30eb\u30d9\u30fc\u30b9 {0} \u306f\u5b58\u5728\u3057\u307e\u305b\u3093
+standardResources.notStarted=\u30ea\u30bd\u30fc\u30b9\u304c\u307e\u3060\u8d77\u52d5\u3055\u308c\u3066\u3044\u307e\u305b\u3093
+standardResources.null=\u30c9\u30ad\u30e5\u30e1\u30f3\u30c8\u30d9\u30fc\u30b9\u306fnull\u3067\u3042\u3063\u3066\u306f\u3044\u3051\u307e\u305b\u3093
+standardResources.slash=\u30c9\u30ad\u30e5\u30e1\u30f3\u30c8\u30d9\u30fc\u30b9 {0} \u306f\u30b9\u30e9\u30c3\u30b7\u30e5\u3067\u7d42\u3063\u3066\u306f\u3044\u3051\u307e\u305b\u3093

Added: incubator/directory/naming/trunk/core/src/java/org/apache/directory/naming/resources/ProxyDirContext.java
==============================================================================
--- (empty file)
+++ incubator/directory/naming/trunk/core/src/java/org/apache/directory/naming/resources/ProxyDirContext.java	Sun Dec  7 13:00:05 2003
@@ -0,0 +1,1617 @@
+/*
+ * $Header: /home/cvs/jakarta-commons-sandbox/naming/core/src/java/org/apache/commons/naming/resources/ProxyDirContext.java,v 1.3 2003/11/30 05:22:15 psteitz Exp $
+ * $Revision: 1.3 $
+ * $Date: 2003/11/30 05:22:15 $
+ *
+ * ====================================================================
+ *
+ * The Apache Software License, Version 1.1
+ *
+ * Copyright (c) 1999 The Apache Software Foundation.  All rights 
+ * reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. The end-user documentation included with the redistribution, if
+ *    any, must include the following acknowledgement:
+ *       "This product includes software developed by the 
+ *        Apache Software Foundation (http://www.apache.org/)."
+ *    Alternately, this acknowledgement may appear in the software itself,
+ *    if and wherever such third-party acknowledgements normally appear.
+ *
+ * 4. The names "The Jakarta Project", "Tomcat", and "Apache Software
+ *    Foundation" must not be used to endorse or promote products derived
+ *    from this software without prior written permission. For written 
+ *    permission, please contact apache@apache.org.
+ *
+ * 5. Products derived from this software may not be called "Apache"
+ *    nor may "Apache" appear in their names without prior written
+ *    permission of the Apache Software Foundation.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation.  For more
+ * information on the Apache Software Foundation, please see
+ * <http://www.apache.org/>.
+ *
+ * [Additional notices, if required by prior licensing conditions]
+ *
+ */ 
+
+
+package org.apache.directory.naming.resources;
+
+import java.util.Collections;
+import java.util.Date;
+import java.util.Hashtable;
+import java.util.Map;
+import java.io.InputStream;
+import java.io.IOException;
+import java.io.ByteArrayInputStream;
+
+import javax.naming.Context;
+import javax.naming.Name;
+import javax.naming.NameParser;
+import javax.naming.NameNotFoundException;
+import javax.naming.NamingEnumeration;
+import javax.naming.NamingException;
+import javax.naming.directory.DirContext;
+import javax.naming.directory.Attributes;
+import javax.naming.directory.Attribute;
+import javax.naming.directory.ModificationItem;
+import javax.naming.directory.SearchControls;
+
+import org.apache.directory.naming.StringManager;
+
+import org.apache.commons.collections.LRUMap;
+
+/**
+ * Proxy Directory Context implementation.
+ *
+ * @author Remy Maucherat
+ * @version $Revision: 1.3 $ $Date: 2003/11/30 05:22:15 $
+ */
+
+public class ProxyDirContext implements DirContext {
+
+
+    // -------------------------------------------------------------- Constants
+
+
+    public static final String CONTEXT = "context";
+    public static final String HOST = "host";
+
+
+    // ----------------------------------------------------------- Constructors
+
+
+    /**
+     * Builds a proxy directory context using the given environment.
+     */
+    public ProxyDirContext(Hashtable env, DirContext dirContext) {
+        this.env = env;
+        this.dirContext = dirContext;
+        if (dirContext instanceof BaseDirContext) {
+            // Initialize parameters based on the associated dir context, like
+            // the caching policy.
+            if (((BaseDirContext) dirContext).isCached()) {
+                cache = Collections.synchronizedMap(new LRUMap(cacheSize));
+                cacheTTL = ((BaseDirContext) dirContext).getCacheTTL();
+                cacheObjectMaxSize = 
+                    ((BaseDirContext) dirContext).getCacheObjectMaxSize();
+            }
+        }
+        hostName = (String) env.get(HOST);
+        contextName = (String) env.get(CONTEXT);
+    }
+
+
+    /**
+     * Builds a clone of this proxy dir context, wrapping the given directory
+     * context, and sharing the same cache.
+     */
+    protected ProxyDirContext(ProxyDirContext proxyDirContext, 
+                              DirContext dirContext, String vPath) {
+        this.env = proxyDirContext.env;
+        this.dirContext = dirContext;
+        this.vPath = vPath;
+        this.cache = proxyDirContext.cache;
+        this.cacheSize = proxyDirContext.cacheSize;
+        this.cacheTTL = proxyDirContext.cacheTTL;
+        this.cacheObjectMaxSize = proxyDirContext.cacheObjectMaxSize;
+        this.hostName = proxyDirContext.hostName;
+        this.contextName = proxyDirContext.contextName;
+    }
+
+
+    // ----------------------------------------------------- Instance Variables
+
+
+    /**
+     * Environment.
+     */
+    protected Hashtable env;
+
+
+    /**
+     * The string manager for this package.
+     */
+    protected StringManager sm = StringManager.getManager(Constants.Package);
+
+
+    /**
+     * Associated DirContext.
+     */
+    protected DirContext dirContext;
+
+
+    /**
+     * Virtual path.
+     */
+    protected String vPath = null;
+
+
+    /**
+     * Host name.
+     */
+    protected String hostName;
+
+
+    /**
+     * Context name.
+     */
+    protected String contextName;
+
+
+    /**
+     * Cache.
+     * Path -> Cache entry.
+     */
+    protected Map cache = null;
+
+
+    /**
+     * Cache size
+     */
+    protected int cacheSize = 1000;
+
+
+    /**
+     * Cache TTL.
+     */
+    protected int cacheTTL = 5000; // 5s
+
+
+    /**
+     * Max size of resources which will have their content cached.
+     */
+    protected int cacheObjectMaxSize = 32768; // 32 KB
+
+
+    /**
+     * Immutable name not found exception.
+     */
+    protected NameNotFoundException notFoundException =
+        new ImmutableNameNotFoundException();
+
+
+    // --------------------------------------------------------- Public Methods
+
+
+    /**
+     * Return the actual directory context we are wrapping.
+     */
+    public DirContext getDirContext() {
+        return this.dirContext;
+    }
+
+
+    /**
+     * Return the document root for this component.
+     */
+    public String getDocBase() {
+        if (dirContext instanceof BaseDirContext)
+            return ((BaseDirContext) dirContext).getDocBase();
+        else
+            return "";
+    }
+
+
+    /**
+     * Return the host name.
+     */
+    public String getHostName() {
+        return this.hostName;
+    }
+
+
+    /**
+     * Return the context name.
+     */
+    public String getContextName() {
+        return this.contextName;
+    }
+
+
+    // -------------------------------------------------------- Context Methods
+
+
+    /**
+     * Retrieves the named object. If name is empty, returns a new instance 
+     * of this context (which represents the same naming context as this 
+     * context, but its environment may be modified independently and it may 
+     * be accessed concurrently).
+     * 
+     * @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(Name name)
+        throws NamingException {
+        CacheEntry entry = cacheLookup(name.toString());
+        if (entry != null) {
+            if (entry.resource != null) {
+                // Check content caching.
+                return entry.resource;
+            } else {
+                return entry.context;
+            }
+        }
+        Object object = dirContext.lookup(parseName(name));
+        if (object instanceof InputStream)
+            return new Resource((InputStream) object);
+        else
+            return object;
+    }
+
+
+    /**
+     * 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 {
+        CacheEntry entry = cacheLookup(name);
+        if (entry != null) {
+            if (entry.resource != null) {
+                return entry.resource;
+            } else {
+                return entry.context;
+            }
+        }
+        Object object = dirContext.lookup(parseName(name));
+        if (object instanceof InputStream) {
+            return new Resource((InputStream) object);
+        } else if (object instanceof DirContext) {
+            return object;
+        } else if (object instanceof Resource) {
+            return object;
+        } else {
+            return new Resource(new ByteArrayInputStream
+                (object.toString().getBytes()));
+        }
+    }
+
+
+    /**
+     * Binds a name to an object. All intermediate contexts and the target 
+     * context (that named by all but terminal atomic component of the name) 
+     * must already exist.
+     * 
+     * @param name the name to bind; may not be empty
+     * @param obj the object to bind; possibly null
+     * @exception NameAlreadyBoundException if name is already bound
+     * @exception InvalidAttributesException if object did not supply all 
+     * mandatory attributes
+     * @exception NamingException if a naming exception is encountered
+     */
+    public void bind(Name name, Object obj)
+        throws NamingException {
+        dirContext.bind(parseName(name), obj);
+        cacheUnload(name.toString());
+    }
+
+
+    /**
+     * Binds a name to an object.
+     * 
+     * @param name the name to bind; may not be empty
+     * @param obj the object to bind; possibly null
+     * @exception NameAlreadyBoundException if name is already bound
+     * @exception InvalidAttributesException if object did not supply all 
+     * mandatory attributes
+     * @exception NamingException if a naming exception is encountered
+     */
+    public void bind(String name, Object obj)
+        throws NamingException {
+        dirContext.bind(parseName(name), obj);
+        cacheUnload(name);
+    }
+
+
+    /**
+     * Binds a name to an object, overwriting any existing binding. All 
+     * intermediate contexts and the target context (that named by all but 
+     * terminal atomic component of the name) must already exist.
+     * <p>
+     * If the object is a DirContext, any existing attributes associated with 
+     * the name are replaced with those of the object. Otherwise, any 
+     * existing attributes associated with the name remain unchanged.
+     * 
+     * @param name the name to bind; may not be empty
+     * @param obj the object to bind; possibly null
+     * @exception InvalidAttributesException if object did not supply all 
+     * mandatory attributes
+     * @exception NamingException if a naming exception is encountered
+     */
+    public void rebind(Name name, Object obj)
+        throws NamingException {
+        dirContext.rebind(parseName(name), obj);
+        cacheUnload(name.toString());
+    }
+
+
+    /**
+     * Binds a name to an object, overwriting any existing binding.
+     * 
+     * @param name the name to bind; may not be empty
+     * @param obj the object to bind; possibly null
+     * @exception InvalidAttributesException if object did not supply all 
+     * mandatory attributes
+     * @exception NamingException if a naming exception is encountered
+     */
+    public void rebind(String name, Object obj)
+        throws NamingException {
+        dirContext.rebind(parseName(name), obj);
+        cacheUnload(name);
+    }
+
+
+    /**
+     * Unbinds the named object. Removes the terminal atomic name in name 
+     * from the target context--that named by all but the terminal atomic 
+     * part of name.
+     * <p>
+     * This method is idempotent. It succeeds even if the terminal atomic 
+     * name is not bound in the target context, but throws 
+     * NameNotFoundException if any of the intermediate contexts do not exist. 
+     * 
+     * @param name the name to bind; may not be empty
+     * @exception NameNotFoundException if an intermediate context does not 
+     * exist
+     * @exception NamingException if a naming exception is encountered
+     */
+    public void unbind(Name name)
+        throws NamingException {
+        dirContext.unbind(parseName(name));
+        cacheUnload(name.toString());
+    }
+
+
+    /**
+     * Unbinds the named object.
+     * 
+     * @param name the name to bind; may not be empty
+     * @exception NameNotFoundException if an intermediate context does not 
+     * exist
+     * @exception NamingException if a naming exception is encountered
+     */
+    public void unbind(String name)
+        throws NamingException {
+        dirContext.unbind(parseName(name));
+        cacheUnload(name);
+    }
+
+
+    /**
+     * Binds a new name to the object bound to an old name, and unbinds the 
+     * old name. Both names are relative to this context. Any attributes 
+     * associated with the old name become associated with the new name. 
+     * Intermediate contexts of the old name are not changed.
+     * 
+     * @param oldName the name of the existing binding; may not be empty
+     * @param newName the name of the new binding; may not be empty
+     * @exception NameAlreadyBoundException if newName is already bound
+     * @exception NamingException if a naming exception is encountered
+     */
+    public void rename(Name oldName, Name newName)
+        throws NamingException {
+        dirContext.rename(parseName(oldName), parseName(newName));
+        cacheUnload(oldName.toString());
+    }
+
+
+    /**
+     * Binds a new name to the object bound to an old name, and unbinds the 
+     * old name.
+     * 
+     * @param oldName the name of the existing binding; may not be empty
+     * @param newName the name of the new binding; may not be empty
+     * @exception NameAlreadyBoundException if newName is already bound
+     * @exception NamingException if a naming exception is encountered
+     */
+    public void rename(String oldName, String newName)
+        throws NamingException {
+        dirContext.rename(parseName(oldName), parseName(newName));
+        cacheUnload(oldName);
+    }
+
+
+    /**
+     * Enumerates the names bound in the named context, along with the class 
+     * names of objects bound to them. The contents of any subcontexts are 
+     * not included.
+     * <p>
+     * If a binding is added to or removed from this context, its effect on 
+     * an enumeration previously returned is undefined.
+     * 
+     * @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(Name name)
+        throws NamingException {
+        return dirContext.list(parseName(name));
+    }
+
+
+    /**
+     * 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 {
+        return dirContext.list(parseName(name));
+    }
+
+
+    /**
+     * Enumerates the names bound in the named context, along with the 
+     * objects bound to them. The contents of any subcontexts are not 
+     * included.
+     * <p>
+     * If a binding is added to or removed from this context, its effect on 
+     * an enumeration previously returned is undefined.
+     * 
+     * @param name the name of the context to list
+     * @return an enumeration of the bindings in this context. 
+     * Each element of the enumeration is of type Binding.
+     * @exception NamingException if a naming exception is encountered
+     */
+    public NamingEnumeration listBindings(Name name)
+        throws NamingException {
+        return dirContext.listBindings(parseName(name));
+    }
+
+
+    /**
+     * Enumerates the names bound in the named context, along with the 
+     * objects bound to them.
+     * 
+     * @param name the name of the context to list
+     * @return an enumeration of the bindings in this context. 
+     * Each element of the enumeration is of type Binding.
+     * @exception NamingException if a naming exception is encountered
+     */
+    public NamingEnumeration listBindings(String name)
+        throws NamingException {
+        return dirContext.listBindings(parseName(name));
+    }
+
+
+    /**
+     * Destroys the named context and removes it from the namespace. Any 
+     * attributes associated with the name are also removed. Intermediate 
+     * contexts are not destroyed.
+     * <p>
+     * This method is idempotent. It succeeds even if the terminal atomic 
+     * name is not bound in the target context, but throws 
+     * NameNotFoundException if any of the intermediate contexts do not exist. 
+     * 
+     * In a federated naming system, a context from one naming system may be 
+     * bound to a name in another. One can subsequently look up and perform 
+     * operations on the foreign context using a composite name. However, an 
+     * attempt destroy the context using this composite name will fail with 
+     * NotContextException, because the foreign context is not a "subcontext" 
+     * of the context in which it is bound. Instead, use unbind() to remove 
+     * the binding of the foreign context. Destroying the foreign context 
+     * requires that the destroySubcontext() be performed on a context from 
+     * the foreign context's "native" naming system.
+     * 
+     * @param name the name of the context to be destroyed; may not be empty
+     * @exception NameNotFoundException if an intermediate context does not 
+     * exist
+     * @exception NotContextException if the name is bound but does not name 
+     * a context, or does not name a context of the appropriate type
+     */
+    public void destroySubcontext(Name name)
+        throws NamingException {
+        dirContext.destroySubcontext(parseName(name));
+        cacheUnload(name.toString());
+    }
+
+
+    /**
+     * Destroys the named context and removes it from the namespace.
+     * 
+     * @param name the name of the context to be destroyed; may not be empty
+     * @exception NameNotFoundException if an intermediate context does not 
+     * exist
+     * @exception NotContextException if the name is bound but does not name 
+     * a context, or does not name a context of the appropriate type
+     */
+    public void destroySubcontext(String name)
+        throws NamingException {
+        dirContext.destroySubcontext(parseName(name));
+        cacheUnload(name);
+    }
+
+
+    /**
+     * Creates and binds a new context. Creates a new context with the given 
+     * name and binds it in the target context (that named by all but 
+     * terminal atomic component of the name). All intermediate contexts and 
+     * the target context must already exist.
+     * 
+     * @param name the name of the context to create; may not be empty
+     * @return the newly created context
+     * @exception NameAlreadyBoundException if name is already bound
+     * @exception InvalidAttributesException if creation of the subcontext 
+     * requires specification of mandatory attributes
+     * @exception NamingException if a naming exception is encountered
+     */
+    public Context createSubcontext(Name name)
+        throws NamingException {
+        Context context = dirContext.createSubcontext(parseName(name));
+        cacheUnload(name.toString());
+        return context;
+    }
+
+
+    /**
+     * Creates and binds a new context.
+     * 
+     * @param name the name of the context to create; may not be empty
+     * @return the newly created context
+     * @exception NameAlreadyBoundException if name is already bound
+     * @exception InvalidAttributesException if creation of the subcontext 
+     * requires specification of mandatory attributes
+     * @exception NamingException if a naming exception is encountered
+     */
+    public Context createSubcontext(String name)
+        throws NamingException {
+        Context context = dirContext.createSubcontext(parseName(name));
+        cacheUnload(name);
+        return context;
+    }
+
+
+    /**
+     * Retrieves the named object, following links except for the terminal 
+     * atomic component of the name. If the object bound to name is not a 
+     * link, returns the object itself.
+     * 
+     * @param name the name of the object to look up
+     * @return the object bound to name, not following the terminal link 
+     * (if any).
+     * @exception NamingException if a naming exception is encountered
+     */
+    public Object lookupLink(Name name)
+        throws NamingException {
+        return dirContext.lookupLink(parseName(name));
+    }
+
+
+    /**
+     * Retrieves the named object, following links except for the terminal 
+     * atomic component of the name.
+     * 
+     * @param name the name of the object to look up
+     * @return the object bound to name, not following the terminal link 
+     * (if any).
+     * @exception NamingException if a naming exception is encountered
+     */
+    public Object lookupLink(String name)
+        throws NamingException {
+        return dirContext.lookupLink(parseName(name));
+    }
+
+
+    /**
+     * Retrieves the parser associated with the named context. In a 
+     * federation of namespaces, different naming systems will parse names 
+     * differently. This method allows an application to get a parser for 
+     * parsing names into their atomic components using the naming convention 
+     * of a particular naming system. Within any single naming system, 
+     * NameParser objects returned by this method must be equal (using the 
+     * equals() test).
+     * 
+     * @param name the name of the context from which to get the parser
+     * @return a name parser that can parse compound names into their atomic 
+     * components
+     * @exception NamingException if a naming exception is encountered
+     */
+    public NameParser getNameParser(Name name)
+        throws NamingException {
+        return dirContext.getNameParser(parseName(name));
+    }
+
+
+    /**
+     * Retrieves the parser associated with the named context.
+     * 
+     * @param name the name of the context from which to get the parser
+     * @return a name parser that can parse compound names into their atomic 
+     * components
+     * @exception NamingException if a naming exception is encountered
+     */
+    public NameParser getNameParser(String name)
+        throws NamingException {
+        return dirContext.getNameParser(parseName(name));
+    }
+
+
+    /**
+     * Composes the name of this context with a name relative to this context.
+     * <p>
+     * Given a name (name) relative to this context, and the name (prefix) 
+     * of this context relative to one of its ancestors, this method returns 
+     * the composition of the two names using the syntax appropriate for the 
+     * naming system(s) involved. That is, if name names an object relative 
+     * to this context, the result is the name of the same object, but 
+     * relative to the ancestor context. None of the names may be null.
+     * 
+     * @param name a name relative to this context
+     * @param prefix the name of this context relative to one of its ancestors
+     * @return the composition of prefix and name
+     * @exception NamingException if a naming exception is encountered
+     */
+    public Name composeName(Name name, Name prefix)
+        throws NamingException {
+        Name result = (Name) prefix.clone();
+	return result.addAll(name);
+    }
+
+
+    /**
+     * Composes the name of this context with a name relative to this context.
+     * 
+     * @param name a name relative to this context
+     * @param prefix the name of this context relative to one of its ancestors
+     * @return the composition of prefix and name
+     * @exception NamingException if a naming exception is encountered
+     */
+    public String composeName(String name, String prefix)
+        throws NamingException {
+        return prefix + "/" + name;
+    }
+
+
+    /**
+     * Adds a new environment property to the environment of this context. If 
+     * the property already exists, its value is overwritten.
+     * 
+     * @param propName the name of the environment property to add; may not 
+     * be null
+     * @param propVal the value of the property to add; may not be null
+     * @exception NamingException if a naming exception is encountered
+     */
+    public Object addToEnvironment(String propName, Object propVal)
+        throws NamingException {
+        return dirContext.addToEnvironment(propName, propVal);
+    }
+
+
+    /**
+     * Removes an environment property from the environment of this context. 
+     * 
+     * @param propName the name of the environment property to remove; 
+     * may not be null
+     * @exception NamingException if a naming exception is encountered
+     */
+    public Object removeFromEnvironment(String propName)
+        throws NamingException {
+        return dirContext.removeFromEnvironment(propName);
+    }
+
+
+    /**
+     * Retrieves the environment in effect for this context. See class 
+     * description for more details on environment properties. 
+     * The caller should not make any changes to the object returned: their 
+     * effect on the context is undefined. The environment of this context 
+     * may be changed using addToEnvironment() and removeFromEnvironment().
+     * 
+     * @return the environment of this context; never null
+     * @exception NamingException if a naming exception is encountered
+     */
+    public Hashtable getEnvironment()
+        throws NamingException {
+        return dirContext.getEnvironment();
+    }
+
+
+    /**
+     * Closes this context. This method releases this context's resources 
+     * immediately, instead of waiting for them to be released automatically 
+     * by the garbage collector.
+     * This method is idempotent: invoking it on a context that has already 
+     * been closed has no effect. Invoking any other method on a closed 
+     * context is not allowed, and results in undefined behaviour.
+     * 
+     * @exception NamingException if a naming exception is encountered
+     */
+    public void close()
+        throws NamingException {
+        dirContext.close();
+    }
+
+
+    /**
+     * Retrieves the full name of this context within its own namespace.
+     * <p>
+     * Many naming services have a notion of a "full name" for objects in 
+     * their respective namespaces. For example, an LDAP entry has a 
+     * distinguished name, and a DNS record has a fully qualified name. This 
+     * method allows the client application to retrieve this name. The string 
+     * returned by this method is not a JNDI composite name and should not be 
+     * passed directly to context methods. In naming systems for which the 
+     * notion of full name does not make sense, 
+     * OperationNotSupportedException is thrown.
+     * 
+     * @return this context's name in its own namespace; never null
+     * @exception OperationNotSupportedException if the naming system does 
+     * not have the notion of a full name
+     * @exception NamingException if a naming exception is encountered
+     */
+    public String getNameInNamespace()
+        throws NamingException {
+        return dirContext.getNameInNamespace();
+    }
+
+
+    // ----------------------------------------------------- DirContext Methods
+
+
+    /**
+     * Retrieves all of the attributes associated with a named object. 
+     * 
+     * @return the set of attributes associated with name. 
+     * Returns an empty attribute set if name has no attributes; never null.
+     * @param name the name of the object from which to retrieve attributes
+     * @exception NamingException if a naming exception is encountered
+     */
+    public Attributes getAttributes(Name name)
+        throws NamingException {
+        CacheEntry entry = cacheLookup(name.toString());
+        if (entry != null) {
+            return entry.attributes;
+        }
+        Attributes attributes = dirContext.getAttributes(parseName(name));
+        if (!(attributes instanceof ResourceAttributes)) {
+            attributes = new ResourceAttributes(attributes);
+        }
+        return attributes;
+    }
+
+
+    /**
+     * Retrieves all of the attributes associated with a named object.
+     * 
+     * @return the set of attributes associated with name
+     * @param name the name of the object from which to retrieve attributes
+     * @exception NamingException if a naming exception is encountered
+     */
+    public Attributes getAttributes(String name)
+        throws NamingException {
+        CacheEntry entry = cacheLookup(name);
+        if (entry != null) {
+            return entry.attributes;
+        }
+        Attributes attributes = dirContext.getAttributes(parseName(name));
+        if (!(attributes instanceof ResourceAttributes)) {
+            attributes = new ResourceAttributes(attributes);
+        }
+        return attributes;
+    }
+
+
+    /**
+     * Retrieves selected attributes associated with a named object. 
+     * See the class description regarding attribute models, attribute type 
+     * names, and operational attributes.
+     * 
+     * @return the requested attributes; never null
+     * @param name the name of the object from which to retrieve attributes
+     * @param attrIds the identifiers of the attributes to retrieve. null 
+     * indicates that all attributes should be retrieved; an empty array 
+     * indicates that none should be retrieved
+     * @exception NamingException if a naming exception is encountered
+     */
+    public Attributes getAttributes(Name name, String[] attrIds)
+        throws NamingException {
+        Attributes attributes = 
+            dirContext.getAttributes(parseName(name), attrIds);
+        if (!(attributes instanceof ResourceAttributes)) {
+            attributes = new ResourceAttributes(attributes);
+        }
+        return attributes;
+    }
+
+
+    /**
+     * Retrieves selected attributes associated with a named object.
+     * 
+     * @return the requested attributes; never null
+     * @param name the name of the object from which to retrieve attributes
+     * @param attrIds the identifiers of the attributes to retrieve. null 
+     * indicates that all attributes should be retrieved; an empty array 
+     * indicates that none should be retrieved
+     * @exception NamingException if a naming exception is encountered
+     */
+     public Attributes getAttributes(String name, String[] attrIds)
+         throws NamingException {
+        Attributes attributes = 
+            dirContext.getAttributes(parseName(name), attrIds);
+        if (!(attributes instanceof ResourceAttributes)) {
+            attributes = new ResourceAttributes(attributes);
+        }
+        return attributes;
+     }
+
+
+    /**
+     * Modifies the attributes associated with a named object. The order of 
+     * the modifications is not specified. Where possible, the modifications 
+     * are performed atomically.
+     * 
+     * @param name the name of the object whose attributes will be updated
+     * @param mod_op the modification operation, one of: ADD_ATTRIBUTE, 
+     * REPLACE_ATTRIBUTE, REMOVE_ATTRIBUTE
+     * @param attrs the attributes to be used for the modification; may not 
+     * be null
+     * @exception AttributeModificationException if the modification cannot be
+     * completed successfully
+     * @exception NamingException if a naming exception is encountered
+     */
+    public void modifyAttributes(Name name, int mod_op, Attributes attrs)
+        throws NamingException {
+        dirContext.modifyAttributes(parseName(name), mod_op, attrs);
+        cacheUnload(name.toString());
+    }
+
+
+    /**
+     * Modifies the attributes associated with a named object.
+     * 
+     * @param name the name of the object whose attributes will be updated
+     * @param mod_op the modification operation, one of: ADD_ATTRIBUTE, 
+     * REPLACE_ATTRIBUTE, REMOVE_ATTRIBUTE
+     * @param attrs the attributes to be used for the modification; may not 
+     * be null
+     * @exception AttributeModificationException if the modification cannot be
+     * completed successfully
+     * @exception NamingException if a naming exception is encountered
+     */
+    public void modifyAttributes(String name, int mod_op, Attributes attrs)
+        throws NamingException {
+        dirContext.modifyAttributes(parseName(name), mod_op, attrs);
+        cacheUnload(name);
+    }
+
+
+    /**
+     * Modifies the attributes associated with a named object using an an 
+     * ordered list of modifications. The modifications are performed in the 
+     * order specified. Each modification specifies a modification operation 
+     * code and an attribute on which to operate. Where possible, the 
+     * modifications are performed atomically.
+     * 
+     * @param name the name of the object whose attributes will be updated
+     * @param mods an ordered sequence of modifications to be performed; may 
+     * not be null
+     * @exception AttributeModificationException if the modification cannot be
+     * completed successfully
+     * @exception NamingException if a naming exception is encountered
+     */
+    public void modifyAttributes(Name name, ModificationItem[] mods)
+        throws NamingException {
+        dirContext.modifyAttributes(parseName(name), mods);
+        cacheUnload(name.toString());
+    }
+
+
+    /**
+     * Modifies the attributes associated with a named object using an an 
+     * ordered list of modifications.
+     * 
+     * @param name the name of the object whose attributes will be updated
+     * @param mods an ordered sequence of modifications to be performed; may 
+     * not be null
+     * @exception AttributeModificationException if the modification cannot be
+     * completed successfully
+     * @exception NamingException if a naming exception is encountered
+     */
+    public void modifyAttributes(String name, ModificationItem[] mods)
+        throws NamingException {
+        dirContext.modifyAttributes(parseName(name), mods);
+        cacheUnload(name);
+    }
+
+
+    /**
+     * Binds a name to an object, along with associated attributes. If attrs 
+     * is null, the resulting binding will have the attributes associated 
+     * with obj if obj is a DirContext, and no attributes otherwise. If attrs 
+     * is non-null, the resulting binding will have attrs as its attributes; 
+     * any attributes associated with obj are ignored.
+     * 
+     * @param name the name to bind; may not be empty
+     * @param obj the object to bind; possibly null
+     * @param attrs the attributes to associate with the binding
+     * @exception NameAlreadyBoundException if name is already bound
+     * @exception InvalidAttributesException if some "mandatory" attributes 
+     * of the binding are not supplied
+     * @exception NamingException if a naming exception is encountered
+     */
+    public void bind(Name name, Object obj, Attributes attrs)
+        throws NamingException {
+        dirContext.bind(parseName(name), obj, attrs);
+        cacheUnload(name.toString());
+    }
+
+
+    /**
+     * Binds a name to an object, along with associated attributes.
+     * 
+     * @param name the name to bind; may not be empty
+     * @param obj the object to bind; possibly null
+     * @param attrs the attributes to associate with the binding
+     * @exception NameAlreadyBoundException if name is already bound
+     * @exception InvalidAttributesException if some "mandatory" attributes 
+     * of the binding are not supplied
+     * @exception NamingException if a naming exception is encountered
+     */
+    public void bind(String name, Object obj, Attributes attrs)
+        throws NamingException {
+        dirContext.bind(parseName(name), obj, attrs);
+        cacheUnload(name);
+    }
+
+
+    /**
+     * Binds a name to an object, along with associated attributes, 
+     * overwriting any existing binding. If attrs is null and obj is a 
+     * DirContext, the attributes from obj are used. If attrs is null and obj 
+     * is not a DirContext, any existing attributes associated with the object
+     * already bound in the directory remain unchanged. If attrs is non-null, 
+     * any existing attributes associated with the object already bound in 
+     * the directory are removed and attrs is associated with the named 
+     * object. If obj is a DirContext and attrs is non-null, the attributes 
+     * of obj are ignored.
+     * 
+     * @param name the name to bind; may not be empty
+     * @param obj the object to bind; possibly null
+     * @param attrs the attributes to associate with the binding
+     * @exception InvalidAttributesException if some "mandatory" attributes 
+     * of the binding are not supplied
+     * @exception NamingException if a naming exception is encountered
+     */
+    public void rebind(Name name, Object obj, Attributes attrs)
+        throws NamingException {
+        dirContext.rebind(parseName(name), obj, attrs);
+        cacheUnload(name.toString());
+    }
+
+
+    /**
+     * Binds a name to an object, along with associated attributes, 
+     * overwriting any existing binding.
+     * 
+     * @param name the name to bind; may not be empty
+     * @param obj the object to bind; possibly null
+     * @param attrs the attributes to associate with the binding
+     * @exception InvalidAttributesException if some "mandatory" attributes 
+     * of the binding are not supplied
+     * @exception NamingException if a naming exception is encountered
+     */
+    public void rebind(String name, Object obj, Attributes attrs)
+        throws NamingException {
+        dirContext.rebind(parseName(name), obj, attrs);
+        cacheUnload(name);
+    }
+
+
+    /**
+     * Creates and binds a new context, along with associated attributes. 
+     * This method creates a new subcontext with the given name, binds it in 
+     * the target context (that named by all but terminal atomic component of 
+     * the name), and associates the supplied attributes with the newly 
+     * created object. All intermediate and target contexts must already 
+     * exist. If attrs is null, this method is equivalent to 
+     * Context.createSubcontext().
+     * 
+     * @param name the name of the context to create; may not be empty
+     * @param attrs the attributes to associate with the newly created context
+     * @return the newly created context
+     * @exception NameAlreadyBoundException if the name is already bound
+     * @exception InvalidAttributesException if attrs does not contain all 
+     * the mandatory attributes required for creation
+     * @exception NamingException if a naming exception is encountered
+     */
+    public DirContext createSubcontext(Name name, Attributes attrs)
+        throws NamingException {
+        DirContext context = 
+            dirContext.createSubcontext(parseName(name), attrs);
+        cacheUnload(name.toString());
+        return context;
+    }
+
+
+    /**
+     * Creates and binds a new context, along with associated attributes.
+     * 
+     * @param name the name of the context to create; may not be empty
+     * @param attrs the attributes to associate with the newly created context
+     * @return the newly created context
+     * @exception NameAlreadyBoundException if the name is already bound
+     * @exception InvalidAttributesException if attrs does not contain all 
+     * the mandatory attributes required for creation
+     * @exception NamingException if a naming exception is encountered
+     */
+    public DirContext createSubcontext(String name, Attributes attrs)
+        throws NamingException {
+        DirContext context = 
+            dirContext.createSubcontext(parseName(name), attrs);
+        cacheUnload(name);
+        return context;
+    }
+
+
+    /**
+     * Retrieves the schema associated with the named object. The schema 
+     * describes rules regarding the structure of the namespace and the 
+     * attributes stored within it. The schema specifies what types of 
+     * objects can be added to the directory and where they can be added; 
+     * what mandatory and optional attributes an object can have. The range 
+     * of support for schemas is directory-specific.
+     * 
+     * @param name the name of the object whose schema is to be retrieved
+     * @return the schema associated with the context; never null
+     * @exception OperationNotSupportedException if schema not supported
+     * @exception NamingException if a naming exception is encountered
+     */
+    public DirContext getSchema(Name name)
+        throws NamingException {
+        return dirContext.getSchema(parseName(name));
+    }
+
+
+    /**
+     * Retrieves the schema associated with the named object.
+     * 
+     * @param name the name of the object whose schema is to be retrieved
+     * @return the schema associated with the context; never null
+     * @exception OperationNotSupportedException if schema not supported
+     * @exception NamingException if a naming exception is encountered
+     */
+    public DirContext getSchema(String name)
+        throws NamingException {
+        return dirContext.getSchema(parseName(name));
+    }
+
+
+    /**
+     * Retrieves a context containing the schema objects of the named 
+     * object's class definitions.
+     * 
+     * @param name the name of the object whose object class definition is to 
+     * be retrieved
+     * @return the DirContext containing the named object's class 
+     * definitions; never null
+     * @exception OperationNotSupportedException if schema not supported
+     * @exception NamingException if a naming exception is encountered
+     */
+    public DirContext getSchemaClassDefinition(Name name)
+        throws NamingException {
+        return dirContext.getSchemaClassDefinition(parseName(name));
+    }
+
+
+    /**
+     * Retrieves a context containing the schema objects of the named 
+     * object's class definitions.
+     * 
+     * @param name the name of the object whose object class definition is to 
+     * be retrieved
+     * @return the DirContext containing the named object's class 
+     * definitions; never null
+     * @exception OperationNotSupportedException if schema not supported
+     * @exception NamingException if a naming exception is encountered
+     */
+    public DirContext getSchemaClassDefinition(String name)
+        throws NamingException {
+        return dirContext.getSchemaClassDefinition(parseName(name));
+    }
+
+
+    /**
+     * Searches in a single context for objects that contain a specified set 
+     * of attributes, and retrieves selected attributes. The search is 
+     * performed using the default SearchControls settings.
+     * 
+     * @param name the name of the context to search
+     * @param matchingAttributes the attributes to search for. If empty or 
+     * null, all objects in the target context are returned.
+     * @param attributesToReturn the attributes to return. null indicates 
+     * that all attributes are to be returned; an empty array indicates that 
+     * none are to be returned.
+     * @return a non-null enumeration of SearchResult objects. Each 
+     * SearchResult contains the attributes identified by attributesToReturn 
+     * and the name of the corresponding object, named relative to the 
+     * context named by name.
+     * @exception NamingException if a naming exception is encountered
+     */
+    public NamingEnumeration search(Name name, Attributes matchingAttributes,
+                                    String[] attributesToReturn)
+        throws NamingException {
+        return dirContext.search(parseName(name), matchingAttributes, 
+                                 attributesToReturn);
+    }
+
+
+    /**
+     * Searches in a single context for objects that contain a specified set 
+     * of attributes, and retrieves selected attributes.
+     * 
+     * @param name the name of the context to search
+     * @param matchingAttributes the attributes to search for. If empty or 
+     * null, all objects in the target context are returned.
+     * @param attributesToReturn the attributes to return. null indicates 
+     * that all attributes are to be returned; an empty array indicates that 
+     * none are to be returned.
+     * @return a non-null enumeration of SearchResult objects. Each 
+     * SearchResult contains the attributes identified by attributesToReturn 
+     * and the name of the corresponding object, named relative to the 
+     * context named by name.
+     * @exception NamingException if a naming exception is encountered
+     */
+    public NamingEnumeration search(String name, Attributes matchingAttributes,
+                                    String[] attributesToReturn)
+        throws NamingException {
+        return dirContext.search(parseName(name), matchingAttributes, 
+                                 attributesToReturn);
+    }
+
+
+    /**
+     * Searches in a single context for objects that contain a specified set 
+     * of attributes. This method returns all the attributes of such objects. 
+     * It is equivalent to supplying null as the atributesToReturn parameter 
+     * to the method search(Name, Attributes, String[]).
+     * 
+     * @param name the name of the context to search
+     * @param matchingAttributes the attributes to search for. If empty or 
+     * null, all objects in the target context are returned.
+     * @return a non-null enumeration of SearchResult objects. Each 
+     * SearchResult contains the attributes identified by attributesToReturn 
+     * and the name of the corresponding object, named relative to the 
+     * context named by name.
+     * @exception NamingException if a naming exception is encountered
+     */
+    public NamingEnumeration search(Name name, Attributes matchingAttributes)
+        throws NamingException {
+        return dirContext.search(parseName(name), matchingAttributes);
+    }
+
+
+    /**
+     * Searches in a single context for objects that contain a specified set 
+     * of attributes.
+     * 
+     * @param name the name of the context to search
+     * @param matchingAttributes the attributes to search for. If empty or 
+     * null, all objects in the target context are returned.
+     * @return a non-null enumeration of SearchResult objects. Each 
+     * SearchResult contains the attributes identified by attributesToReturn 
+     * and the name of the corresponding object, named relative to the 
+     * context named by name.
+     * @exception NamingException if a naming exception is encountered
+     */
+    public NamingEnumeration search(String name, Attributes matchingAttributes)
+        throws NamingException {
+        return dirContext.search(parseName(name), matchingAttributes);
+    }
+
+
+    /**
+     * Searches in the named context or object for entries that satisfy the 
+     * given search filter. Performs the search as specified by the search 
+     * controls.
+     * 
+     * @param name the name of the context or object to search
+     * @param filter the filter expression to use for the search; may not be 
+     * null
+     * @param cons the search controls that control the search. If null, 
+     * the default search controls are used (equivalent to 
+     * (new SearchControls())).
+     * @return an enumeration of SearchResults of the objects that satisfy 
+     * the filter; never null
+     * @exception InvalidSearchFilterException if the search filter specified 
+     * is not supported or understood by the underlying directory
+     * @exception InvalidSearchControlsException if the search controls 
+     * contain invalid settings
+     * @exception NamingException if a naming exception is encountered
+     */
+    public NamingEnumeration search(Name name, String filter, 
+                                    SearchControls cons)
+        throws NamingException {
+        return dirContext.search(parseName(name), filter, cons);
+    }
+
+
+    /**
+     * Searches in the named context or object for entries that satisfy the 
+     * given search filter. Performs the search as specified by the search 
+     * controls.
+     * 
+     * @param name the name of the context or object to search
+     * @param filter the filter expression to use for the search; may not be 
+     * null
+     * @param cons the search controls that control the search. If null, 
+     * the default search controls are used (equivalent to 
+     * (new SearchControls())).
+     * @return an enumeration of SearchResults of the objects that satisfy 
+     * the filter; never null
+     * @exception InvalidSearchFilterException if the search filter 
+     * specified is not supported or understood by the underlying directory
+     * @exception InvalidSearchControlsException if the search controls 
+     * contain invalid settings
+     * @exception NamingException if a naming exception is encountered
+     */
+    public NamingEnumeration search(String name, String filter, 
+                                    SearchControls cons)
+        throws NamingException {
+        return dirContext.search(parseName(name), filter, cons);
+    }
+
+
+    /**
+     * Searches in the named context or object for entries that satisfy the 
+     * given search filter. Performs the search as specified by the search 
+     * controls.
+     * 
+     * @param name the name of the context or object to search
+     * @param filterExpr the filter expression to use for the search. 
+     * The expression may contain variables of the form "{i}" where i is a 
+     * nonnegative integer. May not be null.
+     * @param filterArgs the array of arguments to substitute for the 
+     * variables in filterExpr. The value of filterArgs[i] will replace each 
+     * occurrence of "{i}". If null, equivalent to an empty array.
+     * @param cons the search controls that control the search. If null, the 
+     * default search controls are used (equivalent to (new SearchControls())).
+     * @return an enumeration of SearchResults of the objects that satisy the 
+     * filter; never null
+     * @exception ArrayIndexOutOfBoundsException if filterExpr contains {i} 
+     * expressions where i is outside the bounds of the array filterArgs
+     * @exception InvalidSearchControlsException if cons contains invalid 
+     * settings
+     * @exception InvalidSearchFilterException if filterExpr with filterArgs 
+     * represents an invalid search filter
+     * @exception NamingException if a naming exception is encountered
+     */
+    public NamingEnumeration search(Name name, String filterExpr,
+                                    Object[] filterArgs, SearchControls cons)
+        throws NamingException {
+        return dirContext.search(parseName(name), filterExpr, filterArgs, 
+                                 cons);
+    }
+
+
+    /**
+     * Searches in the named context or object for entries that satisfy the 
+     * given search filter. Performs the search as specified by the search 
+     * controls.
+     * 
+     * @param name the name of the context or object to search
+     * @param filterExpr the filter expression to use for the search. 
+     * The expression may contain variables of the form "{i}" where i is a 
+     * nonnegative integer. May not be null.
+     * @param filterArgs the array of arguments to substitute for the 
+     * variables in filterExpr. The value of filterArgs[i] will replace each 
+     * occurrence of "{i}". If null, equivalent to an empty array.
+     * @param cons the search controls that control the search. If null, the 
+     * default search controls are used (equivalent to (new SearchControls())).
+     * @return an enumeration of SearchResults of the objects that satisy the 
+     * filter; never null
+     * @exception ArrayIndexOutOfBoundsException if filterExpr contains {i} 
+     * expressions where i is outside the bounds of the array filterArgs
+     * @exception InvalidSearchControlsException if cons contains invalid 
+     * settings
+     * @exception InvalidSearchFilterException if filterExpr with filterArgs 
+     * represents an invalid search filter
+     * @exception NamingException if a naming exception is encountered
+     */
+    public NamingEnumeration search(String name, String filterExpr,
+                                    Object[] filterArgs, SearchControls cons)
+        throws NamingException {
+        return dirContext.search(parseName(name), filterExpr, filterArgs, 
+                                 cons);
+    }
+
+
+    // ------------------------------------------------------ Protected Methods
+
+
+    /**
+     * Parses a name.
+     * 
+     * @return the parsed name
+     */
+    protected String parseName(String name) 
+        throws NamingException {
+        return name;
+    }
+
+
+    /**
+     * Parses a name.
+     * 
+     * @return the parsed name
+     */
+    protected Name parseName(Name name) 
+        throws NamingException {
+        return name;
+    }
+
+
+    /**
+     * Lookup in cache.
+     */
+    protected CacheEntry cacheLookup(String name)
+        throws NamingException {
+        if (cache == null)
+            return (null);
+        CacheEntry cacheEntry = (CacheEntry) cache.get(name);
+        if (cacheEntry == null) {
+            cacheEntry = new CacheEntry();
+            cacheEntry.name = name;
+            // Load entry
+            cacheLoad(cacheEntry);
+        } else {
+            if (!validate(cacheEntry)) {
+                if (!revalidate(cacheEntry)) {
+                    cacheUnload(cacheEntry.name);
+                    return (null);
+                } else {
+                    cacheEntry.timestamp = 
+                        System.currentTimeMillis() + cacheTTL;
+                }
+            }
+        }
+        if (!cacheEntry.exists) {
+            throw notFoundException;
+        }
+        return (cacheEntry);
+    }
+
+
+    /**
+     * Validate entry.
+     */
+    protected boolean validate(CacheEntry entry) {
+        if (((!entry.exists)
+             || (entry.context != null)
+             || ((entry.resource != null) 
+                 && (entry.resource.getContent() != null)))
+            && (System.currentTimeMillis() < entry.timestamp)) {
+            return true;
+        }
+        return false;
+    }
+
+
+    /**
+     * Revalidate entry.
+     */
+    protected boolean revalidate(CacheEntry entry) {
+        // Get the attributes at the given path, and check the last 
+        // modification date
+        if (!entry.exists)
+            return false;
+        if (entry.attributes == null)
+            return false;
+        long lastModified = entry.attributes.getLastModified();
+        long contentLength = entry.attributes.getContentLength();
+        if (lastModified <= 0)
+            return false;
+        try {
+            Attributes tempAttributes = dirContext.getAttributes(entry.name);
+            ResourceAttributes attributes = null;
+            if (!(tempAttributes instanceof ResourceAttributes)) {
+                attributes = new ResourceAttributes(tempAttributes);
+            } else {
+                attributes = (ResourceAttributes) tempAttributes;
+            }
+            long lastModified2 = attributes.getLastModified();
+            long contentLength2 = attributes.getContentLength();
+            return (lastModified == lastModified2) 
+                && (contentLength == contentLength2);
+        } catch (NamingException e) {
+            return false;
+        }
+    }
+
+
+    /**
+     * Load entry into cache.
+     */
+    protected void cacheLoad(CacheEntry entry) {
+
+        String name = entry.name;
+
+        // Retrieve missing info
+        boolean exists = true;
+
+        // Retrieving attributes
+        if (entry.attributes == null) {
+            try {
+                Attributes attributes = dirContext.getAttributes(entry.name);
+                if (!(attributes instanceof ResourceAttributes)) {
+                    entry.attributes = 
+                        new ResourceAttributes(attributes);
+                } else {
+                    entry.attributes = (ResourceAttributes) attributes;
+                }
+            } catch (NamingException e) {
+                exists = false;
+            }
+        }
+
+        // Retriving object
+        if ((exists) && (entry.resource == null) && (entry.context == null)) {
+            try {
+                Object object = dirContext.lookup(name);
+                if (object instanceof InputStream) {
+                    entry.resource = new Resource((InputStream) object);
+                } else if (object instanceof DirContext) {
+                    entry.context = (DirContext) object;
+                } else if (object instanceof Resource) {
+                    entry.resource = (Resource) object;
+                } else {
+                    entry.resource = new Resource(new ByteArrayInputStream
+                        (object.toString().getBytes()));
+                }
+            } catch (NamingException e) {
+                exists = false;
+            }
+        }
+
+        // Load object content
+        if ((exists) && (entry.resource != null) 
+            && (entry.resource.getContent() == null) 
+            && (entry.attributes.getContentLength() >= 0)
+            && (entry.attributes.getContentLength() < cacheObjectMaxSize)) {
+            int length = (int) entry.attributes.getContentLength();
+            InputStream is = null;
+            try {
+                is = entry.resource.streamContent();
+                int pos = 0;
+                byte[] b = new byte[length];
+                while (pos < length) {
+                    int n = is.read(b, pos, length - pos);
+                    if (n < 0)
+                        break;
+                    pos = pos + n;
+                }
+                entry.resource.setContent(b);
+            } catch (IOException e) {
+                ; // Ignore
+            } finally {
+                try {
+                    if (is != null)
+                        is.close();
+                } catch (IOException e) {
+                    ; // Ignore
+                }
+            }
+        }
+
+        // Set existence flag
+        entry.exists = exists;
+
+        // Set timestamp
+        entry.timestamp = System.currentTimeMillis() + cacheTTL;
+
+        // Add new entry to cache
+        cache.put(name, entry);
+
+    }
+
+
+    /**
+     * Remove entry from cache.
+     */
+    protected boolean cacheUnload(String name) {
+        if (cache == null)
+            return false;
+        return (cache.remove(name) != null);
+    }
+
+
+    // ------------------------------------------------- CacheEntry Inner Class
+
+
+    protected class CacheEntry {
+
+
+        // ------------------------------------------------- Instance Variables
+
+
+        long timestamp = -1;
+        String name = null;
+        ResourceAttributes attributes = null;
+        Resource resource = null;
+        DirContext context = null;
+        boolean exists = true;
+
+
+        // ----------------------------------------------------- Public Methods
+
+
+        public void recycle() {
+            timestamp = -1;
+            name = null;
+            attributes = null;
+            resource = null;
+            context = null;
+            exists = true;
+        }
+
+
+        public String toString() {
+            return ("Cache entry: " + name + "\n"
+                    + "Exists: " + exists + "\n"
+                    + "Attributes: " + attributes + "\n"
+                    + "Resource: " + resource + "\n"
+                    + "Context: " + context);
+        }
+
+
+    }
+
+
+}
+

Added: incubator/directory/naming/trunk/core/src/java/org/apache/directory/naming/resources/RecyclableNamingEnumeration.java
==============================================================================
--- (empty file)
+++ incubator/directory/naming/trunk/core/src/java/org/apache/directory/naming/resources/RecyclableNamingEnumeration.java	Sun Dec  7 13:00:05 2003
@@ -0,0 +1,160 @@
+/*
+ * $Header: /home/cvs/jakarta-commons-sandbox/naming/core/src/java/org/apache/commons/naming/resources/RecyclableNamingEnumeration.java,v 1.2 2003/10/13 08:15:54 rdonkin Exp $
+ * $Revision: 1.2 $
+ * $Date: 2003/10/13 08:15:54 $
+ *
+ * ====================================================================
+ *
+ * The Apache Software License, Version 1.1
+ *
+ * Copyright (c) 1999 The Apache Software Foundation.  All rights 
+ * reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. The end-user documentation included with the redistribution, if
+ *    any, must include the following acknowledgement:
+ *       "This product includes software developed by the 
+ *        Apache Software Foundation (http://www.apache.org/)."
+ *    Alternately, this acknowledgement may appear in the software itself,
+ *    if and wherever such third-party acknowledgements normally appear.
+ *
+ * 4. The names "The Jakarta Project", "Tomcat", and "Apache Software
+ *    Foundation" must not be used to endorse or promote products derived
+ *    from this software without prior written permission. For written 
+ *    permission, please contact apache@apache.org.
+ *
+ * 5. Products derived from this software may not be called "Apache"
+ *    nor may "Apache" appear in their names without prior written
+ *    permission of the Apache Software Foundation.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation.  For more
+ * information on the Apache Software Foundation, please see
+ * <http://www.apache.org/>.
+ *
+ * [Additional notices, if required by prior licensing conditions]
+ *
+ */ 
+
+
+package org.apache.directory.naming.resources;
+
+import java.util.Hashtable;
+import java.util.Vector;
+import java.util.Enumeration;
+import javax.naming.NamingException;
+import javax.naming.NamingEnumeration;
+import javax.naming.NameClassPair;
+
+/**
+ * Naming enumeration implementation.
+ *
+ * @author Remy Maucherat
+ * @version $Revision: 1.2 $ $Date: 2003/10/13 08:15:54 $
+ */
+
+public class RecyclableNamingEnumeration 
+    implements NamingEnumeration {
+
+
+    // ----------------------------------------------------------- Constructors
+
+
+    public RecyclableNamingEnumeration(Vector entries) {
+        this.entries = entries;
+        recycle();
+    }
+
+
+    // -------------------------------------------------------------- Variables
+
+
+    /**
+     * Entries.
+     */
+    protected Vector entries;
+
+
+    /**
+     * Underlying enumeration.
+     */
+    protected Enumeration enum;
+
+
+    // --------------------------------------------------------- Public Methods
+
+
+    /**
+     * Retrieves the next element in the enumeration.
+     */
+    public Object next()
+        throws NamingException {
+        return nextElement();
+    }
+
+
+    /**
+     * Determines whether there are any more elements in the enumeration.
+     */
+    public boolean hasMore()
+        throws NamingException {
+        return enum.hasMoreElements();
+    }
+
+
+    /**
+     * Closes this enumeration.
+     */
+    public void close()
+        throws NamingException {
+    }
+
+
+    public boolean hasMoreElements() {
+        return enum.hasMoreElements();
+    }
+
+
+    public Object nextElement() {
+        return enum.nextElement();
+    }
+
+
+    // -------------------------------------------------------- Package Methods
+
+
+    /**
+     * Recycle.
+     */
+    void recycle() {
+        enum = entries.elements();
+    }
+
+
+}
+

Added: incubator/directory/naming/trunk/core/src/java/org/apache/directory/naming/resources/Resource.java
==============================================================================
--- (empty file)
+++ incubator/directory/naming/trunk/core/src/java/org/apache/directory/naming/resources/Resource.java	Sun Dec  7 13:00:05 2003
@@ -0,0 +1,158 @@
+/*
+ * $Header: /home/cvs/jakarta-commons-sandbox/naming/core/src/java/org/apache/commons/naming/resources/Resource.java,v 1.2 2003/10/13 08:15:54 rdonkin Exp $
+ * $Revision: 1.2 $
+ * $Date: 2003/10/13 08:15:54 $
+ *
+ * ====================================================================
+ *
+ * The Apache Software License, Version 1.1
+ *
+ * Copyright (c) 1999 The Apache Software Foundation.  All rights 
+ * reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. The end-user documentation included with the redistribution, if
+ *    any, must include the following acknowledgement:
+ *       "This product includes software developed by the 
+ *        Apache Software Foundation (http://www.apache.org/)."
+ *    Alternately, this acknowledgement may appear in the software itself,
+ *    if and wherever such third-party acknowledgements normally appear.
+ *
+ * 4. The names "The Jakarta Project", "Tomcat", and "Apache Software
+ *    Foundation" must not be used to endorse or promote products derived
+ *    from this software without prior written permission. For written 
+ *    permission, please contact apache@apache.org.
+ *
+ * 5. Products derived from this software may not be called "Apache"
+ *    nor may "Apache" appear in their names without prior written
+ *    permission of the Apache Software Foundation.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation.  For more
+ * information on the Apache Software Foundation, please see
+ * <http://www.apache.org/>.
+ *
+ * [Additional notices, if required by prior licensing conditions]
+ *
+ */ 
+
+package org.apache.directory.naming.resources;
+
+import java.io.InputStream;
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+
+/**
+ * Encapsultes the contents of a resource.
+ * 
+ * @author <a href="mailto:remm@apache.org">Remy Maucherat</a>
+ * @version $Revision: 1.2 $
+ */
+public class Resource {
+    
+    
+    // ----------------------------------------------------------- Constructors
+    
+    
+    public Resource() {
+    }
+    
+    
+    public Resource(InputStream inputStream) {
+        setContent(inputStream);
+    }
+    
+    
+    public Resource(byte[] binaryContent) {
+        setContent(binaryContent);
+    }
+    
+    
+    // ----------------------------------------------------- Instance Variables
+    
+    
+    /**
+     * Binary content.
+     */
+    protected byte[] binaryContent = null;
+    
+    
+    /**
+     * Input stream.
+     */
+    protected InputStream inputStream = null;
+    
+    
+    // ------------------------------------------------------------- Properties
+    
+    
+    /**
+     * Content accessor.
+     * 
+     * @return InputStream
+     */
+    public InputStream streamContent()
+        throws IOException {
+        if (binaryContent != null) {
+            return new ByteArrayInputStream(binaryContent);
+        }
+        return inputStream;
+    }
+    
+    
+    /**
+     * Content accessor.
+     * 
+     * @return binary content
+     */
+    public byte[] getContent() {
+        return binaryContent;
+    }
+    
+    
+    /**
+     * Content mutator.
+     * 
+     * @param inputStream New input stream
+     */
+    public void setContent(InputStream inputStream) {
+        this.inputStream = inputStream;
+    }
+    
+    
+    /**
+     * Content mutator.
+     * 
+     * @param binaryContent New bin content
+     */
+    public void setContent(byte[] binaryContent) {
+        this.binaryContent = binaryContent;
+    }
+    
+    
+}

Added: incubator/directory/naming/trunk/core/src/java/org/apache/directory/naming/resources/ResourceAttributes.java
==============================================================================
--- (empty file)
+++ incubator/directory/naming/trunk/core/src/java/org/apache/directory/naming/resources/ResourceAttributes.java	Sun Dec  7 13:00:05 2003
@@ -0,0 +1,881 @@
+/*
+ * $Header: /home/cvs/jakarta-commons-sandbox/naming/core/src/java/org/apache/commons/naming/resources/ResourceAttributes.java,v 1.2 2003/10/13 08:15:54 rdonkin Exp $
+ * $Revision: 1.2 $
+ * $Date: 2003/10/13 08:15:54 $
+ *
+ * ====================================================================
+ *
+ * The Apache Software License, Version 1.1
+ *
+ * Copyright (c) 1999 The Apache Software Foundation.  All rights 
+ * reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. The end-user documentation included with the redistribution, if
+ *    any, must include the following acknowledgement:
+ *       "This product includes software developed by the 
+ *        Apache Software Foundation (http://www.apache.org/)."
+ *    Alternately, this acknowledgement may appear in the software itself,
+ *    if and wherever such third-party acknowledgements normally appear.
+ *
+ * 4. The names "The Jakarta Project", "Tomcat", and "Apache Software
+ *    Foundation" must not be used to endorse or promote products derived
+ *    from this software without prior written permission. For written 
+ *    permission, please contact apache@apache.org.
+ *
+ * 5. Products derived from this software may not be called "Apache"
+ *    nor may "Apache" appear in their names without prior written
+ *    permission of the Apache Software Foundation.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation.  For more
+ * information on the Apache Software Foundation, please see
+ * <http://www.apache.org/>.
+ *
+ * [Additional notices, if required by prior licensing conditions]
+ *
+ */ 
+
+package org.apache.directory.naming.resources;
+
+import java.util.Hashtable;
+import java.util.Vector;
+import java.util.Enumeration;
+import java.util.Date;
+import java.util.StringTokenizer;
+import java.util.Locale;
+import java.text.SimpleDateFormat;
+import java.text.DateFormat;
+import java.text.ParseException;
+import javax.naming.NamingException;
+import javax.naming.NamingEnumeration;
+import javax.naming.directory.Attributes;
+import javax.naming.directory.BasicAttributes;
+import javax.naming.directory.BasicAttribute;
+import javax.naming.directory.Attribute;
+
+/**
+ * Attributes implementation.
+ * 
+ * @author <a href="mailto:remm@apache.org">Remy Maucherat</a>
+ * @version $Revision: 1.2 $
+ */
+public class ResourceAttributes implements Attributes {
+    
+    
+    // -------------------------------------------------------------- Constants
+    
+    
+    // Default attribute names
+    
+    /**
+     * Creation date.
+     */
+    public static final String CREATION_DATE = "creationdate";
+    
+    
+    /**
+     * Creation date.
+     */
+    public static final String ALTERNATE_CREATION_DATE = "creation-date";
+    
+    
+    /**
+     * Last modification date.
+     */
+    public static final String LAST_MODIFIED = "getlastmodified";
+    
+    
+    /**
+     * Last modification date.
+     */
+    public static final String ALTERNATE_LAST_MODIFIED = "last-modified";
+    
+    
+    /**
+     * Name.
+     */
+    public static final String NAME = "displayname";
+    
+    
+    /**
+     * Type.
+     */
+    public static final String TYPE = "resourcetype";
+    
+    
+    /**
+     * Type.
+     */
+    public static final String ALTERNATE_TYPE = "content-type";
+    
+    
+    /**
+     * Source.
+     */
+    public static final String SOURCE = "source";
+    
+    
+    /**
+     * MIME type of the content.
+     */
+    public static final String CONTENT_TYPE = "getcontenttype";
+    
+    
+    /**
+     * Content language.
+     */
+    public static final String CONTENT_LANGUAGE = "getcontentlanguage";
+    
+    
+    /**
+     * Content length.
+     */
+    public static final String CONTENT_LENGTH = "getcontentlength";
+    
+    
+    /**
+     * Content length.
+     */
+    public static final String ALTERNATE_CONTENT_LENGTH = "content-length";
+    
+    
+    /**
+     * ETag.
+     */
+    public static final String ETAG = "getetag";
+    
+    
+    /**
+     * Collection type.
+     */
+    public static final String COLLECTION_TYPE = "<collection/>";
+    
+    
+    /**
+     * HTTP date format.
+     */
+    protected static final SimpleDateFormat format =
+        new SimpleDateFormat("EEE, dd MMM yyyy HH:mm:ss zzz", Locale.US);
+    
+    
+    /**
+     * Date formats using for Date parsing.
+     */
+    protected static final SimpleDateFormat formats[] = {
+        new SimpleDateFormat("EEE, dd MMM yyyy HH:mm:ss zzz", Locale.US),
+        new SimpleDateFormat("EEE MMM dd HH:mm:ss zzz yyyy", Locale.US),
+        new SimpleDateFormat("EEEEEE, dd-MMM-yy HH:mm:ss zzz", Locale.US),
+        new SimpleDateFormat("EEE MMMM d HH:mm:ss yyyy", Locale.US)
+    };
+    
+    
+    // ----------------------------------------------------------- Constructors
+    
+    
+    /**
+     * Default constructor.
+     */
+    public ResourceAttributes() {
+    }
+    
+    
+    /**
+     * Merges with another attribute set.
+     */
+    public ResourceAttributes(Attributes attributes) {
+        this.attributes = attributes;
+    }
+    
+    
+    // ----------------------------------------------------- Instance Variables
+
+
+    /**
+     * Collection flag.
+     */
+    protected boolean collection = false;
+
+
+    /**
+     * Content length.
+     */
+    protected long contentLength = -1;
+
+
+    /**
+     * Creation time.
+     */
+    protected long creation = -1;
+
+
+    /**
+     * Creation date.
+     */
+    protected Date creationDate = null;
+
+
+    /**
+     * Last modified time.
+     */
+    protected long lastModified = -1;
+
+
+    /**
+     * Last modified date.
+     */
+    protected Date lastModifiedDate = null;
+
+
+    /**
+     * Name.
+     */
+    protected String name = null;
+
+
+    /**
+     * Weak ETag.
+     */
+    protected String weakETag = null;
+
+
+    /**
+     * Strong ETag.
+     */
+    protected String strongETag = null;
+
+
+    /**
+     * External attributes.
+     */
+    protected Attributes attributes = null;
+
+
+    // ------------------------------------------------------------- Properties
+
+
+    /**
+     * Is collection.
+     */
+    public boolean isCollection() {
+        if (attributes != null) {
+            return (getResourceType().equals(COLLECTION_TYPE));
+        } else {
+            return (collection);
+        }
+    }
+    
+    
+    /**
+     * Set collection flag.
+     * 
+     * @return value of the collection flag
+     */
+    public void setCollection(boolean collection) {
+        this.collection = collection;
+        if (attributes != null) {
+            String value = "";
+            if (collection)
+                value = COLLECTION_TYPE;
+            attributes.put(TYPE, value);
+        }
+    }
+    
+    
+    /**
+     * Get content length.
+     * 
+     * @return content length value
+     */
+    public long getContentLength() {
+        if (contentLength != -1L)
+            return contentLength;
+        if (attributes != null) {
+            Attribute attribute = attributes.get(CONTENT_LENGTH);
+            if (attribute != null) {
+                try {
+                    Object value = attribute.get();
+                    if (value instanceof Long) {
+                        contentLength = ((Long) value).longValue();
+                    } else {
+                        try {
+                            contentLength = Long.parseLong(value.toString());
+                        } catch (NumberFormatException e) {
+                            ; // Ignore
+                        }
+                    }
+                } catch (NamingException e) {
+                    ; // No value for the attribute
+                }
+            }
+        }
+        return contentLength;
+    }
+    
+    
+    /**
+     * Set content length.
+     * 
+     * @param contentLength New content length value
+     */
+    public void setContentLength(long contentLength) {
+        this.contentLength = contentLength;
+        if (attributes != null)
+            attributes.put(CONTENT_LENGTH, new Long(contentLength));
+    }
+    
+    
+    /**
+     * Get creation time.
+     * 
+     * @return creation time value
+     */
+    public long getCreation() {
+        if (creation != -1L)
+            return creation;
+        if (creationDate != null)
+            return creationDate.getTime();
+        if (attributes != null) {
+            Attribute attribute = attributes.get(CREATION_DATE);
+            if (attribute != null) {
+                try {
+                    Object value = attribute.get();
+                    if (value instanceof Long) {
+                        creation = ((Long) value).longValue();
+                    } else if (value instanceof Date) {
+                        creation = ((Date) value).getTime();
+                        creationDate = (Date) value;
+                    } else {
+                        String creationDateValue = value.toString();
+                        Date result = null;
+                        // Parsing the HTTP Date
+                        for (int i = 0; (result == null) && 
+                                 (i < formats.length); i++) {
+                            try {
+                                result = formats[i].parse(creationDateValue);
+                            } catch (ParseException e) {
+                                ;
+                            }
+                        }
+                        if (result != null) {
+                            creation = result.getTime();
+                            creationDate = result;
+                        }
+                    }
+                } catch (NamingException e) {
+                    ; // No value for the attribute
+                }
+            }
+        }
+        return creation;
+    }
+    
+    
+    /**
+     * Set creation.
+     * 
+     * @param creation New creation value
+     */
+    public void setCreation(long creation) {
+        this.creation = creation;
+        this.creationDate = null;
+        if (attributes != null)
+            attributes.put(CREATION_DATE, new Date(creation));
+    }
+    
+    
+    /**
+     * Get creation date.
+     * 
+     * @return Creation date value
+     */
+    public Date getCreationDate() {
+        if (creationDate != null)
+            return creationDate;
+        if (creation != -1L) {
+            creationDate = new Date(creation);
+            return creationDate;
+        }
+        if (attributes != null) {
+            Attribute attribute = attributes.get(CREATION_DATE);
+            if (attribute != null) {
+                try {
+                    Object value = attribute.get();
+                    if (value instanceof Long) {
+                        creation = ((Long) value).longValue();
+                        creationDate = new Date(creation);
+                    } else if (value instanceof Date) {
+                        creation = ((Date) value).getTime();
+                        creationDate = (Date) value;
+                    } else {
+                        String creationDateValue = value.toString();
+                        Date result = null;
+                        // Parsing the HTTP Date
+                        for (int i = 0; (result == null) && 
+                                 (i < formats.length); i++) {
+                            try {
+                                result = formats[i].parse(creationDateValue);
+                            } catch (ParseException e) {
+                                ;
+                            }
+                        }
+                        if (result != null) {
+                            creation = result.getTime();
+                            creationDate = result;
+                        }
+                    }
+                } catch (NamingException e) {
+                    ; // No value for the attribute
+                }
+            }
+        }
+        return creationDate;
+    }
+    
+    
+    /**
+     * Creation date mutator.
+     * 
+     * @param creationDate New creation date
+     */
+    public void setCreationDate(Date creationDate) {
+        this.creation = creationDate.getTime();
+        this.creationDate = creationDate;
+        if (attributes != null)
+            attributes.put(CREATION_DATE, creationDate);
+    }
+    
+    
+    /**
+     * Get last modified time.
+     * 
+     * @return lastModified time value
+     */
+    public long getLastModified() {
+        if (lastModified != -1L)
+            return lastModified;
+        if (lastModifiedDate != null)
+            return lastModifiedDate.getTime();
+        if (attributes != null) {
+            Attribute attribute = attributes.get(LAST_MODIFIED);
+            if (attribute != null) {
+                try {
+                    Object value = attribute.get();
+                    if (value instanceof Long) {
+                        lastModified = ((Long) value).longValue();
+                    } else if (value instanceof Date) {
+                        lastModified = ((Date) value).getTime();
+                        lastModifiedDate = (Date) value;
+                    } else {
+                        String lastModifiedDateValue = value.toString();
+                        Date result = null;
+                        // Parsing the HTTP Date
+                        for (int i = 0; (result == null) && 
+                                 (i < formats.length); i++) {
+                            try {
+                                result = 
+                                    formats[i].parse(lastModifiedDateValue);
+                            } catch (ParseException e) {
+                                ;
+                            }
+                        }
+                        if (result != null) {
+                            lastModified = result.getTime();
+                            lastModifiedDate = result;
+                        }
+                    }
+                } catch (NamingException e) {
+                    ; // No value for the attribute
+                }
+            }
+        }
+        return lastModified;
+    }
+    
+    
+    /**
+     * Set last modified.
+     * 
+     * @param lastModified New last modified value
+     */
+    public void setLastModified(long lastModified) {
+        this.lastModified = lastModified;
+        this.lastModifiedDate = null;
+        if (attributes != null)
+            attributes.put(LAST_MODIFIED, new Date(lastModified));
+    }
+    
+    
+    /**
+     * Set last modified date.
+     * 
+     * @param lastModified New last modified date value
+     * @deprecated
+     */
+    public void setLastModified(Date lastModified) {
+        setLastModifiedDate(lastModified);
+    }
+
+
+    /**
+     * Get lastModified date.
+     * 
+     * @return LastModified date value
+     */
+    public Date getLastModifiedDate() {
+        if (lastModifiedDate != null)
+            return lastModifiedDate;
+        if (lastModified != -1L) {
+            lastModifiedDate = new Date(lastModified);
+            return lastModifiedDate;
+        }
+        if (attributes != null) {
+            Attribute attribute = attributes.get(LAST_MODIFIED);
+            if (attribute != null) {
+                try {
+                    Object value = attribute.get();
+                    if (value instanceof Long) {
+                        lastModified = ((Long) value).longValue();
+                        lastModifiedDate = new Date(lastModified);
+                    } else if (value instanceof Date) {
+                        lastModified = ((Date) value).getTime();
+                        lastModifiedDate = (Date) value;
+                    } else {
+                        String lastModifiedDateValue = value.toString();
+                        Date result = null;
+                        // Parsing the HTTP Date
+                        for (int i = 0; (result == null) && 
+                                 (i < formats.length); i++) {
+                            try {
+                                result = 
+                                    formats[i].parse(lastModifiedDateValue);
+                            } catch (ParseException e) {
+                                ;
+                            }
+                        }
+                        if (result != null) {
+                            lastModified = result.getTime();
+                            lastModifiedDate = result;
+                        }
+                    }
+                } catch (NamingException e) {
+                    ; // No value for the attribute
+                }
+            }
+        }
+        return lastModifiedDate;
+    }
+    
+    
+    /**
+     * Last modified date mutator.
+     * 
+     * @param lastModifiedDate New last modified date
+     */
+    public void setLastModifiedDate(Date lastModifiedDate) {
+        this.lastModified = lastModifiedDate.getTime();
+        this.lastModifiedDate = lastModifiedDate;
+        if (attributes != null)
+            attributes.put(LAST_MODIFIED, lastModifiedDate);
+    }
+    
+    
+    /**
+     * Get name.
+     * 
+     * @return Name value
+     */
+    public String getName() {
+        if (name != null)
+            return name;
+        if (attributes != null) {
+            Attribute attribute = attributes.get(NAME);
+            if (attribute != null) {
+                try {
+                    name = attribute.get().toString();
+                } catch (NamingException e) {
+                    ; // No value for the attribute
+                }
+            }
+        }
+        return name;
+    }
+
+
+    /**
+     * Set name.
+     * 
+     * @param name New name value
+     */
+    public void setName(String name) {
+        this.name = name;
+        if (attributes != null)
+            attributes.put(NAME, name);
+    }
+    
+    
+    /**
+     * Get resource type.
+     * 
+     * @return String resource type
+     */
+    public String getResourceType() {
+        String result = null;
+        if (attributes != null) {
+            Attribute attribute = attributes.get(TYPE);
+            if (attribute != null) {
+                try {
+                    result = attribute.get().toString();
+                } catch (NamingException e) {
+                    ; // No value for the attribute
+                }
+            }
+        }
+        if (result == null) {
+            if (collection)
+                result = COLLECTION_TYPE;
+            else
+                result = "";
+        }
+        return result;
+    }
+    
+    
+    /**
+     * Type mutator.
+     * 
+     * @param resourceType New resource type
+     */
+    public void setResourceType(String resourceType) {
+        collection = resourceType.equals(COLLECTION_TYPE);
+        if (attributes != null)
+            attributes.put(TYPE, resourceType);
+    }
+
+
+    /**
+     * Get ETag.
+     * 
+     * @return Weak ETag
+     */
+    public String getETag() {
+        return getETag(false);
+    }
+
+
+    /**
+     * Get ETag.
+     * 
+     * @param strong If true, the strong ETag will be returned
+     * @return ETag
+     */
+    public String getETag(boolean strong) {
+        String result = null;
+        if (attributes != null) {
+            Attribute attribute = attributes.get(ETAG);
+            if (attribute != null) {
+                try {
+                    result = attribute.get().toString();
+                } catch (NamingException e) {
+                    ; // No value for the attribute
+                }
+            }
+        }
+        if (strong) {
+            // The strong ETag must always be calculated by the resources
+            result = strongETag;
+        } else {
+            // The weakETag is contentLenght + lastModified
+            if (weakETag == null) {
+                weakETag = "W/\"" + getContentLength() + "-" 
+                    + getLastModified() + "\"";
+            }
+            result = weakETag;
+        }
+        return result;
+    }
+
+
+    /**
+     * Set strong ETag.
+     */
+    public void setETag(String eTag) {
+        this.strongETag = eTag;
+        if (attributes != null)
+            attributes.put(ETAG, eTag);
+    }
+
+    
+    // ----------------------------------------------------- Attributes Methods
+
+
+    /**
+     * Get attribute.
+     */
+    public Attribute get(String attrID) {
+        if (attributes == null) {
+            if (attrID.equals(CREATION_DATE)) {
+                return new BasicAttribute(CREATION_DATE, getCreationDate());
+            } else if (attrID.equals(ALTERNATE_CREATION_DATE)) {
+                return new BasicAttribute(ALTERNATE_CREATION_DATE, 
+                                          getCreationDate());
+            } else if (attrID.equals(LAST_MODIFIED)) {
+                return new BasicAttribute(LAST_MODIFIED, 
+                                          getLastModifiedDate());
+            } else if (attrID.equals(ALTERNATE_LAST_MODIFIED)) {
+                return new BasicAttribute(ALTERNATE_LAST_MODIFIED,
+                                          getLastModifiedDate());
+            } else if (attrID.equals(NAME)) {
+                return new BasicAttribute(NAME, getName());
+            } else if (attrID.equals(TYPE)) {
+                return new BasicAttribute(TYPE, getResourceType());
+            } else if (attrID.equals(ALTERNATE_TYPE)) {
+                return new BasicAttribute(ALTERNATE_TYPE, getResourceType());
+            } else if (attrID.equals(CONTENT_LENGTH)) {
+                return new BasicAttribute(CONTENT_LENGTH, 
+                                          new Long(getContentLength()));
+            } else if (attrID.equals(ALTERNATE_CONTENT_LENGTH)) {
+                return new BasicAttribute(ALTERNATE_CONTENT_LENGTH, 
+                                          new Long(getContentLength()));
+            }
+        } else {
+            return attributes.get(attrID);
+        }
+        return null;
+    }
+    
+    
+    /**
+     * Put attribute.
+     */
+    public Attribute put(Attribute attribute) {
+        if (attributes == null) {
+            try {
+                return put(attribute.getID(), attribute.get());
+            } catch (NamingException e) {
+                return null;
+            }
+        } else {
+            return attributes.put(attribute);
+        }
+    }
+    
+    
+    /**
+     * Put attribute.
+     */
+    public Attribute put(String attrID, Object val) {
+        if (attributes == null) {
+            return null; // No reason to implement this
+        } else {
+            return attributes.put(attrID, val);
+        }
+    }
+    
+    
+    /**
+     * Remove attribute.
+     */
+    public Attribute remove(String attrID) {
+        if (attributes == null) {
+            return null; // No reason to implement this
+        } else {
+            return attributes.remove(attrID);
+        }
+    }
+    
+    
+    /**
+     * Get all attributes.
+     */
+    public NamingEnumeration getAll() {
+        if (attributes == null) {
+            Vector attributes = new Vector();
+            attributes.addElement(new BasicAttribute
+                                  (CREATION_DATE, getCreationDate()));
+            attributes.addElement(new BasicAttribute
+                                  (LAST_MODIFIED, getLastModifiedDate()));
+            attributes.addElement(new BasicAttribute(NAME, getName()));
+            attributes.addElement(new BasicAttribute(TYPE, getResourceType()));
+            attributes.addElement
+                (new BasicAttribute(CONTENT_LENGTH, 
+                                    new Long(getContentLength())));
+            return new RecyclableNamingEnumeration(attributes);
+        } else {
+            return attributes.getAll();
+        }
+    }
+    
+    
+    /**
+     * Get all attribute IDs.
+     */
+    public NamingEnumeration getIDs() {
+        if (attributes == null) {
+            Vector attributeIDs = new Vector();
+            attributeIDs.addElement(CREATION_DATE);
+            attributeIDs.addElement(LAST_MODIFIED);
+            attributeIDs.addElement(NAME);
+            attributeIDs.addElement(TYPE);
+            attributeIDs.addElement(CONTENT_LENGTH);
+            return new RecyclableNamingEnumeration(attributeIDs);
+        } else {
+            return attributes.getIDs();
+        }
+    }
+    
+    
+    /**
+     * Retrieves the number of attributes in the attribute set.
+     */
+    public int size() {
+        if (attributes == null) {
+            return 5;
+        } else {
+            return attributes.size();
+        }
+    }
+    
+    
+    /**
+     * Clone the attributes object (WARNING: fake cloning).
+     */
+    public Object clone() {
+        return this;
+    }
+    
+    
+    /**
+     * Case sensitivity.
+     */
+    public boolean isCaseIgnored() {
+        return false;
+    }
+    
+    
+}

Added: incubator/directory/naming/trunk/core/src/java/org/apache/directory/naming/resources/WARDirContext.java
==============================================================================
--- (empty file)
+++ incubator/directory/naming/trunk/core/src/java/org/apache/directory/naming/resources/WARDirContext.java	Sun Dec  7 13:00:05 2003
@@ -0,0 +1,1003 @@
+/*
+ * $Header: /home/cvs/jakarta-commons-sandbox/naming/core/src/java/org/apache/commons/naming/resources/WARDirContext.java,v 1.2 2003/10/13 08:15:54 rdonkin Exp $
+ * $Revision: 1.2 $
+ * $Date: 2003/10/13 08:15:54 $
+ *
+ * ====================================================================
+ *
+ * The Apache Software License, Version 1.1
+ *
+ * Copyright (c) 1999 The Apache Software Foundation.  All rights 
+ * reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. The end-user documentation included with the redistribution, if
+ *    any, must include the following acknowledgement:
+ *       "This product includes software developed by the 
+ *        Apache Software Foundation (http://www.apache.org/)."
+ *    Alternately, this acknowledgement may appear in the software itself,
+ *    if and wherever such third-party acknowledgements normally appear.
+ *
+ * 4. The names "The Jakarta Project", "Tomcat", and "Apache Software
+ *    Foundation" must not be used to endorse or promote products derived
+ *    from this software without prior written permission. For written 
+ *    permission, please contact apache@apache.org.
+ *
+ * 5. Products derived from this software may not be called "Apache"
+ *    nor may "Apache" appear in their names without prior written
+ *    permission of the Apache Software Foundation.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation.  For more
+ * information on the Apache Software Foundation, please see
+ * <http://www.apache.org/>.
+ *
+ * [Additional notices, if required by prior licensing conditions]
+ *
+ */ 
+
+
+package org.apache.directory.naming.resources;
+
+import java.util.Arrays;
+import java.util.Hashtable;
+import java.util.Vector;
+import java.util.Date;
+import java.util.Enumeration;
+import java.io.File;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.io.IOException;
+import java.util.zip.ZipEntry;
+import java.util.zip.ZipFile;
+import java.util.zip.ZipException;
+import javax.naming.Context;
+import javax.naming.Name;
+import javax.naming.NameParser;
+import javax.naming.NamingEnumeration;
+import javax.naming.NamingException;
+import javax.naming.CompositeName;
+import javax.naming.NameParser;
+import javax.naming.OperationNotSupportedException;
+import javax.naming.NameAlreadyBoundException;
+import javax.naming.directory.DirContext;
+import javax.naming.directory.Attributes;
+import javax.naming.directory.Attribute;
+import javax.naming.directory.ModificationItem;
+import javax.naming.directory.SearchControls;
+import org.apache.directory.naming.StringManager;
+import org.apache.directory.naming.NameParserImpl;
+import org.apache.directory.naming.NamingEntry;
+import org.apache.directory.naming.NamingContextBindingsEnumeration;
+import org.apache.directory.naming.NamingContextEnumeration;
+
+/**
+ * WAR Directory Context implementation.
+ *
+ * @author Remy Maucherat
+ * @version $Revision: 1.2 $ $Date: 2003/10/13 08:15:54 $
+ */
+
+public class WARDirContext extends BaseDirContext {
+
+
+    // ----------------------------------------------------------- Constructors
+
+
+    /**
+     * Builds a WAR directory context using the given environment.
+     */
+    public WARDirContext() {
+        super();
+    }
+
+
+    /**
+     * Builds a WAR directory context using the given environment.
+     */
+    public WARDirContext(Hashtable env) {
+        super(env);
+    }
+
+
+    /**
+     * Constructor used for returning fake subcontexts.
+     */
+    protected WARDirContext(ZipFile base, Entry entries) {
+        this.base = base;
+        this.entries = entries;
+    }
+
+
+    // ----------------------------------------------------- Instance Variables
+
+
+    /**
+     * The WAR file.
+     */
+    protected ZipFile base = null;
+
+
+    /**
+     * WAR entries.
+     */
+    protected Entry entries = null;
+
+
+    // ------------------------------------------------------------- Properties
+
+
+    /**
+     * Set the document root.
+     * 
+     * @param docBase The new document root
+     * 
+     * @exception IllegalArgumentException if the specified value is not
+     *  supported by this implementation
+     * @exception IllegalArgumentException if this would create a
+     *  malformed URL
+     */
+    public void setDocBase(String docBase) {
+
+	// Validate the format of the proposed document root
+	if (docBase == null)
+	    throw new IllegalArgumentException
+		(sm.getString("resources.null"));
+	if (!(docBase.endsWith(".war")))
+	    throw new IllegalArgumentException
+		(sm.getString("warResources.notWar"));
+
+	// Calculate a File object referencing this document base directory
+	File base = new File(docBase);
+
+	// Validate that the document base is an existing directory
+	if (!base.exists() || !base.canRead() || base.isDirectory())
+	    throw new IllegalArgumentException
+		(sm.getString("warResources.notWar"));
+        try {
+            this.base = new ZipFile(base);
+        } catch (Exception e) {
+	    throw new IllegalArgumentException
+		(sm.getString("warResources.invalidWar", e.getMessage()));
+        }
+        super.setDocBase(docBase);
+
+        loadEntries();
+
+    }
+
+
+    // --------------------------------------------------------- Public Methods
+
+
+    /**
+     * Release any resources allocated for this directory context.
+     */
+    public void release() {
+
+        entries = null;
+        if (base != null) {
+            try {
+                base.close();
+            } catch (IOException e) {
+                System.out.println
+                    ("Exception closing WAR File " + base.getName());
+                e.printStackTrace(System.out);
+            }
+        }
+        base = null;
+        super.release();
+
+    }
+
+
+    // -------------------------------------------------------- Context Methods
+
+
+    /**
+     * 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 {
+        return lookup(new CompositeName(name));
+    }
+
+
+    /**
+     * Retrieves the named object. If name is empty, returns a new instance 
+     * of this context (which represents the same naming context as this 
+     * context, but its environment may be modified independently and it may 
+     * be accessed concurrently).
+     * 
+     * @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(Name name)
+        throws NamingException {
+        if (name.isEmpty())
+            return this;
+        Entry entry = treeLookup(name);
+        if (entry == null)
+            throw new NamingException
+                (sm.getString("resources.notFound", name));
+        ZipEntry zipEntry = entry.getEntry();
+        if (zipEntry.isDirectory())
+            return new WARDirContext(base, entry);
+        else
+            return new WARResource(entry.getEntry());
+    }
+
+
+    /**
+     * Unbinds the named object. Removes the terminal atomic name in name 
+     * from the target context--that named by all but the terminal atomic 
+     * part of name.
+     * <p>
+     * This method is idempotent. It succeeds even if the terminal atomic 
+     * name is not bound in the target context, but throws 
+     * NameNotFoundException if any of the intermediate contexts do not exist. 
+     * 
+     * @param name the name to bind; may not be empty
+     * @exception NameNotFoundException if an intermediate context does not 
+     * exist
+     * @exception NamingException if a naming exception is encountered
+     */
+    public void unbind(String name)
+        throws NamingException {
+        throw new OperationNotSupportedException();
+    }
+
+
+    /**
+     * Binds a new name to the object bound to an old name, and unbinds the 
+     * old name. Both names are relative to this context. Any attributes 
+     * associated with the old name become associated with the new name. 
+     * Intermediate contexts of the old name are not changed.
+     * 
+     * @param oldName the name of the existing binding; may not be empty
+     * @param newName the name of the new binding; may not be empty
+     * @exception NameAlreadyBoundException if newName is already bound
+     * @exception NamingException if a naming exception is encountered
+     */
+    public void rename(String oldName, String newName)
+        throws NamingException {
+        throw new OperationNotSupportedException();
+    }
+
+
+    /**
+     * Enumerates the names bound in the named context, along with the class 
+     * names of objects bound to them. The contents of any subcontexts are 
+     * not included.
+     * <p>
+     * If a binding is added to or removed from this context, its effect on 
+     * an enumeration previously returned is undefined.
+     * 
+     * @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 {
+        return list(new CompositeName(name));
+    }
+
+
+    /**
+     * Enumerates the names bound in the named context, along with the class 
+     * names of objects bound to them. The contents of any subcontexts are 
+     * not included.
+     * <p>
+     * If a binding is added to or removed from this context, its effect on 
+     * an enumeration previously returned is undefined.
+     * 
+     * @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(Name name)
+        throws NamingException {
+        if (name.isEmpty())
+            return new NamingContextEnumeration(list(entries));
+        Entry entry = treeLookup(name);
+        if (entry == null)
+            throw new NamingException
+                (sm.getString("resources.notFound", name));
+        return new NamingContextEnumeration(list(entry));
+    }
+
+
+    /**
+     * Enumerates the names bound in the named context, along with the 
+     * objects bound to them. The contents of any subcontexts are not 
+     * included.
+     * <p>
+     * If a binding is added to or removed from this context, its effect on 
+     * an enumeration previously returned is undefined.
+     * 
+     * @param name the name of the context to list
+     * @return an enumeration of the bindings in this context. 
+     * Each element of the enumeration is of type Binding.
+     * @exception NamingException if a naming exception is encountered
+     */
+    public NamingEnumeration listBindings(String name)
+        throws NamingException {
+        return listBindings(new CompositeName(name));
+    }
+
+
+    /**
+     * Enumerates the names bound in the named context, along with the 
+     * objects bound to them. The contents of any subcontexts are not 
+     * included.
+     * <p>
+     * If a binding is added to or removed from this context, its effect on 
+     * an enumeration previously returned is undefined.
+     * 
+     * @param name the name of the context to list
+     * @return an enumeration of the bindings in this context. 
+     * Each element of the enumeration is of type Binding.
+     * @exception NamingException if a naming exception is encountered
+     */
+    public NamingEnumeration listBindings(Name name)
+        throws NamingException {
+        if (name.isEmpty())
+            return new NamingContextBindingsEnumeration(list(entries));
+        Entry entry = treeLookup(name);
+        if (entry == null)
+            throw new NamingException
+                (sm.getString("resources.notFound", name));
+        return new NamingContextBindingsEnumeration(list(entry));
+    }
+
+
+    /**
+     * Destroys the named context and removes it from the namespace. Any 
+     * attributes associated with the name are also removed. Intermediate 
+     * contexts are not destroyed.
+     * <p>
+     * This method is idempotent. It succeeds even if the terminal atomic 
+     * name is not bound in the target context, but throws 
+     * NameNotFoundException if any of the intermediate contexts do not exist. 
+     * 
+     * In a federated naming system, a context from one naming system may be 
+     * bound to a name in another. One can subsequently look up and perform 
+     * operations on the foreign context using a composite name. However, an 
+     * attempt destroy the context using this composite name will fail with 
+     * NotContextException, because the foreign context is not a "subcontext" 
+     * of the context in which it is bound. Instead, use unbind() to remove 
+     * the binding of the foreign context. Destroying the foreign context 
+     * requires that the destroySubcontext() be performed on a context from 
+     * the foreign context's "native" naming system.
+     * 
+     * @param name the name of the context to be destroyed; may not be empty
+     * @exception NameNotFoundException if an intermediate context does not 
+     * exist
+     * @exception NotContextException if the name is bound but does not name 
+     * a context, or does not name a context of the appropriate type
+     */
+    public void destroySubcontext(String name)
+        throws NamingException {
+        throw new OperationNotSupportedException();
+    }
+
+
+    /**
+     * Retrieves the named object, following links except for the terminal 
+     * atomic component of the name. If the object bound to name is not a 
+     * link, returns the object itself.
+     * 
+     * @param name the name of the object to look up
+     * @return the object bound to name, not following the terminal link 
+     * (if any).
+     * @exception NamingException if a naming exception is encountered
+     */
+    public Object lookupLink(String name)
+        throws NamingException {
+        // Note : Links are not supported
+        return lookup(name);
+    }
+
+
+    /**
+     * Retrieves the full name of this context within its own namespace.
+     * <p>
+     * Many naming services have a notion of a "full name" for objects in 
+     * their respective namespaces. For example, an LDAP entry has a 
+     * distinguished name, and a DNS record has a fully qualified name. This 
+     * method allows the client application to retrieve this name. The string 
+     * returned by this method is not a JNDI composite name and should not be 
+     * passed directly to context methods. In naming systems for which the 
+     * notion of full name does not make sense, 
+     * OperationNotSupportedException is thrown.
+     * 
+     * @return this context's name in its own namespace; never null
+     * @exception OperationNotSupportedException if the naming system does 
+     * not have the notion of a full name
+     * @exception NamingException if a naming exception is encountered
+     */
+    public String getNameInNamespace()
+        throws NamingException {
+        return docBase;
+    }
+
+
+    // ----------------------------------------------------- DirContext Methods
+
+
+    /**
+     * Retrieves selected attributes associated with a named object. 
+     * See the class description regarding attribute models, attribute type 
+     * names, and operational attributes.
+     * 
+     * @return the requested attributes; never null
+     * @param name the name of the object from which to retrieve attributes
+     * @param attrIds the identifiers of the attributes to retrieve. null 
+     * indicates that all attributes should be retrieved; an empty array 
+     * indicates that none should be retrieved
+     * @exception NamingException if a naming exception is encountered
+     */
+    public Attributes getAttributes(String name, String[] attrIds)
+        throws NamingException {
+        return getAttributes(new CompositeName(name), attrIds);
+    }
+
+
+    /**
+     * Retrieves all of the attributes associated with a named object. 
+     * 
+     * @return the set of attributes associated with name. 
+     * Returns an empty attribute set if name has no attributes; never null.
+     * @param name the name of the object from which to retrieve attributes
+     * @exception NamingException if a naming exception is encountered
+     */
+    public Attributes getAttributes(Name name, String[] attrIds)
+        throws NamingException {
+        
+        Entry entry = null;
+        if (name.isEmpty())
+            entry = entries;
+        else
+            entry = treeLookup(name);
+        if (entry == null)
+            throw new NamingException
+                (sm.getString("resources.notFound", name));
+        
+        ZipEntry zipEntry = entry.getEntry();
+
+        ResourceAttributes attrs = new ResourceAttributes();
+        attrs.setCreationDate(new Date(zipEntry.getTime()));
+        attrs.setName(entry.getName());
+        if (!zipEntry.isDirectory())
+            attrs.setResourceType("");
+        attrs.setContentLength(zipEntry.getSize());
+        attrs.setLastModified(new Date(zipEntry.getTime()));
+        
+        return attrs;
+        
+    }
+
+
+    /**
+     * Modifies the attributes associated with a named object. The order of 
+     * the modifications is not specified. Where possible, the modifications 
+     * are performed atomically.
+     * 
+     * @param name the name of the object whose attributes will be updated
+     * @param mod_op the modification operation, one of: ADD_ATTRIBUTE, 
+     * REPLACE_ATTRIBUTE, REMOVE_ATTRIBUTE
+     * @param attrs the attributes to be used for the modification; may not 
+     * be null
+     * @exception AttributeModificationException if the modification cannot be
+     * completed successfully
+     * @exception NamingException if a naming exception is encountered
+     */
+    public void modifyAttributes(String name, int mod_op, Attributes attrs)
+        throws NamingException {
+        throw new OperationNotSupportedException();
+    }
+
+
+    /**
+     * Modifies the attributes associated with a named object using an an 
+     * ordered list of modifications. The modifications are performed in the 
+     * order specified. Each modification specifies a modification operation 
+     * code and an attribute on which to operate. Where possible, the 
+     * modifications are performed atomically.
+     * 
+     * @param name the name of the object whose attributes will be updated
+     * @param mods an ordered sequence of modifications to be performed; may 
+     * not be null
+     * @exception AttributeModificationException if the modification cannot be
+     * completed successfully
+     * @exception NamingException if a naming exception is encountered
+     */
+    public void modifyAttributes(String name, ModificationItem[] mods)
+        throws NamingException {
+        throw new OperationNotSupportedException();
+    }
+
+
+    /**
+     * Binds a name to an object, along with associated attributes. If attrs 
+     * is null, the resulting binding will have the attributes associated 
+     * with obj if obj is a DirContext, and no attributes otherwise. If attrs 
+     * is non-null, the resulting binding will have attrs as its attributes; 
+     * any attributes associated with obj are ignored.
+     * 
+     * @param name the name to bind; may not be empty
+     * @param obj the object to bind; possibly null
+     * @param attrs the attributes to associate with the binding
+     * @exception NameAlreadyBoundException if name is already bound
+     * @exception InvalidAttributesException if some "mandatory" attributes 
+     * of the binding are not supplied
+     * @exception NamingException if a naming exception is encountered
+     */
+    public void bind(String name, Object obj, Attributes attrs)
+        throws NamingException {
+        throw new OperationNotSupportedException();
+    }
+
+
+    /**
+     * Binds a name to an object, along with associated attributes, 
+     * overwriting any existing binding. If attrs is null and obj is a 
+     * DirContext, the attributes from obj are used. If attrs is null and obj 
+     * is not a DirContext, any existing attributes associated with the object
+     * already bound in the directory remain unchanged. If attrs is non-null, 
+     * any existing attributes associated with the object already bound in 
+     * the directory are removed and attrs is associated with the named 
+     * object. If obj is a DirContext and attrs is non-null, the attributes 
+     * of obj are ignored.
+     * 
+     * @param name the name to bind; may not be empty
+     * @param obj the object to bind; possibly null
+     * @param attrs the attributes to associate with the binding
+     * @exception InvalidAttributesException if some "mandatory" attributes 
+     * of the binding are not supplied
+     * @exception NamingException if a naming exception is encountered
+     */
+    public void rebind(String name, Object obj, Attributes attrs)
+        throws NamingException {
+        throw new OperationNotSupportedException();
+    }
+
+
+    /**
+     * Creates and binds a new context, along with associated attributes. 
+     * This method creates a new subcontext with the given name, binds it in 
+     * the target context (that named by all but terminal atomic component of 
+     * the name), and associates the supplied attributes with the newly 
+     * created object. All intermediate and target contexts must already 
+     * exist. If attrs is null, this method is equivalent to 
+     * Context.createSubcontext().
+     * 
+     * @param name the name of the context to create; may not be empty
+     * @param attrs the attributes to associate with the newly created context
+     * @return the newly created context
+     * @exception NameAlreadyBoundException if the name is already bound
+     * @exception InvalidAttributesException if attrs does not contain all 
+     * the mandatory attributes required for creation
+     * @exception NamingException if a naming exception is encountered
+     */
+    public DirContext createSubcontext(String name, Attributes attrs)
+        throws NamingException {
+        throw new OperationNotSupportedException();
+    }
+
+
+    /**
+     * Retrieves the schema associated with the named object. The schema 
+     * describes rules regarding the structure of the namespace and the 
+     * attributes stored within it. The schema specifies what types of 
+     * objects can be added to the directory and where they can be added; 
+     * what mandatory and optional attributes an object can have. The range 
+     * of support for schemas is directory-specific.
+     * 
+     * @param name the name of the object whose schema is to be retrieved
+     * @return the schema associated with the context; never null
+     * @exception OperationNotSupportedException if schema not supported
+     * @exception NamingException if a naming exception is encountered
+     */
+    public DirContext getSchema(String name)
+        throws NamingException {
+        throw new OperationNotSupportedException();
+    }
+
+
+    /**
+     * Retrieves a context containing the schema objects of the named 
+     * object's class definitions.
+     * 
+     * @param name the name of the object whose object class definition is to 
+     * be retrieved
+     * @return the DirContext containing the named object's class 
+     * definitions; never null
+     * @exception OperationNotSupportedException if schema not supported
+     * @exception NamingException if a naming exception is encountered
+     */
+    public DirContext getSchemaClassDefinition(String name)
+        throws NamingException {
+        throw new OperationNotSupportedException();
+    }
+
+
+    /**
+     * Searches in a single context for objects that contain a specified set 
+     * of attributes, and retrieves selected attributes. The search is 
+     * performed using the default SearchControls settings.
+     * 
+     * @param name the name of the context to search
+     * @param matchingAttributes the attributes to search for. If empty or 
+     * null, all objects in the target context are returned.
+     * @param attributesToReturn the attributes to return. null indicates 
+     * that all attributes are to be returned; an empty array indicates that 
+     * none are to be returned.
+     * @return a non-null enumeration of SearchResult objects. Each 
+     * SearchResult contains the attributes identified by attributesToReturn 
+     * and the name of the corresponding object, named relative to the 
+     * context named by name.
+     * @exception NamingException if a naming exception is encountered
+     */
+    public NamingEnumeration search(String name, Attributes matchingAttributes,
+                                    String[] attributesToReturn)
+        throws NamingException {
+        throw new OperationNotSupportedException();
+    }
+
+
+    /**
+     * Searches in a single context for objects that contain a specified set 
+     * of attributes. This method returns all the attributes of such objects. 
+     * It is equivalent to supplying null as the atributesToReturn parameter 
+     * to the method search(Name, Attributes, String[]).
+     * 
+     * @param name the name of the context to search
+     * @param matchingAttributes the attributes to search for. If empty or 
+     * null, all objects in the target context are returned.
+     * @return a non-null enumeration of SearchResult objects. Each 
+     * SearchResult contains the attributes identified by attributesToReturn 
+     * and the name of the corresponding object, named relative to the 
+     * context named by name.
+     * @exception NamingException if a naming exception is encountered
+     */
+    public NamingEnumeration search(String name, Attributes matchingAttributes)
+        throws NamingException {
+        throw new OperationNotSupportedException();
+    }
+
+
+    /**
+     * Searches in the named context or object for entries that satisfy the 
+     * given search filter. Performs the search as specified by the search 
+     * controls.
+     * 
+     * @param name the name of the context or object to search
+     * @param filter the filter expression to use for the search; may not be 
+     * null
+     * @param cons the search controls that control the search. If null, 
+     * the default search controls are used (equivalent to 
+     * (new SearchControls())).
+     * @return an enumeration of SearchResults of the objects that satisfy 
+     * the filter; never null
+     * @exception InvalidSearchFilterException if the search filter specified 
+     * is not supported or understood by the underlying directory
+     * @exception InvalidSearchControlsException if the search controls 
+     * contain invalid settings
+     * @exception NamingException if a naming exception is encountered
+     */
+    public NamingEnumeration search(String name, String filter, 
+                                    SearchControls cons)
+        throws NamingException {
+        throw new OperationNotSupportedException();
+    }
+
+
+    /**
+     * Searches in the named context or object for entries that satisfy the 
+     * given search filter. Performs the search as specified by the search 
+     * controls.
+     * 
+     * @param name the name of the context or object to search
+     * @param filterExpr the filter expression to use for the search. 
+     * The expression may contain variables of the form "{i}" where i is a 
+     * nonnegative integer. May not be null.
+     * @param filterArgs the array of arguments to substitute for the 
+     * variables in filterExpr. The value of filterArgs[i] will replace each 
+     * occurrence of "{i}". If null, equivalent to an empty array.
+     * @param cons the search controls that control the search. If null, the 
+     * default search controls are used (equivalent to (new SearchControls())).
+     * @return an enumeration of SearchResults of the objects that satisy the 
+     * filter; never null
+     * @exception ArrayIndexOutOfBoundsException if filterExpr contains {i} 
+     * expressions where i is outside the bounds of the array filterArgs
+     * @exception InvalidSearchControlsException if cons contains invalid 
+     * settings
+     * @exception InvalidSearchFilterException if filterExpr with filterArgs 
+     * represents an invalid search filter
+     * @exception NamingException if a naming exception is encountered
+     */
+    public NamingEnumeration search(String name, String filterExpr, 
+                                    Object[] filterArgs, SearchControls cons)
+        throws NamingException {
+        throw new OperationNotSupportedException();
+    }
+
+
+    // ------------------------------------------------------ Protected Methods
+
+
+    /**
+     * Normalize the name of an entry read from the Zip.
+     */
+    protected String normalize(ZipEntry entry) {
+
+        String result = "/" + entry.getName();
+        if (entry.isDirectory()) {
+            result = result.substring(0, result.length() - 1);
+        }
+        return result;
+
+    }
+
+
+    /**
+     * Constructs a tree of the entries contained in a WAR file.
+     */
+    protected void loadEntries() {
+
+        try {
+
+            Enumeration entryList = base.entries();
+            entries = new Entry("/", new ZipEntry("/"));
+            
+            while (entryList.hasMoreElements()) {
+                
+                ZipEntry entry = (ZipEntry) entryList.nextElement();
+                String name = normalize(entry);
+                int pos = name.lastIndexOf('/');
+                // Check that parent entries exist and, if not, create them.
+                // This fixes a bug for war files that don't record separate
+                // zip entries for the directories.
+                int currentPos = -1;
+                int lastPos = 0;
+                while ((currentPos = name.indexOf('/', lastPos)) != -1) {
+                    Name parentName = new CompositeName(name.substring(0, lastPos));
+                    Name childName = new CompositeName(name.substring(0, currentPos));
+                    String entryName = name.substring(lastPos, currentPos);
+                    // Parent should have been created in last cycle through
+                    // this loop
+                    Entry parent = treeLookup(parentName);
+                    Entry child = treeLookup(childName);
+                    if (child == null) {
+                        // Create a new entry for missing entry and strip off
+                        // the leading '/' character and appended on by the
+                        // normalize method and add '/' character to end to
+                        // signify that it is a directory entry
+                        String zipName = name.substring(1, currentPos) + "/";
+                        child = new Entry(entryName, new ZipEntry(zipName));
+                        if (parent != null)
+                            parent.addChild(child);
+                    }
+                    // Increment lastPos
+                    lastPos = currentPos + 1;
+                }
+                String entryName = name.substring(pos + 1, name.length());
+                Name compositeName = new CompositeName(name.substring(0, pos));
+                Entry parent = treeLookup(compositeName);
+                Entry child = new Entry(entryName, entry);
+                if (parent != null)
+                    parent.addChild(child);
+                
+            }
+
+        } catch (Exception e) {
+        }
+
+    }
+
+
+    /**
+     * Entry tree lookup.
+     */
+    protected Entry treeLookup(Name name) {
+        if (name.isEmpty())
+            return entries;
+        Entry currentEntry = entries;
+        for (int i = 0; i < name.size(); i++) {
+            if (name.get(i).length() == 0)
+                continue;
+            currentEntry = currentEntry.getChild(name.get(i));
+            if (currentEntry == null)
+                return null;
+        }
+        return currentEntry;
+    }
+
+
+    /**
+     * List children as objects.
+     */
+    protected Vector list(Entry entry) {
+        
+        Vector entries = new Vector();
+        Entry[] children = entry.getChildren();
+        Arrays.sort(children);
+        NamingEntry namingEntry = null;
+        
+        for (int i = 0; i < children.length; i++) {
+            ZipEntry current = children[i].getEntry();
+            Object object = null;
+            if (current.isDirectory()) {
+                object = new WARDirContext(base, children[i]);
+            } else {
+                object = new WARResource(current);
+            }
+            namingEntry = new NamingEntry
+                (children[i].getName(), object, NamingEntry.ENTRY);
+            entries.addElement(namingEntry);
+        }
+        
+        return entries;
+        
+    }
+
+
+    // ---------------------------------------------------- Entries Inner Class
+
+
+    /**
+     * Entries structure.
+     */
+    protected class Entry implements Comparable {
+
+
+        // -------------------------------------------------------- Constructor
+        
+        
+        public Entry(String name, ZipEntry entry) {
+            this.name = name;
+            this.entry = entry;
+        }
+        
+        
+        // --------------------------------------------------- Member Variables
+        
+        
+        protected String name = null;
+        
+        
+        protected ZipEntry entry = null;
+        
+        
+        protected Entry children[] = new Entry[0];
+        
+        
+        // ----------------------------------------------------- Public Methods
+        
+        
+        public int compareTo(Object o) {
+            if (!(o instanceof Entry))
+                return (+1);
+            return (name.compareTo(((Entry) o).getName()));
+        }
+
+        public ZipEntry getEntry() {
+            return entry;
+        }
+        
+        
+        public String getName() {
+            return name;
+        }
+        
+        
+        public void addChild(Entry entry) {
+            Entry[] newChildren = new Entry[children.length + 1];
+            for (int i = 0; i < children.length; i++)
+                newChildren[i] = children[i];
+            newChildren[children.length] = entry;
+            children = newChildren;
+        }
+
+
+        public Entry[] getChildren() {
+            return children;
+        }
+
+
+        public Entry getChild(String name) {
+            for (int i = 0; i < children.length; i++) {
+                if (children[i].name.equals(name)) {
+                    return children[i];
+                }
+            }
+            return null;
+        }
+
+
+    }
+
+
+    // ------------------------------------------------ WARResource Inner Class
+
+
+    /**
+     * This specialized resource implementation avoids opening the IputStream
+     * to the WAR right away.
+     */
+    protected class WARResource extends Resource {
+        
+        
+        // -------------------------------------------------------- Constructor
+        
+        
+        public WARResource(ZipEntry entry) {
+            this.entry = entry;
+        }
+        
+        
+        // --------------------------------------------------- Member Variables
+        
+        
+        protected ZipEntry entry;
+        
+        
+        // ----------------------------------------------------- Public Methods
+        
+        
+        /**
+         * Content accessor.
+         * 
+         * @return InputStream
+         */
+        public InputStream streamContent()
+            throws IOException {
+            try {
+                if (binaryContent == null) {
+                    inputStream = base.getInputStream(entry);
+                }
+            } catch (ZipException e) {
+                throw new IOException(e.getMessage());
+            }
+            return super.streamContent();
+        }
+        
+        
+    }
+
+
+}
+

Added: incubator/directory/naming/trunk/core/src/java/org/apache/directory/naming/resources/jndi/Handler.java
==============================================================================
--- (empty file)
+++ incubator/directory/naming/trunk/core/src/java/org/apache/directory/naming/resources/jndi/Handler.java	Sun Dec  7 13:00:05 2003
@@ -0,0 +1,93 @@
+/*
+ * $Header: /home/cvs/jakarta-commons-sandbox/naming/core/src/java/org/apache/commons/naming/resources/jndi/Handler.java,v 1.2 2003/10/13 08:15:54 rdonkin Exp $
+ * $Revision: 1.2 $
+ * $Date: 2003/10/13 08:15:54 $
+ *
+ * ====================================================================
+ *
+ * The Apache Software License, Version 1.1
+ *
+ * Copyright (c) 1999 The Apache Software Foundation.  All rights 
+ * reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. The end-user documentation included with the redistribution, if
+ *    any, must include the following acknowledgement:
+ *       "This product includes software developed by the 
+ *        Apache Software Foundation (http://www.apache.org/)."
+ *    Alternately, this acknowledgement may appear in the software itself,
+ *    if and wherever such third-party acknowledgements normally appear.
+ *
+ * 4. The names "The Jakarta Project", "Tomcat", and "Apache Software
+ *    Foundation" must not be used to endorse or promote products derived
+ *    from this software without prior written permission. For written 
+ *    permission, please contact apache@apache.org.
+ *
+ * 5. Products derived from this software may not be called "Apache"
+ *    nor may "Apache" appear in their names without prior written
+ *    permission of the Apache Software Foundation.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation.  For more
+ * information on the Apache Software Foundation, please see
+ * <http://www.apache.org/>.
+ *
+ * [Additional notices, if required by prior licensing conditions]
+ *
+ */ 
+
+package org.apache.directory.naming.resources.jndi;
+
+import java.net.URL;
+import java.net.URLConnection;
+import java.net.URLStreamHandler;
+import java.io.IOException;
+import java.util.Hashtable;
+import javax.naming.NamingException;
+import javax.naming.directory.DirContext;
+
+import org.apache.directory.naming.resources.DirContextURLStreamHandler;
+
+/**
+ * Stream handler to a JNDI directory context.
+ * 
+ * @author <a href="mailto:remm@apache.org">Remy Maucherat</a>
+ * @version $Revision: 1.2 $
+ */
+public class Handler 
+    extends DirContextURLStreamHandler {
+    
+    
+    // ----------------------------------------------------------- Constructors
+    
+    
+    public Handler() {
+    }
+    
+    
+}

Added: incubator/directory/naming/trunk/core/src/test/org/apache/directory/naming/BasicContextTest.java
==============================================================================
--- (empty file)
+++ incubator/directory/naming/trunk/core/src/test/org/apache/directory/naming/BasicContextTest.java	Sun Dec  7 13:00:05 2003
@@ -0,0 +1,235 @@
+/* ====================================================================
+ * The Apache Software License, Version 1.1
+ *
+ * Copyright (c) 2003 The Apache Software Foundation.  All rights
+ * reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. The end-user documentation included with the redistribution,
+ *    if any, must include the following acknowledgment:
+ *       "This product includes software developed by the
+ *        Apache Software Foundation (http://www.apache.org/)."
+ *    Alternately, this acknowledgment may appear in the software itself,
+ *    if and wherever such third-party acknowledgments normally appear.
+ *
+ * 4. The names "Apache" and "Apache Software Foundation" and
+ *    "Apache Geronimo" must not be used to endorse or promote products
+ *    derived from this software without prior written permission. For
+ *    written permission, please contact apache@apache.org.
+ *
+ * 5. Products derived from this software may not be called "Apache",
+ *    "Apache Geronimo", nor may "Apache" appear in their name, without
+ *    prior written permission of the Apache Software Foundation.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation.  For more
+ * information on the Apache Software Foundation, please see
+ * <http://www.apache.org/>.
+ *
+ * ====================================================================
+ */
+package org.apache.directory.naming;
+
+import java.util.HashMap;
+import java.util.Hashtable;
+import java.util.Iterator;
+import java.util.Enumeration;
+import java.util.Map;
+import java.util.Properties;
+import java.util.NoSuchElementException;
+
+import javax.naming.Binding;
+import javax.naming.CompositeName;
+import javax.naming.CompoundName;
+import javax.naming.Context;
+import javax.naming.InitialContext;
+import javax.naming.NameClassPair;
+import javax.naming.NamingEnumeration;
+import javax.naming.NamingException;
+import javax.naming.Name;
+
+import junit.framework.Test;
+import junit.framework.TestCase;
+import junit.framework.TestSuite;
+import junit.textui.TestRunner;
+
+import org.apache.directory.naming.java.javaURLContextFactory;
+
+/**
+ * Unit tests for basic ops on an {@link NamingContext}.
+ * Adapted from o.a.geronimo.naming test of the same name
+ *  
+ * @version $Revision: 1.2 $ $Date: 2003/11/30 05:36:07 $
+ */
+public class BasicContextTest extends TestCase {
+    private HashMap envBinding;
+    private Context initialContext;
+    private Context compContext;
+    private Context envContext;
+    
+    public BasicContextTest(String name) {
+        super(name);
+    }
+
+    public static void main(String[] args) {
+        TestRunner.run(suite());
+    }
+
+    public static Test suite() {
+    	TestSuite suite = new TestSuite(BasicContextTest.class);
+    	suite.setName("Basic Context Tests");
+        return suite;
+    }
+    
+    protected void setUp() throws Exception {
+        super.setUp();
+        Hashtable env = new Hashtable();
+        envBinding = new HashMap();
+        env.put(Context.INITIAL_CONTEXT_FACTORY,
+            "org.apache.directory.naming.java.javaURLContextFactory");
+        env.put(Context.URL_PKG_PREFIXES,"org.apache.directory.naming");
+        initialContext = new InitialContext(env);
+        compContext = initialContext.createSubcontext("java:comp");
+        envContext =  compContext.createSubcontext("env");
+        envContext.bind("hello", "Hello");
+        envContext.bind("world", "World");
+        envBinding.put("hello", "Hello");
+        envBinding.put("world", "World");
+        ContextAccessController.setReadOnly(javaURLContextFactory.MAIN);
+        ContextAccessController.setSecurityToken(javaURLContextFactory.MAIN,"x");
+    }
+    
+    protected void tearDown() throws Exception {
+        ContextAccessController.setWritable(javaURLContextFactory.MAIN,"x");
+        compContext.destroySubcontext("env");
+        initialContext.destroySubcontext("java:comp");
+        initialContext = null;
+    }
+
+    public void testInitialContext() throws NamingException {
+        assertEquals("Hello", initialContext.lookup("java:comp/env/hello"));
+        assertEquals("World", initialContext.lookup(new CompositeName("java:comp/env/world")));
+        assertEquals(envContext.lookup("hello"), 
+            ((Context) envContext.lookup("")).lookup("hello"));  
+    }
+
+    public void testLookup() throws NamingException {
+        assertEquals("Hello", envContext.lookup("hello"));
+        assertEquals("Hello", compContext.lookup("env/hello"));
+        try {
+            envContext.lookup("foo");
+            fail("expecting NamingException");
+        } catch (NamingException e) {
+            // OK
+        }
+        assertEquals("Hello", envContext.lookup(new CompositeName("hello")));
+        assertEquals("Hello", compContext.lookup(new CompositeName("env/hello")));
+        assertEquals("World", 
+            ((Context) initialContext.lookup("java:comp")).lookup("env/world"));
+    }
+    
+
+    public void testComposeName() throws NamingException {
+        assertEquals("org/research/user/jane", 
+            envContext.composeName("user/jane", "org/research"));
+        assertEquals("research/user/jane", 
+            envContext.composeName("user/jane", "research"));
+        assertEquals(new CompositeName("org/research/user/jane"), 
+            envContext.composeName(new CompositeName("user/jane"), 
+                new CompositeName("org/research")));
+        assertEquals(new CompositeName("research/user/jane"), 
+            envContext.composeName(new CompositeName("user/jane"), 
+                new CompositeName("research")));
+    }
+
+    public void testList() throws NamingException {
+        NamingEnumeration enum;
+        Map expected;
+        Map result;
+
+        expected = new HashMap();
+        for (Iterator i = envBinding.entrySet().iterator(); i.hasNext();) {
+            Map.Entry entry = (Map.Entry) i.next();
+            expected.put(entry.getKey(), entry.getValue().getClass().getName());
+        }
+        enum = envContext.list("");
+        result = new HashMap();
+        while (enum.hasMore()) {
+            NameClassPair pair = (NameClassPair) enum.next();
+            result.put(pair.getName(), pair.getClassName());
+        }
+        assertEquals(expected, result);
+
+        try {
+            enum.next();
+            fail();
+        } catch (NoSuchElementException e) {
+            // ok
+        }
+        try {
+            enum.nextElement();
+            fail();
+        } catch (NoSuchElementException e) {
+            // ok
+        }
+    }
+
+    public void testListBindings() throws NamingException {
+        NamingEnumeration enum;
+        Map result;
+        enum = envContext.listBindings("");
+        result = new HashMap();
+        while (enum.hasMore()) {
+            Binding pair = (Binding) enum.next();
+            result.put(pair.getName(), pair.getObject());
+        }
+        assertEquals(envBinding, result);
+
+        try {
+            enum.next();
+            fail();
+        } catch (NoSuchElementException e) {
+            // ok
+        }
+        try {
+            enum.nextElement();
+            fail();
+        } catch (NoSuchElementException e) {
+            // ok
+        }
+    }
+    
+    public void testAccess() throws NamingException {
+        try {
+            envContext.bind("goodbye", "Goodbye");
+            fail("expecting NamingException"); // Context is read only
+        } catch (NamingException ex) {}   
+        ContextAccessController.setWritable(javaURLContextFactory.MAIN,"x");
+        envContext.bind("goodbye", "Goodbye"); // Unlocked now
+    }  
+}

Added: incubator/directory/naming/trunk/core/src/test/org/apache/directory/naming/LocalStrings.properties
==============================================================================
--- (empty file)
+++ incubator/directory/naming/trunk/core/src/test/org/apache/directory/naming/LocalStrings.properties	Sun Dec  7 13:00:05 2003
@@ -0,0 +1,10 @@
+contextBindings.unknownContext=Unknown context name : {0}
+contextBindings.noContextBoundToThread=No naming context bound to this thread
+contextBindings.noContextBoundToCL=No naming context bound to this class loader
+selectorContext.noJavaUrl=This context must be accessed throught a java: URL
+namingContext.contextExpected=Name is not bound to a Context
+namingContext.nameNotBound=Name {0} is not bound in this Context
+namingContext.readOnly=Context is read only
+namingContext.invalidName=Name is not valid
+namingContext.alreadyBound=Name {0} is already bound in this Context
+namingContext.noAbsoluteName=Can't generate an absolute name for this namespace
\ No newline at end of file

Added: incubator/directory/naming/trunk/core/src/test/org/apache/directory/naming/LocalStrings_es.properties
==============================================================================
--- (empty file)
+++ incubator/directory/naming/trunk/core/src/test/org/apache/directory/naming/LocalStrings_es.properties	Sun Dec  7 13:00:05 2003
@@ -0,0 +1,16 @@
+# $Id: LocalStrings_es.properties,v 1.1 2003/09/02 04:43:37 psteitz Exp $
+
+# language es
+
+# package org.apache.naming
+
+
+contextBindings.unknownContext=Contexto {0} desconocido 
+contextBindings.noContextBoundToThread=No hay contexto de nombres asociado a este hilo
+selectorContext.noJavaUrl=Este contexto debe de ser accedido a traves de una URL de tipo java:
+namingContext.contextExpected=El nombre no esta asociado a ningun Contexto
+namingContext.nameNotBound=El nombre {0} no este asociado a este contexto
+namingContext.readOnly=El contexto es de solo lectura
+namingContext.invalidName=Nombre no valido
+namingContext.noAbsoluteName=No se puede generar un nombre absoluto para este espacio de nombres
+namingContext.alreadyBound=El nombre {0} este ya asociado en este Contexto

Added: incubator/directory/naming/trunk/core/src/test/org/apache/directory/naming/LocalStrings_fr.properties
==============================================================================
--- (empty file)
+++ incubator/directory/naming/trunk/core/src/test/org/apache/directory/naming/LocalStrings_fr.properties	Sun Dec  7 13:00:05 2003
@@ -0,0 +1,10 @@
+contextBindings.unknownContext=Nom de Contexte inconnu : {0}
+contextBindings.noContextBoundToThread=Aucun Contexte de nommage li� � ce thread
+contextBindings.noContextBoundToCL=Aucun Contexte de nommage li� � ce chargeur de classes
+selectorContext.noJavaUrl=Ce Contexte doit �tre acc�d� par une java: URL
+namingContext.contextExpected=Le Nom n''est pas li� � un Contexte
+namingContext.nameNotBound=Le Nom {0} n''est pas li� � ce Contexte
+namingContext.readOnly=Le Contexte est en lecture seule
+namingContext.invalidName=Le Nom est invalide
+namingContext.alreadyBound=Le Nom {0} est d�j� li� � ce Contexte
+namingContext.noAbsoluteName=Impossible de g�n�rer un nom absolu pour cet espace de nommage (namespace)
\ No newline at end of file

Added: incubator/directory/naming/trunk/core/src/test/org/apache/directory/naming/LocalStrings_ja.properties
==============================================================================
--- (empty file)
+++ incubator/directory/naming/trunk/core/src/test/org/apache/directory/naming/LocalStrings_ja.properties	Sun Dec  7 13:00:05 2003
@@ -0,0 +1,10 @@
+contextBindings.unknownContext=\u672a\u77e5\u306e\u30b3\u30f3\u30c6\u30ad\u30b9\u30c8\u540d\u3067\u3059: {0}
+contextBindings.noContextBoundToThread=\u540d\u524d\u4ed8\u3051\u30b3\u30f3\u30c6\u30ad\u30b9\u30c8\u306f\u3053\u306e\u30b9\u30ec\u30c3\u30c9\u306b\u306f\u30d0\u30a4\u30f3\u30c9\u3055\u308c\u3066\u3044\u307e\u305b\u3093
+contextBindings.noContextBoundToCL=\u540d\u524d\u4ed8\u3051\u30b3\u30f3\u30c6\u30ad\u30b9\u30c8\u306f\u3053\u306e\u30af\u30e9\u30b9\u30ed\u30fc\u30c0\u306b\u306f\u30d0\u30a4\u30f3\u30c9\u3055\u308c\u3066\u3044\u307e\u305b\u3093
+selectorContext.noJavaUrl=\u3053\u306e\u30b3\u30f3\u30c6\u30ad\u30b9\u30c8\u306b\u306fjava: URL\u3092\u7528\u3044\u3066\u30a2\u30af\u30bb\u30b9\u3055\u308c\u306d\u3070\u3044\u3051\u307e\u305b\u3093
+namingContext.contextExpected=\u540d\u524d\u304c\u30b3\u30f3\u30c6\u30ad\u30b9\u30c8\u306b\u30d0\u30a4\u30f3\u30c9\u3055\u308c\u3066\u3044\u307e\u305b\u3093
+namingContext.nameNotBound=\u540d\u524d {0} \u306f\u3053\u306e\u30b3\u30f3\u30c6\u30ad\u30b9\u30c8\u306b\u30d0\u30a4\u30f3\u30c9\u3055\u308c\u3066\u3044\u307e\u305b\u3093
+namingContext.readOnly=\u30b3\u30f3\u30c6\u30ad\u30b9\u30c8\u306f\u30ea\u30fc\u30c9\u30aa\u30f3\u30ea\u30fc\u3067\u3059
+namingContext.invalidName=\u540d\u524d\u306f\u7121\u52b9\u3067\u3059
+namingContext.alreadyBound=\u540d\u524d {0} \u306f\u3059\u3067\u306b\u3053\u306e\u30b3\u30f3\u30c6\u30ad\u30b9\u30c8\u306b\u30d0\u30a4\u30f3\u30c9\u3055\u308c\u3066\u3044\u307e\u3059
+namingContext.noAbsoluteName=\u3053\u306e\u540d\u524d\u7a7a\u9593\u306b\u7d76\u5bfe\u540d\u3092\u751f\u6210\u3067\u304d\u307e\u305b\u3093

Added: incubator/directory/naming/trunk/factory/project.properties
==============================================================================
--- (empty file)
+++ incubator/directory/naming/trunk/factory/project.properties	Sun Dec  7 13:00:05 2003
@@ -0,0 +1,3 @@
+maven.checkstyle.properties=${basedir}/../checkstyle.xml
+maven.checkstyle.header.file=${basedir}/../LICENSE.txt
+maven.multiproject.type=jar

Added: incubator/directory/naming/trunk/factory/project.xml
==============================================================================
--- (empty file)
+++ incubator/directory/naming/trunk/factory/project.xml	Sun Dec  7 13:00:05 2003
@@ -0,0 +1,77 @@
+<?xml version="1.0"?>
+<project>
+   <extend>${basedir}/../project.xml</extend>  
+   <id>commons-naming-factory</id>
+   <name>Naming Factories</name>
+
+   <dependencies>
+   
+     <!-- Compile time dependencies -->
+    <dependency>
+      <groupId>${pom.groupId}</groupId>
+      <artifactId>commons-naming-core</artifactId>
+      <version>${pom.currentVersion}</version>
+    </dependency>
+       
+    <dependency>
+      <id>jta-spec</id>
+      <version>1.0.1</version>
+    </dependency>
+
+    <dependency>
+      <id>javamail</id>
+      <version>1.2</version>
+    </dependency>
+
+    <dependency>
+      <id>tyrex</id>
+      <version>1.0</version>
+    </dependency>
+           
+     <dependency>
+       <groupId>commons-logging</groupId>
+       <artifactId>commons-logging</artifactId>
+       <version>1.0.3</version>
+     </dependency>
+
+     <dependency>
+       <groupId>commons-lang</groupId>
+       <artifactId>commons-lang</artifactId>
+       <version>1.0.1</version>
+     </dependency>
+
+     <dependency>
+       <groupId>commons-digester</groupId>
+       <artifactId>commons-digester</artifactId>
+       <version>1.4.1</version>
+     </dependency>
+
+     <!-- Runtime dependencies - Digester -->
+     <dependency>
+       <groupId>commons-beanutils</groupId>
+       <artifactId>commons-beanutils</artifactId>
+       <version>1.6.1</version>
+     </dependency>
+
+     <!-- Runtime dependencies - DBCP factories -->
+     <dependency>
+       <groupId>commons-dbcp</groupId>
+       <artifactId>commons-dbcp</artifactId>
+       <version>1.0</version>
+     </dependency>
+
+     <dependency>
+       <groupId>commons-pool</groupId>
+       <artifactId>commons-pool</artifactId>
+       <version>1.0.1</version>
+     </dependency>
+
+     <!-- Test dependencies - used to test database connection factories -->
+     <dependency>
+       <groupId>hsqldb</groupId>
+       <artifactId>hsqldb</artifactId>
+       <version>1.7.1</version>
+     </dependency>
+   </dependencies>
+</project>
+

Added: incubator/directory/naming/trunk/factory/src/java/org/apache/directory/naming/config/Config.java
==============================================================================
--- (empty file)
+++ incubator/directory/naming/trunk/factory/src/java/org/apache/directory/naming/config/Config.java	Sun Dec  7 13:00:05 2003
@@ -0,0 +1,323 @@
+/*
+ * $Header: /home/cvs/jakarta-commons-sandbox/naming/factory/src/java/org/apache/commons/naming/config/Config.java,v 1.2 2003/12/01 02:02:45 brett Exp $
+ * $Revision: 1.2 $
+ * $Date: 2003/12/01 02:02:45 $
+ *
+ * ====================================================================
+ *
+ * The Apache Software License, Version 1.1
+ *
+ * Copyright (c) 1999 The Apache Software Foundation.  All rights 
+ * reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. The end-user documentation included with the redistribution, if
+ *    any, must include the following acknowlegement:  
+ *       "This product includes software developed by the 
+ *        Apache Software Foundation (http://www.apache.org/)."
+ *    Alternately, this acknowlegement may appear in the software itself,
+ *    if and wherever such third-party acknowlegements normally appear.
+ *
+ * 4. The names "The Jakarta Project", "Tomcat", and "Apache Software
+ *    Foundation" must not be used to endorse or promote products derived
+ *    from this software without prior written permission. For written 
+ *    permission, please contact apache@apache.org.
+ *
+ * 5. Products derived from this software may not be called "Apache"
+ *    nor may "Apache" appear in their names without prior written
+ *    permission of the Apache Group.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation.  For more
+ * information on the Apache Software Foundation, please see
+ * <http://www.apache.org/>.
+ *
+ * [Additional notices, if required by prior licensing conditions]
+ *
+ */ 
+
+package org.apache.directory.naming.config;
+
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.LinkedList;
+import java.util.Map;
+import java.util.Set;
+import java.util.TreeSet;
+
+import javax.naming.CompositeName;
+import javax.naming.InvalidNameException;
+import javax.naming.StringRefAddr;
+
+import org.apache.commons.lang.builder.ToStringBuilder;
+import org.apache.commons.lang.builder.ToStringStyle;
+import org.apache.directory.naming.ResourceRef;
+
+/**
+ * Configuration classes. 
+ * 
+ * @author <a href="brett@apache.org">Brett Porter</a>
+ * @version $Id: Config.java,v 1.2 2003/12/01 02:02:45 brett Exp $
+ */
+public final class Config
+{
+    public static final class Naming
+    {
+        private final Collection contextList = new LinkedList();
+
+        public void addContext(Context context)
+        {
+            contextList.add(context);
+        }
+        /**
+         * @return
+         */
+        public Collection getContextList()
+        {
+            return Collections.unmodifiableCollection(contextList);
+        }
+
+        public Set generateSortedSubcontextNameSet() throws InvalidNameException
+        {
+            Set sortedSubcontextNameSet = new TreeSet();
+            for (Iterator i = contextList.iterator(); i.hasNext();)
+            {
+                Context context = (Context) i.next();
+                context.addSubContextNames(sortedSubcontextNameSet);
+            }
+            return Collections.unmodifiableSet(sortedSubcontextNameSet);
+        }
+
+        public String toString()
+        {
+            return new ToStringBuilder(this, ToStringStyle.MULTI_LINE_STYLE)
+                .append("contextList", contextList)
+                .toString();
+        }
+    }
+
+    public static final class Context
+    {
+        private String name;
+        private final Collection environmentList = new LinkedList();
+        private final Collection resourceList = new LinkedList();
+
+        public void addEnvironment(Environment environment)
+        {
+            environmentList.add(environment);
+        }
+
+        /**
+         * @param sortedSubcontextNameSet
+         */
+        public void addSubContextNames(Set sortedSubcontextNameSet) throws InvalidNameException
+        {
+            if (name != null)
+            {
+                sortedSubcontextNameSet.add(name);
+            }
+            for (Iterator i = environmentList.iterator(); i.hasNext();)
+            {
+                Environment e = (Environment) i.next();
+                CompositeName name = new CompositeName(e.getName());
+                addSubContextNames(name, sortedSubcontextNameSet);
+            }
+            for (Iterator i = resourceList.iterator(); i.hasNext();)
+            {
+                Resource r = (Resource) i.next();
+                CompositeName name = new CompositeName(r.getName());
+                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());
+            }
+        }
+
+        public void addResource(Resource resource)
+        {
+            resourceList.add(resource);
+        }
+        public Collection getEnvironmentList()
+        {
+            return Collections.unmodifiableCollection(environmentList);
+        }
+
+        public String getName()
+        {
+            return name;
+        }
+
+        public void setName(String name)
+        {
+            this.name = name;
+        }
+
+        public Collection getResourceList()
+        {
+            return Collections.unmodifiableCollection(resourceList);
+        }
+
+        public String toString()
+        {
+            return new ToStringBuilder(this, ToStringStyle.MULTI_LINE_STYLE)
+                .append("name", name)
+                .append("environmentList", environmentList)
+                .append("resourceList", resourceList)
+                .toString();
+        }
+    }
+
+    public static final class Environment
+    {
+        private String name;
+        private String value;
+        private String type;
+        public String getName()
+        {
+            return name;
+        }
+
+        public void setName(String name)
+        {
+            this.name = name;
+        }
+
+        public String getType()
+        {
+            return type;
+        }
+
+        public void setType(String type)
+        {
+            this.type = type;
+        }
+
+        public String getValue()
+        {
+            return value;
+        }
+
+        public void setValue(String value)
+        {
+            this.value = value;
+        }
+
+        public String toString()
+        {
+            return new ToStringBuilder(this, ToStringStyle.MULTI_LINE_STYLE)
+                .append("name", name)
+                .append("type", type)
+                .append("value", value)
+                .toString();
+        }
+
+        /**
+         * @todo finish types, throw exceptions
+         * @return
+         */
+        public Object createValue()
+        {
+            if (type.equals(String.class.getName()))
+            {
+                return value;
+            }
+            else if (type.equals(Integer.class.getName()))
+            {
+                return Integer.valueOf(value);
+            }
+            return null;
+        }
+    }
+
+    public static final class Resource
+    {
+        private String name;
+        private String type;
+        private final Map parameters = new HashMap();
+
+        public void addParameter(String name, String value)
+        {
+            parameters.put(name, value);
+        }
+        public String getName()
+        {
+            return name;
+        }
+
+        public void setName(String name)
+        {
+            this.name = name;
+        }
+
+        public Map getParameters()
+        {
+            return parameters;
+        }
+
+        public String getType()
+        {
+            return type;
+        }
+
+        public void setType(String type)
+        {
+            this.type = type;
+        }
+
+        /**
+         * @todo finish types, throw exceptions
+         * @return
+         */
+        public Object createValue()
+        {
+            ResourceRef ref = new ResourceRef(type, null, null, null);
+            for (Iterator i = parameters.keySet().iterator(); i.hasNext();)
+            {
+                String name = (String) i.next();
+                String value = (String) parameters.get(name);
+                ref.add(new StringRefAddr(name, value));
+            }
+            return ref;
+        }
+
+        public String toString()
+        {
+            return new ToStringBuilder(this, ToStringStyle.MULTI_LINE_STYLE)
+                .append("name", name)
+                .append("type", type)
+                .append("parameters", parameters)
+                .toString();
+        }
+    }
+}
+

Added: incubator/directory/naming/trunk/factory/src/java/org/apache/directory/naming/config/ParseException.java
==============================================================================
--- (empty file)
+++ incubator/directory/naming/trunk/factory/src/java/org/apache/directory/naming/config/ParseException.java	Sun Dec  7 13:00:05 2003
@@ -0,0 +1,82 @@
+/*
+ * $Header: /home/cvs/jakarta-commons-sandbox/naming/factory/src/java/org/apache/commons/naming/config/ParseException.java,v 1.1 2003/11/14 20:43:26 brett Exp $
+ * $Revision: 1.1 $
+ * $Date: 2003/11/14 20:43:26 $
+ *
+ * ====================================================================
+ *
+ * The Apache Software License, Version 1.1
+ *
+ * Copyright (c) 1999 The Apache Software Foundation.  All rights 
+ * reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. The end-user documentation included with the redistribution, if
+ *    any, must include the following acknowlegement:  
+ *       "This product includes software developed by the 
+ *        Apache Software Foundation (http://www.apache.org/)."
+ *    Alternately, this acknowlegement may appear in the software itself,
+ *    if and wherever such third-party acknowlegements normally appear.
+ *
+ * 4. The names "The Jakarta Project", "Tomcat", and "Apache Software
+ *    Foundation" must not be used to endorse or promote products derived
+ *    from this software without prior written permission. For written 
+ *    permission, please contact apache@apache.org.
+ *
+ * 5. Products derived from this software may not be called "Apache"
+ *    nor may "Apache" appear in their names without prior written
+ *    permission of the Apache Group.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation.  For more
+ * information on the Apache Software Foundation, please see
+ * <http://www.apache.org/>.
+ *
+ * [Additional notices, if required by prior licensing conditions]
+ *
+ */ 
+
+
+package org.apache.directory.naming.config;
+
+/**
+ * Exception during reading of an XML configuration file.
+ * 
+ * @author <a href="brett@apache.org">Brett Porter</a>
+ * @version $Id: ParseException.java,v 1.1 2003/11/14 20:43:26 brett Exp $
+ */
+public class ParseException extends Exception
+{
+    ParseException(String msg) {
+        super(msg);
+    }
+
+    ParseException(String msg, Throwable cause) {
+        super(msg, cause);
+    }
+}

Added: incubator/directory/naming/trunk/factory/src/java/org/apache/directory/naming/config/XmlConfigurator.java
==============================================================================
--- (empty file)
+++ incubator/directory/naming/trunk/factory/src/java/org/apache/directory/naming/config/XmlConfigurator.java	Sun Dec  7 13:00:05 2003
@@ -0,0 +1,196 @@
+/*
+ * $Header: /home/cvs/jakarta-commons-sandbox/naming/factory/src/java/org/apache/commons/naming/config/XmlConfigurator.java,v 1.2 2003/12/01 02:02:45 brett Exp $
+ * $Revision: 1.2 $
+ * $Date: 2003/12/01 02:02:45 $
+ *
+ * ====================================================================
+ *
+ * The Apache Software License, Version 1.1
+ *
+ * Copyright (c) 1999 The Apache Software Foundation.  All rights 
+ * reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. The end-user documentation included with the redistribution, if
+ *    any, must include the following acknowlegement:  
+ *       "This product includes software developed by the 
+ *        Apache Software Foundation (http://www.apache.org/)."
+ *    Alternately, this acknowlegement may appear in the software itself,
+ *    if and wherever such third-party acknowlegements normally appear.
+ *
+ * 4. The names "The Jakarta Project", "Tomcat", and "Apache Software
+ *    Foundation" must not be used to endorse or promote products derived
+ *    from this software without prior written permission. For written 
+ *    permission, please contact apache@apache.org.
+ *
+ * 5. Products derived from this software may not be called "Apache"
+ *    nor may "Apache" appear in their names without prior written
+ *    permission of the Apache Group.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation.  For more
+ * information on the Apache Software Foundation, please see
+ * <http://www.apache.org/>.
+ *
+ * [Additional notices, if required by prior licensing conditions]
+ *
+ */ 
+
+
+package org.apache.directory.naming.config;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.Iterator;
+import java.util.Set;
+
+import javax.naming.Context;
+import javax.naming.InitialContext;
+import javax.naming.NamingException;
+
+import org.apache.commons.digester.Digester;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.directory.naming.ContextAccessController;
+import org.xml.sax.SAXException;
+
+/**
+ * Configure an in memory JNDI implementation using an XML configuration file.
+ * 
+ * @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
+{
+    private static final String COMP_CONTEXT_NAME = "java:comp";
+    private static final String ENV_CONTEXT_NAME = "env";
+    private static final String ROOT_ELEMENT = "naming";
+    private static final String CONTEXT_ELEMENT = ROOT_ELEMENT + "/context";
+    private static final String ENV_ELEMENT = CONTEXT_ELEMENT + "/environment";
+    private static final String RES_ELEMENT = CONTEXT_ELEMENT + "/resource";
+    private static final String RES_PARAM_ELEMENT = RES_ELEMENT + "/parameter";
+    private static Context envContext = null;
+
+    private static final Log LOG = LogFactory.getLog(XmlConfigurator.class);
+
+    public static synchronized void setupInitialContext() throws NamingException {
+        System.setProperty(Context.INITIAL_CONTEXT_FACTORY, "org.apache.directory.naming.java.javaURLContextFactory");
+        System.setProperty(Context.URL_PKG_PREFIXES, "org.apache.directory.naming");
+
+        Context initialContext = new InitialContext();
+        envContext = initialContext.createSubcontext(COMP_CONTEXT_NAME).createSubcontext(ENV_CONTEXT_NAME);
+    }
+
+    public static synchronized void destroyInitialContext() throws NamingException {
+        Context initialContext = new InitialContext();
+        Context ctx = (Context) initialContext.lookup(COMP_CONTEXT_NAME);
+        ctx.destroySubcontext(ENV_CONTEXT_NAME);
+        envContext = null;
+        initialContext.destroySubcontext(COMP_CONTEXT_NAME);
+        initialContext = null;
+    }
+
+    public static synchronized void loadConfiguration(InputStream inputFile) throws NamingException, ParseException {
+        if (envContext == null)
+        {
+            setupInitialContext();
+        }
+        ContextAccessController.setWritable("root", "x");
+
+        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");
+        digester.addObjectCreate(RES_ELEMENT, Config.Resource.class);
+        digester.addSetProperties(RES_ELEMENT);
+        digester.addSetNext(RES_ELEMENT, "addResource");
+        digester.addCallMethod(RES_PARAM_ELEMENT + "", "addParameter", 2);
+        digester.addCallParam(RES_PARAM_ELEMENT + "/name", 0);
+        digester.addCallParam(RES_PARAM_ELEMENT + "/value", 1);
+
+        try
+        {
+            Config.Naming naming = (Config.Naming) digester.parse(inputFile);
+            if (naming == null) {
+                throw new ParseException("Unable to find root element '" + ROOT_ELEMENT + "'");
+            }
+            if (LOG.isDebugEnabled()) {
+                LOG.debug("XML configuration loaded: " + naming.toString());
+            }
+
+            precreateSubcontextTree(envContext, naming.generateSortedSubcontextNameSet());
+
+            for (Iterator i = naming.getContextList().iterator(); i.hasNext();)
+            {
+                Config.Context ctx = (Config.Context) i.next();
+                Context jndiCtx = envContext;
+                if (ctx.getName() != null)
+                {
+                    jndiCtx = (Context) jndiCtx.lookup(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.bind(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();)
+        {
+            String name = (String) i.next();
+            ctx.createSubcontext(name);
+        }
+    }
+
+}

Added: incubator/directory/naming/trunk/factory/src/java/org/apache/directory/naming/factory/BeanFactory.java
==============================================================================
--- (empty file)
+++ incubator/directory/naming/trunk/factory/src/java/org/apache/directory/naming/factory/BeanFactory.java	Sun Dec  7 13:00:05 2003
@@ -0,0 +1,281 @@
+/*
+ * $Header: /home/cvs/jakarta-commons-sandbox/naming/factory/src/java/org/apache/commons/naming/factory/BeanFactory.java,v 1.2 2003/10/13 08:15:11 rdonkin Exp $
+ * $Revision: 1.2 $
+ * $Date: 2003/10/13 08:15:11 $
+ *
+ * ====================================================================
+ *
+ * The Apache Software License, Version 1.1
+ *
+ * Copyright (c) 1999-2001 The Apache Software Foundation.  All rights
+ * reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. The end-user documentation included with the redistribution, if
+ *    any, must include the following acknowledgement:
+ *       "This product includes software developed by the
+ *        Apache Software Foundation (http://www.apache.org/)."
+ *    Alternately, this acknowledgement may appear in the software itself,
+ *    if and wherever such third-party acknowledgements normally appear.
+ *
+ * 4. The names "The Jakarta Project", "Tomcat", and "Apache Software
+ *    Foundation" must not be used to endorse or promote products derived
+ *    from this software without prior written permission. For written
+ *    permission, please contact apache@apache.org.
+ *
+ * 5. Products derived from this software may not be called "Apache"
+ *    nor may "Apache" appear in their names without prior written
+ *    permission of the Apache Software Foundation.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation.  For more
+ * information on the Apache Software Foundation, please see
+ * <http://www.apache.org/>.
+ *
+ * [Additional notices, if required by prior licensing conditions]
+ *
+ */
+
+package org.apache.directory.naming.factory;
+
+import java.util.Hashtable;
+import java.util.Enumeration;
+import javax.naming.Name;
+import javax.naming.Context;
+import javax.naming.NamingException;
+import javax.naming.Reference;
+import javax.naming.RefAddr;
+import javax.naming.spi.ObjectFactory;
+import org.apache.directory.naming.ResourceRef;
+
+import java.beans.Introspector;
+import java.beans.BeanInfo;
+import java.beans.PropertyDescriptor;
+
+import java.lang.reflect.Method;
+
+/**
+ * Object factory for any Resource conforming to the JavaBean spec.
+ * 
+ * <p>This factory can be configured in a <code>&lt;DefaultContext&gt;</code>
+ * or <code>&lt;Context&gt;</code> element in your <code>conf/server.xml</code>
+ * configuration file.  An example of factory configuration is:</p>
+ * <pre>
+ * &lt;Resource name="jdbc/myDataSource" auth="SERVLET"
+ *   type="oracle.jdbc.pool.OracleConnectionCacheImpl"/&gt;
+ * &lt;ResourceParams name="jdbc/myDataSource"&gt;
+ *   &lt;parameter&gt;
+ *     &lt;name&gt;factory&lt;/name&gt;
+ *     &lt;value&gt;org.apache.directory.naming.factory.BeanFactory&lt;/value&gt;
+ *   &lt;/parameter&gt;
+ *   &lt;parameter&gt;
+ *     &lt;name&gt;driverType&lt;/name&gt;
+ *     &lt;value&gt;thin&lt;/value&gt;
+ *   &lt;/parameter&gt;
+ *   &lt;parameter&gt;
+ *     &lt;name&gt;serverName&lt;/name&gt;
+ *     &lt;value&gt;hue&lt;/value&gt;
+ *   &lt;/parameter&gt;
+ *   &lt;parameter&gt;
+ *     &lt;name&gt;networkProtocol&lt;/name&gt;
+ *     &lt;value&gt;tcp&lt;/value&gt;
+ *   &lt;/parameter&gt; 
+ *   &lt;parameter&gt;
+ *     &lt;name&gt;databaseName&lt;/name&gt;
+ *     &lt;value&gt;XXXX&lt;/value&gt;
+ *   &lt;/parameter&gt;
+ *   &lt;parameter&gt;
+ *     &lt;name&gt;portNumber&lt;/name&gt;
+ *     &lt;value&gt;NNNN&lt;/value&gt;
+ *   &lt;/parameter&gt;
+ *   &lt;parameter&gt;
+ *     &lt;name&gt;user&lt;/name&gt;
+ *     &lt;value&gt;XXXX&lt;/value&gt;
+ *   &lt;/parameter&gt;
+ *   &lt;parameter&gt;
+ *     &lt;name&gt;password&lt;/name&gt;
+ *     &lt;value&gt;XXXX&lt;/value&gt;
+ *   &lt;/parameter&gt;
+ *   &lt;parameter&gt;
+ *     &lt;name&gt;maxLimit&lt;/name&gt;
+ *     &lt;value&gt;5&lt;/value&gt;
+ *   &lt;/parameter&gt;
+ * &lt;/ResourceParams&gt;
+ * </pre>
+ *
+ * @author <a href="mailto:aner at ncstech.com">Aner Perez</a>
+ */
+public class BeanFactory
+    implements ObjectFactory {
+
+    // ----------------------------------------------------------- Constructors
+
+
+    // -------------------------------------------------------------- Constants
+
+
+    // ----------------------------------------------------- Instance Variables
+
+
+    // --------------------------------------------------------- Public Methods
+
+
+    // -------------------------------------------------- ObjectFactory Methods
+
+
+    /**
+     * Create a new Bean instance.
+     * 
+     * @param obj The reference object describing the Bean
+     */
+    public Object getObjectInstance(Object obj, Name name, Context nameCtx,
+                                    Hashtable environment)
+        throws NamingException {
+
+        if (obj instanceof ResourceRef) {
+
+            try {
+                
+                Reference ref = (Reference) obj;
+                String beanClassName = ref.getClassName();
+                Class beanClass = null;
+                ClassLoader tcl = 
+                    Thread.currentThread().getContextClassLoader();
+                if (tcl != null) {
+                    try {
+                        beanClass = tcl.loadClass(beanClassName);
+                    } catch(ClassNotFoundException e) {
+                    }
+                } else {
+                    try {
+                        beanClass = Class.forName(beanClassName);
+                    } catch(ClassNotFoundException e) {
+                        e.printStackTrace();
+                    }
+                }
+                if (beanClass == null) {
+                    throw new NamingException
+                        ("Class not found: " + beanClassName);
+                }
+                
+                BeanInfo bi = Introspector.getBeanInfo(beanClass);
+                PropertyDescriptor[] pda = bi.getPropertyDescriptors();
+                
+                Object bean = beanClass.newInstance();
+                
+                Enumeration e = ref.getAll();
+                while (e.hasMoreElements()) {
+                    
+                    RefAddr ra = (RefAddr) e.nextElement();
+                    String propName = ra.getType();
+                    
+                    if (propName.equals(Constants.FACTORY) ||
+                        propName.equals("scope") || propName.equals("auth")) {
+                        continue;
+                    }
+                    
+                    String value = (String)ra.getContent();
+                    
+                    Object[] valueArray = new Object[1];
+                    
+                    int i = 0;
+                    for (i = 0; i<pda.length; i++) {
+
+                        if (pda[i].getName().equals(propName)) {
+
+                            Class propType = pda[i].getPropertyType();
+
+                            if (propType.equals(String.class)) {
+                                valueArray[0] = value;
+                            } else if (propType.equals(Character.class) 
+                                       || propType.equals(char.class)) {
+                                valueArray[0] = new Character(value.charAt(0));
+                            } else if (propType.equals(Byte.class) 
+                                       || propType.equals(byte.class)) {
+                                valueArray[0] = new Byte(value);
+                            } else if (propType.equals(Short.class) 
+                                       || propType.equals(short.class)) {
+                                valueArray[0] = new Short(value);
+                            } else if (propType.equals(Integer.class) 
+                                       || propType.equals(int.class)) {
+                                valueArray[0] = new Integer(value);
+                            } else if (propType.equals(Long.class) 
+                                       || propType.equals(long.class)) {
+                                valueArray[0] = new Long(value);
+                            } else if (propType.equals(Float.class) 
+                                       || propType.equals(float.class)) {
+                                valueArray[0] = new Float(value);
+                            } else if (propType.equals(Double.class) 
+                                       || propType.equals(double.class)) {
+                                valueArray[0] = new Double(value);
+                            } else {
+                                throw new NamingException
+                                    ("String conversion for property type '"
+                                     + propType.getName() + "' not available");
+                            }
+                            
+                            Method setProp = pda[i].getWriteMethod();
+                            if (setProp != null) {
+                                setProp.invoke(bean, valueArray);
+                            } else {
+                                throw new NamingException
+                                    ("Write not allowed for property: " 
+                                     + propName);
+                            }
+
+                            break;
+
+                        }
+
+                    }
+
+                    if (i == pda.length) {
+                        throw new NamingException
+                            ("No set method found for property: " + propName);
+                    }
+
+                }
+
+                return bean;
+
+            } catch (java.beans.IntrospectionException ie) {
+                throw new NamingException(ie.getMessage());
+            } catch (java.lang.IllegalAccessException iae) {
+                throw new NamingException(iae.getMessage());
+            } catch (java.lang.InstantiationException ie2) {
+                throw new NamingException(ie2.getMessage());
+            } catch (java.lang.reflect.InvocationTargetException ite) {
+                throw new NamingException(ite.getMessage());
+            }
+
+        } else {
+            return null;
+        }
+
+    }
+}

Added: incubator/directory/naming/trunk/factory/src/java/org/apache/directory/naming/factory/Constants.java
==============================================================================
--- (empty file)
+++ incubator/directory/naming/trunk/factory/src/java/org/apache/directory/naming/factory/Constants.java	Sun Dec  7 13:00:05 2003
@@ -0,0 +1,108 @@
+/*
+ * $Header: /home/cvs/jakarta-commons-sandbox/naming/factory/src/java/org/apache/commons/naming/factory/Constants.java,v 1.2 2003/10/13 08:15:11 rdonkin Exp $
+ * $Revision: 1.2 $
+ * $Date: 2003/10/13 08:15:11 $
+ *
+ * ====================================================================
+ *
+ * The Apache Software License, Version 1.1
+ *
+ * Copyright (c) 1999 The Apache Software Foundation.  All rights 
+ * reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. The end-user documentation included with the redistribution, if
+ *    any, must include the following acknowledgement:
+ *       "This product includes software developed by the 
+ *        Apache Software Foundation (http://www.apache.org/)."
+ *    Alternately, this acknowledgement may appear in the software itself,
+ *    if and wherever such third-party acknowledgements normally appear.
+ *
+ * 4. The names "The Jakarta Project", "Tomcat", and "Apache Software
+ *    Foundation" must not be used to endorse or promote products derived
+ *    from this software without prior written permission. For written 
+ *    permission, please contact apache@apache.org.
+ *
+ * 5. Products derived from this software may not be called "Apache"
+ *    nor may "Apache" appear in their names without prior written
+ *    permission of the Apache Software Foundation.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation.  For more
+ * information on the Apache Software Foundation, please see
+ * <http://www.apache.org/>.
+ *
+ * [Additional notices, if required by prior licensing conditions]
+ *
+ */ 
+
+
+package org.apache.directory.naming.factory;
+
+
+/**
+ * Static constants for this package.
+ */
+
+public final class Constants {
+
+    public static final String Package = "org.apache.directory.naming.factory";
+
+    public static final String DEFAULT_RESOURCE_FACTORY = 
+        Package + ".ResourceFactory";
+
+    public static final String DEFAULT_RESOURCE_LINK_FACTORY = 
+        Package + ".ResourceLinkFactory";
+
+    public static final String DEFAULT_TRANSACTION_FACTORY = 
+        Package + ".TransactionFactory";
+
+    public static final String DEFAULT_RESOURCE_ENV_FACTORY = 
+        Package + ".ResourceEnvFactory";
+
+    public static final String DEFAULT_EJB_FACTORY = 
+        Package + ".EjbFactory";
+
+    public static final String DBCP_DATASOURCE_FACTORY = 
+        "org.apache.commons.dbcp.BasicDataSourceFactory";
+
+    public static final String TYREX_RESOURCE_FACTORY =
+        Package + ".TyrexResourceFactory";
+
+    public static final String TYREX_TRANSACTION_FACTORY = 
+        Package + ".TyrexTransactionFactory";
+
+    public static final String OBJECT_FACTORIES = "";
+
+    public static final String FACTORY = "factory";
+
+    public static final String TYREX_DOMAIN_CONFIG = "tyrexDomainConfig";
+
+    public static final String TYREX_DOMAIN_NAME = "tyrexDomainName";
+
+}

Added: incubator/directory/naming/trunk/factory/src/java/org/apache/directory/naming/factory/EjbFactory.java
==============================================================================
--- (empty file)
+++ incubator/directory/naming/trunk/factory/src/java/org/apache/directory/naming/factory/EjbFactory.java	Sun Dec  7 13:00:05 2003
@@ -0,0 +1,196 @@
+/*
+ * $Header: /home/cvs/jakarta-commons-sandbox/naming/factory/src/java/org/apache/commons/naming/factory/EjbFactory.java,v 1.2 2003/10/13 08:15:11 rdonkin Exp $
+ * $Revision: 1.2 $
+ * $Date: 2003/10/13 08:15:11 $
+ *
+ * ====================================================================
+ *
+ * The Apache Software License, Version 1.1
+ *
+ * Copyright (c) 1999 The Apache Software Foundation.  All rights 
+ * reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. The end-user documentation included with the redistribution, if
+ *    any, must include the following acknowledgement:
+ *       "This product includes software developed by the 
+ *        Apache Software Foundation (http://www.apache.org/)."
+ *    Alternately, this acknowledgement may appear in the software itself,
+ *    if and wherever such third-party acknowledgements normally appear.
+ *
+ * 4. The names "The Jakarta Project", "Tomcat", and "Apache Software
+ *    Foundation" must not be used to endorse or promote products derived
+ *    from this software without prior written permission. For written 
+ *    permission, please contact apache@apache.org.
+ *
+ * 5. Products derived from this software may not be called "Apache"
+ *    nor may "Apache" appear in their names without prior written
+ *    permission of the Apache Software Foundation.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation.  For more
+ * information on the Apache Software Foundation, please see
+ * <http://www.apache.org/>.
+ *
+ * [Additional notices, if required by prior licensing conditions]
+ *
+ */ 
+
+
+package org.apache.directory.naming.factory;
+
+import java.util.Hashtable;
+import javax.naming.Name;
+import javax.naming.Context;
+import javax.naming.InitialContext;
+import javax.naming.NamingException;
+import javax.naming.Reference;
+import javax.naming.RefAddr;
+import javax.naming.spi.ObjectFactory;
+import org.apache.directory.naming.EjbRef;
+
+/**
+ * Object factory for EJBs.
+ * 
+ * @author Remy Maucherat
+ * @version $Revision: 1.2 $ $Date: 2003/10/13 08:15:11 $
+ */
+
+public class EjbFactory
+    implements ObjectFactory {
+
+
+    // ----------------------------------------------------------- Constructors
+
+
+    // -------------------------------------------------------------- Constants
+
+
+    // ----------------------------------------------------- Instance Variables
+
+
+    // --------------------------------------------------------- Public Methods
+
+
+    // -------------------------------------------------- ObjectFactory Methods
+
+
+    /**
+     * Crete a new EJB instance.
+     * 
+     * @param obj The reference object describing the DataSource
+     */
+    public Object getObjectInstance(Object obj, Name name, Context nameCtx,
+                                    Hashtable environment)
+        throws Exception {
+        
+        if (obj instanceof EjbRef) {
+            Reference ref = (Reference) obj;
+
+            // If ejb-link has been specified, resolving the link using JNDI
+            RefAddr linkRefAddr = ref.get(EjbRef.LINK);
+            if (linkRefAddr != null) {
+                // Retrieving the EJB link
+                String ejbLink = linkRefAddr.getContent().toString();
+                Object beanObj = (new InitialContext()).lookup(ejbLink);
+                // Load home interface and checking if bean correctly
+                // implements specified home interface
+                /*
+                String homeClassName = ref.getClassName();
+                try {
+                    Class home = Class.forName(homeClassName);
+                    if (home.isInstance(beanObj)) {
+                        System.out.println("Bean of type " 
+                                           + beanObj.getClass().getName() 
+                                           + " implements home interface " 
+                                           + home.getName());
+                    } else {
+                        System.out.println("Bean of type " 
+                                           + beanObj.getClass().getName() 
+                                           + " doesn't implement home interface " 
+                                           + home.getName());
+                        throw new NamingException
+                            ("Bean of type " + beanObj.getClass().getName() 
+                             + " doesn't implement home interface " 
+                             + home.getName());
+                    }
+                } catch (ClassNotFoundException e) {
+                    System.out.println("Couldn't load home interface "
+                                       + homeClassName);
+                }
+                */
+                return beanObj;
+            }
+            
+            ObjectFactory factory = null;
+            RefAddr factoryRefAddr = ref.get(Constants.FACTORY);
+            if (factoryRefAddr != null) {
+                // Using the specified factory
+                String factoryClassName = 
+                    factoryRefAddr.getContent().toString();
+                // Loading factory
+                ClassLoader tcl = 
+                    Thread.currentThread().getContextClassLoader();
+                Class factoryClass = null;
+                if (tcl != null) {
+                    try {
+                        factoryClass = tcl.loadClass(factoryClassName);
+                    } catch(ClassNotFoundException e) {
+                    }
+                } else {
+                    try {
+                        factoryClass = Class.forName(factoryClassName);
+                    } catch(ClassNotFoundException e) {
+                    }
+                }
+                if (factoryClass != null) {
+                    try {
+                        factory = (ObjectFactory) factoryClass.newInstance();
+                    } catch(Throwable t) {
+                    }
+                }
+            }
+
+            // Note: No defaults here
+            if (factory != null) {
+                return factory.getObjectInstance
+                    (obj, name, nameCtx, environment);
+            } else {
+                throw new NamingException
+                    ("Cannot create resource instance");
+            }
+
+        }
+
+        return null;
+
+    }
+
+
+}
+

Added: incubator/directory/naming/trunk/factory/src/java/org/apache/directory/naming/factory/MailSessionFactory.java
==============================================================================
--- (empty file)
+++ incubator/directory/naming/trunk/factory/src/java/org/apache/directory/naming/factory/MailSessionFactory.java	Sun Dec  7 13:00:05 2003
@@ -0,0 +1,172 @@
+/*
+ * $Header: /home/cvs/jakarta-commons-sandbox/naming/factory/src/java/org/apache/commons/naming/factory/MailSessionFactory.java,v 1.2 2003/10/13 08:15:11 rdonkin Exp $
+ * $Revision: 1.2 $
+ * $Date: 2003/10/13 08:15:11 $
+ *
+ * ====================================================================
+ *
+ * The Apache Software License, Version 1.1
+ *
+ * Copyright (c) 1999-2001 The Apache Software Foundation.  All rights
+ * reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. The end-user documentation included with the redistribution, if
+ *    any, must include the following acknowledgement:
+ *       "This product includes software developed by the
+ *        Apache Software Foundation (http://www.apache.org/)."
+ *    Alternately, this acknowledgement may appear in the software itself,
+ *    if and wherever such third-party acknowledgements normally appear.
+ *
+ * 4. The names "The Jakarta Project", "Tomcat", and "Apache Software
+ *    Foundation" must not be used to endorse or promote products derived
+ *    from this software without prior written permission. For written
+ *    permission, please contact apache@apache.org.
+ *
+ * 5. Products derived from this software may not be called "Apache"
+ *    nor may "Apache" appear in their names without prior written
+ *    permission of the Apache Software Foundation.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation.  For more
+ * information on the Apache Software Foundation, please see
+ * <http://www.apache.org/>.
+ *
+ * [Additional notices, if required by prior licensing conditions]
+ *
+ */
+
+package org.apache.directory.naming.factory;
+
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+import java.util.Enumeration;
+import java.util.Hashtable;
+import java.util.Properties;
+import javax.mail.Session;
+import javax.naming.Name;
+import javax.naming.Context;
+import javax.naming.RefAddr;
+import javax.naming.Reference;
+import javax.naming.spi.ObjectFactory;
+
+/**
+ * <p>Factory class that creates a JNDI named JavaMail Session factory,
+ * which can be used for managing inbound and outbound electronic mail
+ * messages via JavaMail APIs.  All messaging environment properties
+ * described in the JavaMail Specification may be passed to the Session
+ * factory; however the following properties are the most commonly used:</p>
+ * <ul>
+ * <li>
+ * <li><strong>mail.smtp.host</strong> - Hostname for outbound transport
+ *     connections.  Defaults to <code>localhost</code> if not specified.</li>
+ * </ul>
+ *
+ * <p>This factory can be configured in a <code>&lt;DefaultContext&gt;</code>
+ * or <code>&lt;Context&gt;</code> element in your <code>conf/server.xml</code>
+ * configuration file.  An example of factory configuration is:</p>
+ * <pre>
+ * &lt;Resource name="mail/smtp" auth="CONTAINER"
+ *           type="javax.mail.Session"/&gt;
+ * &lt;ResourceParams name="mail/smtp"&gt;
+ *   &lt;parameter&gt;
+ *     &lt;name&gt;factory&lt;/name&gt;
+ *     &lt;value&gt;org.apache.directory.naming.factory.MailSessionFactory&lt;/value&gt;
+ *   &lt;/parameter&gt;
+ *   &lt;parameter&gt;
+ *     &lt;name&gt;mail.smtp.host&lt;/name&gt;
+ *     &lt;value&gt;mail.mycompany.com&lt;/value&gt;
+ *   &lt;/parameter&gt;
+ * &lt;/ResourceParams&gt;
+ * </pre>
+ *
+ * @author Craig R. McClanahan
+ * @version $Revision: 1.2 $ $Date: 2003/10/13 08:15:11 $
+ */
+
+public class MailSessionFactory implements ObjectFactory {
+
+
+    /**
+     * The Java type for which this factory knows how to create objects.
+     */
+    protected static final String factoryType = "javax.mail.Session";
+
+
+    /**
+     * Create and return an object instance based on the specified
+     * characteristics.
+     *
+     * @param refObj Reference information containing our parameters, or null
+     *  if there are no parameters
+     * @param name The name of this object, relative to context, or null
+     *  if there is no name
+     * @param context The context to which name is relative, or null if name
+     *  is relative to the default initial context
+     * @param env Environment variables, or null if there are none
+     *
+     * @exception Exception if an error occurs during object creation
+     */
+    public Object getObjectInstance(Object refObj, Name name, Context context,
+				    Hashtable env) throws Exception 
+    {
+
+        // Return null if we cannot create an object of the requested type
+	final Reference ref = (Reference) refObj;
+        if (!ref.getClassName().equals(factoryType))
+            return (null);
+
+        // Create a new Session inside a doPrivileged block, so that JavaMail
+        // can read its default properties without throwing Security
+        // exceptions
+        return AccessController.doPrivileged( new PrivilegedAction() {
+		public Object run() {
+
+                    // Create the JavaMail properties we will use
+                    Properties props = new Properties();
+                    props.put("mail.transport.protocol", "smtp");
+                    props.put("mail.smtp.host", "localhost");
+                    Enumeration attrs = ref.getAll();
+                    while (attrs.hasMoreElements()) {
+                        RefAddr attr = (RefAddr) attrs.nextElement();
+                        if ("factory".equals(attr.getType()))
+                            continue;
+                        props.put(attr.getType(), (String) attr.getContent());
+                    }
+
+                    // Create and return the new Session object
+                    Session session = Session.getInstance(props, null);
+                    return (session);
+
+		}
+	    } );
+
+    }
+
+
+}

Added: incubator/directory/naming/trunk/factory/src/java/org/apache/directory/naming/factory/ResourceEnvFactory.java
==============================================================================
--- (empty file)
+++ incubator/directory/naming/trunk/factory/src/java/org/apache/directory/naming/factory/ResourceEnvFactory.java	Sun Dec  7 13:00:05 2003
@@ -0,0 +1,157 @@
+/*
+ * $Header: /home/cvs/jakarta-commons-sandbox/naming/factory/src/java/org/apache/commons/naming/factory/ResourceEnvFactory.java,v 1.2 2003/10/13 08:15:11 rdonkin Exp $
+ * $Revision: 1.2 $
+ * $Date: 2003/10/13 08:15:11 $
+ *
+ * ====================================================================
+ *
+ * The Apache Software License, Version 1.1
+ *
+ * Copyright (c) 1999 The Apache Software Foundation.  All rights 
+ * reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. The end-user documentation included with the redistribution, if
+ *    any, must include the following acknowledgement:
+ *       "This product includes software developed by the 
+ *        Apache Software Foundation (http://www.apache.org/)."
+ *    Alternately, this acknowledgement may appear in the software itself,
+ *    if and wherever such third-party acknowledgements normally appear.
+ *
+ * 4. The names "The Jakarta Project", "Tomcat", and "Apache Software
+ *    Foundation" must not be used to endorse or promote products derived
+ *    from this software without prior written permission. For written 
+ *    permission, please contact apache@apache.org.
+ *
+ * 5. Products derived from this software may not be called "Apache"
+ *    nor may "Apache" appear in their names without prior written
+ *    permission of the Apache Software Foundation.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation.  For more
+ * information on the Apache Software Foundation, please see
+ * <http://www.apache.org/>.
+ *
+ * [Additional notices, if required by prior licensing conditions]
+ *
+ */ 
+
+
+package org.apache.directory.naming.factory;
+
+import java.util.Hashtable;
+import javax.naming.Name;
+import javax.naming.Context;
+import javax.naming.NamingException;
+import javax.naming.Reference;
+import javax.naming.RefAddr;
+import javax.naming.spi.ObjectFactory;
+import org.apache.directory.naming.ResourceEnvRef;
+
+/**
+ * Object factory for Resources env.
+ * 
+ * @author Remy Maucherat
+ * @version $Revision: 1.2 $ $Date: 2003/10/13 08:15:11 $
+ */
+
+public class ResourceEnvFactory
+    implements ObjectFactory {
+
+
+    // ----------------------------------------------------------- Constructors
+
+
+    // -------------------------------------------------------------- Constants
+
+
+    // ----------------------------------------------------- Instance Variables
+
+
+    // --------------------------------------------------------- Public Methods
+
+
+    // -------------------------------------------------- ObjectFactory Methods
+
+
+    /**
+     * Crete a new Resource env instance.
+     * 
+     * @param obj The reference object describing the DataSource
+     */
+    public Object getObjectInstance(Object obj, Name name, Context nameCtx,
+                                    Hashtable environment)
+        throws Exception {
+        
+        if (obj instanceof ResourceEnvRef) {
+            Reference ref = (Reference) obj;
+            ObjectFactory factory = null;
+            RefAddr factoryRefAddr = ref.get(Constants.FACTORY);
+            if (factoryRefAddr != null) {
+                // Using the specified factory
+                String factoryClassName = 
+                    factoryRefAddr.getContent().toString();
+                // Loading factory
+                ClassLoader tcl = 
+                    Thread.currentThread().getContextClassLoader();
+                Class factoryClass = null;
+                if (tcl != null) {
+                    try {
+                        factoryClass = tcl.loadClass(factoryClassName);
+                    } catch(ClassNotFoundException e) {
+                    }
+                } else {
+                    try {
+                        factoryClass = Class.forName(factoryClassName);
+                    } catch(ClassNotFoundException e) {
+                    }
+                }
+                if (factoryClass != null) {
+                    try {
+                        factory = (ObjectFactory) factoryClass.newInstance();
+                    } catch(Throwable t) {
+                    }
+                }
+            }
+            // Note: No defaults here
+            if (factory != null) {
+                return factory.getObjectInstance
+                    (obj, name, nameCtx, environment);
+            } else {
+                throw new NamingException
+                    ("Cannot create resource instance");
+            }
+        }
+
+        return null;
+
+    }
+
+
+}
+

Added: incubator/directory/naming/trunk/factory/src/java/org/apache/directory/naming/factory/ResourceFactory.java
==============================================================================
--- (empty file)
+++ incubator/directory/naming/trunk/factory/src/java/org/apache/directory/naming/factory/ResourceFactory.java	Sun Dec  7 13:00:05 2003
@@ -0,0 +1,200 @@
+/*
+ * $Header: /home/cvs/jakarta-commons-sandbox/naming/factory/src/java/org/apache/commons/naming/factory/ResourceFactory.java,v 1.2 2003/10/13 08:15:11 rdonkin Exp $
+ * $Revision: 1.2 $
+ * $Date: 2003/10/13 08:15:11 $
+ *
+ * ====================================================================
+ *
+ * The Apache Software License, Version 1.1
+ *
+ * Copyright (c) 1999 The Apache Software Foundation.  All rights 
+ * reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. The end-user documentation included with the redistribution, if
+ *    any, must include the following acknowledgement:
+ *       "This product includes software developed by the 
+ *        Apache Software Foundation (http://www.apache.org/)."
+ *    Alternately, this acknowledgement may appear in the software itself,
+ *    if and wherever such third-party acknowledgements normally appear.
+ *
+ * 4. The names "The Jakarta Project", "Tomcat", and "Apache Software
+ *    Foundation" must not be used to endorse or promote products derived
+ *    from this software without prior written permission. For written 
+ *    permission, please contact apache@apache.org.
+ *
+ * 5. Products derived from this software may not be called "Apache"
+ *    nor may "Apache" appear in their names without prior written
+ *    permission of the Apache Software Foundation.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation.  For more
+ * information on the Apache Software Foundation, please see
+ * <http://www.apache.org/>.
+ *
+ * [Additional notices, if required by prior licensing conditions]
+ *
+ */ 
+
+
+package org.apache.directory.naming.factory;
+
+import java.util.Hashtable;
+import javax.naming.Name;
+import javax.naming.Context;
+import javax.naming.NamingException;
+import javax.naming.Reference;
+import javax.naming.RefAddr;
+import javax.naming.spi.ObjectFactory;
+import org.apache.directory.naming.ResourceRef;
+
+/**
+ * Object factory for Resources.
+ * 
+ * @author Remy Maucherat
+ * @version $Revision: 1.2 $ $Date: 2003/10/13 08:15:11 $
+ */
+
+public class ResourceFactory
+    implements ObjectFactory {
+
+
+    // ----------------------------------------------------------- Constructors
+
+
+    // -------------------------------------------------------------- Constants
+
+
+    // ----------------------------------------------------- Instance Variables
+
+
+    // --------------------------------------------------------- Public Methods
+
+
+    // -------------------------------------------------- ObjectFactory Methods
+
+
+    /**
+     * Crete a new DataSource instance.
+     * 
+     * @param obj The reference object describing the DataSource
+     */
+    public Object getObjectInstance(Object obj, Name name, Context nameCtx,
+                                    Hashtable environment)
+        throws Exception {
+        
+        if (obj instanceof ResourceRef) {
+            Reference ref = (Reference) obj;
+            ObjectFactory factory = null;
+            RefAddr factoryRefAddr = ref.get(Constants.FACTORY);
+            if (factoryRefAddr != null) {
+                // Using the specified factory
+                String factoryClassName = 
+                    factoryRefAddr.getContent().toString();
+                // Loading factory
+                ClassLoader tcl = 
+                    Thread.currentThread().getContextClassLoader();
+                Class factoryClass = null;
+                if (tcl != null) {
+                    try {
+                        factoryClass = tcl.loadClass(factoryClassName);
+                    } catch(ClassNotFoundException e) {
+                        throw new NamingException(
+                            "Could not create resource factory, ClassNotFoundException:" +
+                            e.getMessage());
+                    }
+                } else {
+                    try {
+                        factoryClass = Class.forName(factoryClassName);
+                    } catch(ClassNotFoundException e) {
+                        throw new NamingException(
+                            "Could not create resource factory, ClassNotFoundException:" +
+                            e.getMessage());
+                    }
+                }
+                if (factoryClass != null) {
+                    try {
+                        factory = (ObjectFactory) factoryClass.newInstance();
+                    } catch(Throwable t) {
+                        if( t instanceof NamingException)
+                            throw (NamingException)t;
+                        throw new NamingException(
+                            "Could not create resource factory instance, " +
+                            t.getMessage());
+                    }
+                }
+            } else {
+                if (ref.getClassName().equals("javax.sql.DataSource")) {
+                    String javaxSqlDataSourceFactoryClassName =
+                        System.getProperty("javax.sql.DataSource.Factory",
+                                           Constants.DBCP_DATASOURCE_FACTORY);
+                    try {
+                        factory = (ObjectFactory) 
+                            Class.forName(javaxSqlDataSourceFactoryClassName)
+                            .newInstance();
+                    } catch(Throwable t) {
+
+                    }
+                } else if (ref.getClassName().equals("javax.mail.Session")) {
+                    String javaxMailSessionFactoryClassName =
+                        System.getProperty("javax.mail.Session.Factory",
+                                           "org.apache.directory.naming.factory.MailSessionFactory");
+                    try {
+                        factory = (ObjectFactory) 
+                            Class.forName(javaxMailSessionFactoryClassName)
+                            .newInstance();
+                    } catch(Throwable t) {
+                    }
+                } else if (ref.getClassName().equals("tyrex.resource.Resource")) {
+                    String tyrexResourceFactoryClassName =
+                        System.getProperty("tyrex.resource.Resource.Factory",
+                                           Constants.TYREX_RESOURCE_FACTORY);
+                    try {
+                        factory = (ObjectFactory)
+                            Class.forName(tyrexResourceFactoryClassName)
+                            .newInstance();
+                    } catch(Throwable t) {
+                    }
+                }
+            }
+            if (factory != null) {
+                return factory.getObjectInstance
+                    (obj, name, nameCtx, environment);
+            } else {
+                throw new NamingException
+                    ("Cannot create resource instance");
+            }
+        }
+        
+        return null;
+
+    }
+
+
+}
+

Added: incubator/directory/naming/trunk/factory/src/java/org/apache/directory/naming/factory/ResourceLinkFactory.java
==============================================================================
--- (empty file)
+++ incubator/directory/naming/trunk/factory/src/java/org/apache/directory/naming/factory/ResourceLinkFactory.java	Sun Dec  7 13:00:05 2003
@@ -0,0 +1,154 @@
+/*
+ * $Header: /home/cvs/jakarta-commons-sandbox/naming/factory/src/java/org/apache/commons/naming/factory/ResourceLinkFactory.java,v 1.2 2003/10/13 08:15:11 rdonkin Exp $
+ * $Revision: 1.2 $
+ * $Date: 2003/10/13 08:15:11 $
+ *
+ * ====================================================================
+ *
+ * The Apache Software License, Version 1.1
+ *
+ * Copyright (c) 1999 The Apache Software Foundation.  All rights 
+ * reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. The end-user documentation included with the redistribution, if
+ *    any, must include the following acknowledgement:
+ *       "This product includes software developed by the 
+ *        Apache Software Foundation (http://www.apache.org/)."
+ *    Alternately, this acknowledgement may appear in the software itself,
+ *    if and wherever such third-party acknowledgements normally appear.
+ *
+ * 4. The names "The Jakarta Project", "Tomcat", and "Apache Software
+ *    Foundation" must not be used to endorse or promote products derived
+ *    from this software without prior written permission. For written 
+ *    permission, please contact apache@apache.org.
+ *
+ * 5. Products derived from this software may not be called "Apache"
+ *    nor may "Apache" appear in their names without prior written
+ *    permission of the Apache Software Foundation.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation.  For more
+ * information on the Apache Software Foundation, please see
+ * <http://www.apache.org/>.
+ *
+ * [Additional notices, if required by prior licensing conditions]
+ *
+ */ 
+
+
+package org.apache.directory.naming.factory;
+
+import java.util.Hashtable;
+import java.sql.Driver;
+import java.sql.DriverManager;
+import javax.naming.Name;
+import javax.naming.Context;
+import javax.naming.NamingException;
+import javax.naming.Reference;
+import javax.naming.RefAddr;
+import javax.naming.spi.ObjectFactory;
+import org.apache.directory.naming.ResourceLinkRef;
+
+
+/**
+ * <p>Object factory for resource links.</p>
+ * 
+ * @author Remy Maucherat
+ * @version $Revision: 1.2 $ $Date: 2003/10/13 08:15:11 $
+ */
+
+public class ResourceLinkFactory
+    implements ObjectFactory {
+
+
+    // ----------------------------------------------------------- Constructors
+
+
+    // ------------------------------------------------------- Static Variables
+
+
+    /**
+     * Global naming context.
+     */
+    private static Context globalContext = null;
+
+
+    // --------------------------------------------------------- Public Methods
+
+
+    /**
+     * Set the global context (note: can only be used once).
+     * 
+     * @param newGlobalContext new global context value
+     */
+    public static void setGlobalContext(Context newGlobalContext) {
+        if (globalContext != null)
+            return;
+        globalContext = newGlobalContext;
+    }
+
+
+    // -------------------------------------------------- ObjectFactory Methods
+
+
+    /**
+     * Create a new DataSource instance.
+     * 
+     * @param obj The reference object describing the DataSource
+     */
+    public Object getObjectInstance(Object obj, Name name, Context nameCtx,
+                                    Hashtable environment)
+        throws NamingException {
+        
+        if (!(obj instanceof ResourceLinkRef))
+            return null;
+
+        // Can we process this request?
+        Reference ref = (Reference) obj;
+
+        String type = ref.getClassName();
+
+        // Read the global ref addr
+        String globalName = null;
+        RefAddr refAddr = ref.get(ResourceLinkRef.GLOBALNAME);
+        if (refAddr != null) {
+            globalName = refAddr.getContent().toString();
+            Object result = null;
+            result = globalContext.lookup(globalName);
+            // FIXME: Check type
+            return result;
+        }
+
+        return (null);
+
+        
+    }
+
+
+}

Added: incubator/directory/naming/trunk/factory/src/java/org/apache/directory/naming/factory/SendMailFactory.java
==============================================================================
--- (empty file)
+++ incubator/directory/naming/trunk/factory/src/java/org/apache/directory/naming/factory/SendMailFactory.java	Sun Dec  7 13:00:05 2003
@@ -0,0 +1,172 @@
+/*
+ * $Header: /home/cvs/jakarta-commons-sandbox/naming/factory/src/java/org/apache/commons/naming/factory/SendMailFactory.java,v 1.2 2003/10/13 08:15:11 rdonkin Exp $
+ * $Revision: 1.2 $
+ * $Date: 2003/10/13 08:15:11 $
+ *
+ * ====================================================================
+ *
+ * The Apache Software License, Version 1.1
+ *
+ * Copyright (c) 1999 The Apache Software Foundation.  All rights
+ * reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. The end-user documentation included with the redistribution, if
+ *    any, must include the following acknowledgement:
+ *       "This product includes software developed by the
+ *        Apache Software Foundation (http://www.apache.org/)."
+ *    Alternately, this acknowledgement may appear in the software itself,
+ *    if and wherever such third-party acknowledgements normally appear.
+ *
+ * 4. The names "The Jakarta Project", "Tomcat", and "Apache Software
+ *    Foundation" must not be used to endorse or promote products derived
+ *    from this software without prior written permission. For written
+ *    permission, please contact apache@apache.org.
+ *
+ * 5. Products derived from this software may not be called "Apache"
+ *    nor may "Apache" appear in their names without prior written
+ *    permission of the Apache Software Foundation.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation.  For more
+ * information on the Apache Software Foundation, please see
+ * <http://www.apache.org/>.
+ *
+ * [Additional notices, if required by prior licensing conditions]
+ *
+ */
+
+package org.apache.directory.naming.factory;
+
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+import java.util.Hashtable;
+import java.util.Properties;
+import java.util.Enumeration;
+import javax.mail.Session;
+import javax.mail.internet.InternetAddress;
+import javax.mail.internet.MimeMessage;
+import javax.mail.internet.MimePart;
+import javax.mail.internet.MimePartDataSource;
+import javax.naming.Name;
+import javax.naming.Context;
+import javax.naming.Reference;
+import javax.naming.RefAddr;
+import javax.naming.spi.ObjectFactory;
+
+/**
+ * Factory class that creates a JNDI named javamail MimePartDataSource
+ * object which can be used for sending email using SMTP.
+ * <p>
+ * Can be configured in the DefaultContext or Context scope
+ * of your server.xml configuration file.
+ * <p>
+ * Example:
+ * <p>
+ * <pre>
+ * &lt;Resource name="mail/send" auth="CONTAINER"
+ *           type="javax.mail.internet.MimePartDataSource"/>
+ * &lt;ResourceParams name="mail/send">
+ *   &lt;parameter>&lt;name>factory&lt;/name>
+ *     &lt;value>org.apache.directory.naming.factory.SendMailFactory&lt;/value>
+ *   &lt;/parameter>
+ *   &lt;parameter>&lt;name>mail.smtp.host&lt;/name>
+ *     &lt;value>your.smtp.host&lt;/value>
+ *   &lt;/parameter>
+ *   &lt;parameter>&lt;name>mail.smtp.user&lt;/name>
+ *     &lt;value>someuser&lt;/value>
+ *   &lt;/parameter>
+ *   &lt;parameter>&lt;name>mail.from&lt;/name>
+ *     &lt;value>someuser@some.host&lt;/value>
+ *   &lt;/parameter>
+ *   &lt;parameter>&lt;name>mail.smtp.sendpartial&lt;/name>
+ *     &lt;value>true&lt;/value>
+ *   &lt;/parameter>
+ *  &lt;parameter>&lt;name>mail.smtp.dsn.notify&lt;/name>
+ *     &lt;value>FAILURE&lt;/value>
+ *   &lt;/parameter>
+ *   &lt;parameter>&lt;name>mail.smtp.dsn.ret&lt;/name>
+ *     &lt;value>FULL&lt;/value>
+ *   &lt;/parameter>
+ * &lt;/ResourceParams>
+ * </pre>
+ *
+ * @author Glenn Nielsen Rich Catlett
+ */
+
+public class SendMailFactory implements ObjectFactory 
+{
+    // The class name for the javamail MimeMessageDataSource
+    protected final String DataSourceClassName = 
+	"javax.mail.internet.MimePartDataSource";
+
+    public Object getObjectInstance(Object RefObj, Name Nm, Context Ctx,
+				    Hashtable Env) throws Exception 
+    {
+	final Reference Ref = (Reference)RefObj;
+
+	// Creation of the DataSource is wrapped inside a doPrivileged
+	// so that javamail can read its default properties without
+	// throwing Security Exceptions
+	if (Ref.getClassName().equals(DataSourceClassName)) {
+	    return AccessController.doPrivileged( new PrivilegedAction()
+	    {
+		public Object run() {
+        	    // set up the smtp session that will send the message
+	            Properties props = new Properties();
+		    // enumeration of all refaddr
+		    Enumeration list = Ref.getAll();
+		    // current refaddr to be set
+		    RefAddr refaddr;
+	            // set transport to smtp
+	            props.put("mail.transport.protocol", "smtp");
+
+		    while (list.hasMoreElements()) {
+			refaddr = (RefAddr)list.nextElement();
+
+			// set property
+			props.put(refaddr.getType(), (String)refaddr.getContent());
+		    }
+		    MimeMessage message = new MimeMessage(
+			Session.getInstance(props));
+		    try {
+			String from = (String)Ref.get("mail.from").getContent();
+		        message.setFrom(new InternetAddress(from));
+		        message.setSubject("");
+		    } catch (Exception e) {}
+		    MimePartDataSource mds = new MimePartDataSource(
+			(MimePart)message);
+		    return mds;
+		}
+	    } );
+	}
+	else { // We can't create an instance of the DataSource
+	    return null;
+	}
+    }
+}

Added: incubator/directory/naming/trunk/factory/src/java/org/apache/directory/naming/factory/TransactionFactory.java
==============================================================================
--- (empty file)
+++ incubator/directory/naming/trunk/factory/src/java/org/apache/directory/naming/factory/TransactionFactory.java	Sun Dec  7 13:00:05 2003
@@ -0,0 +1,169 @@
+/*
+ * $Header: /home/cvs/jakarta-commons-sandbox/naming/factory/src/java/org/apache/commons/naming/factory/TransactionFactory.java,v 1.2 2003/10/13 08:15:11 rdonkin Exp $
+ * $Revision: 1.2 $
+ * $Date: 2003/10/13 08:15:11 $
+ *
+ * ====================================================================
+ *
+ * The Apache Software License, Version 1.1
+ *
+ * Copyright (c) 1999 The Apache Software Foundation.  All rights 
+ * reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. The end-user documentation included with the redistribution, if
+ *    any, must include the following acknowledgement:
+ *       "This product includes software developed by the 
+ *        Apache Software Foundation (http://www.apache.org/)."
+ *    Alternately, this acknowledgement may appear in the software itself,
+ *    if and wherever such third-party acknowledgements normally appear.
+ *
+ * 4. The names "The Jakarta Project", "Tomcat", and "Apache Software
+ *    Foundation" must not be used to endorse or promote products derived
+ *    from this software without prior written permission. For written 
+ *    permission, please contact apache@apache.org.
+ *
+ * 5. Products derived from this software may not be called "Apache"
+ *    nor may "Apache" appear in their names without prior written
+ *    permission of the Apache Software Foundation.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation.  For more
+ * information on the Apache Software Foundation, please see
+ * <http://www.apache.org/>.
+ *
+ * [Additional notices, if required by prior licensing conditions]
+ *
+ */ 
+
+
+package org.apache.directory.naming.factory;
+
+import java.util.Hashtable;
+import javax.naming.Name;
+import javax.naming.Context;
+import javax.naming.NamingException;
+import javax.naming.Reference;
+import javax.naming.RefAddr;
+import javax.naming.spi.ObjectFactory;
+import org.apache.directory.naming.TransactionRef;
+
+/**
+ * Object factory for User trasactions.
+ * 
+ * @author Remy Maucherat
+ * @version $Revision: 1.2 $ $Date: 2003/10/13 08:15:11 $
+ */
+
+public class TransactionFactory
+    implements ObjectFactory {
+
+
+    // ----------------------------------------------------------- Constructors
+
+
+    // -------------------------------------------------------------- Constants
+
+
+    // ----------------------------------------------------- Instance Variables
+
+
+    // --------------------------------------------------------- Public Methods
+
+
+    // -------------------------------------------------- ObjectFactory Methods
+
+
+    /**
+     * Crete a new User transaction instance.
+     * 
+     * @param obj The reference object describing the DataSource
+     */
+    public Object getObjectInstance(Object obj, Name name, Context nameCtx,
+                                    Hashtable environment)
+        throws Exception {
+        
+        if (obj instanceof TransactionRef) {
+            Reference ref = (Reference) obj;
+            ObjectFactory factory = null;
+            RefAddr factoryRefAddr = ref.get(Constants.FACTORY);
+            if (factoryRefAddr != null) {
+                // Using the specified factory
+                String factoryClassName = 
+                    factoryRefAddr.getContent().toString();
+                // Loading factory
+                ClassLoader tcl = 
+                    Thread.currentThread().getContextClassLoader();
+                Class factoryClass = null;
+                if (tcl != null) {
+                    try {
+                        factoryClass = tcl.loadClass(factoryClassName);
+                    } catch(ClassNotFoundException e) {
+                    }
+                } else {
+                    try {
+                        factoryClass = Class.forName(factoryClassName);
+                    } catch(ClassNotFoundException e) {
+                    }
+                }
+                if (factoryClass != null) {
+                    try {
+                        factory = (ObjectFactory) factoryClass.newInstance();
+                    } catch(Throwable t) {
+                    }
+                }
+            } else {
+                // Defaults to Tyrex
+                String javaxTransactionUserTransactionFactoryClassName =
+                    System.getProperty
+                    ("javax.transaction.UserTransaction.Factory",
+                     Constants.TYREX_TRANSACTION_FACTORY);
+                try {
+                    factory = (ObjectFactory) Class.forName
+                        (javaxTransactionUserTransactionFactoryClassName)
+                        .newInstance();
+                } catch(Throwable t) {
+                }
+            }
+            if (factory != null) {
+                return factory.getObjectInstance
+                    (obj, name, nameCtx, environment);
+            } else {
+                throw new NamingException
+                    ("Cannot create resource instance");
+            }
+            
+        }
+        
+        return null;
+        
+    }
+
+
+}
+

Added: incubator/directory/naming/trunk/factory/src/java/org/apache/directory/naming/factory/TyrexFactory.java
==============================================================================
--- (empty file)
+++ incubator/directory/naming/trunk/factory/src/java/org/apache/directory/naming/factory/TyrexFactory.java	Sun Dec  7 13:00:05 2003
@@ -0,0 +1,180 @@
+/*
+ * $Header: /home/cvs/jakarta-commons-sandbox/naming/factory/src/java/org/apache/commons/naming/factory/TyrexFactory.java,v 1.3 2003/11/30 05:16:47 psteitz Exp $
+ * $Revision: 1.3 $
+ * $Date: 2003/11/30 05:16:47 $
+ *
+ * ====================================================================
+ *
+ * The Apache Software License, Version 1.1
+ *
+ * Copyright (c) 1999 The Apache Software Foundation.  All rights
+ * reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. The end-user documentation included with the redistribution, if
+ *    any, must include the following acknowledgement:
+ *       "This product includes software developed by the
+ *        Apache Software Foundation (http://www.apache.org/)."
+ *    Alternately, this acknowledgement may appear in the software itself,
+ *    if and wherever such third-party acknowledgements normally appear.
+ *
+ * 4. The names "The Jakarta Project", "Tomcat", and "Apache Software
+ *    Foundation" must not be used to endorse or promote products derived
+ *    from this software without prior written permission. For written
+ *    permission, please contact apache@apache.org.
+ *
+ * 5. Products derived from this software may not be called "Apache"
+ *    nor may "Apache" appear in their names without prior written
+ *    permission of the Apache Software Foundation.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation.  For more
+ * information on the Apache Software Foundation, please see
+ * <http://www.apache.org/>.
+ *
+ * [Additional notices, if required by prior licensing conditions]
+ *
+ */
+
+
+package org.apache.directory.naming.factory;
+
+import java.net.URL;
+import javax.naming.InitialContext;
+import javax.naming.NamingException;
+import javax.naming.spi.ObjectFactory;
+import tyrex.tm.TransactionDomain;
+import tyrex.tm.DomainConfigurationException;
+import tyrex.tm.RecoveryException;
+
+/**
+ * Abstract superclass of any factory that creates objects from Tyrex.
+ * <p>
+ * Subclasses can use getTransactionDomain() to handle the retrieval and
+ * creation of the TransactionDomain.</p>
+ * <p>
+ * Tyrex is an open-source transaction manager, developed by Assaf Arkin and
+ * exolab.org. See the <a href="http://tyrex.exolab.org/">Tyrex homepage</a>
+ * for more details about Tyrex and downloads.</p>
+ *
+ * @author David Haraburda
+ * @version $Revision: 1.3 $ $Date: 2003/11/30 05:16:47 $
+ */
+
+public abstract class TyrexFactory implements ObjectFactory {
+
+
+    // ----------------------------------------------------------- Constructors
+
+
+    // -------------------------------------------------------------- Constants
+
+
+    // ----------------------------------------------------- Instance Variables
+
+
+    // ------------------------------------------------------ Protected Methods
+
+
+    /**
+     * Get (and if necessary, create) the active TransactionDomain
+     *
+     * This class checks to see if there is already a TransactionDomain
+     * setup and instantiated.  If so, it is returned, otherwise one is
+     * created and initialized using properties obtained from JNDI.
+     */
+    protected TransactionDomain getTransactionDomain() throws NamingException {
+        TransactionDomain domain = null;
+        InitialContext initCtx = new InitialContext();
+        String config = initCtx.lookup("java:comp/env/" +
+            Constants.TYREX_DOMAIN_CONFIG).toString();
+        String name = initCtx.lookup("java:comp/env/" +
+            Constants.TYREX_DOMAIN_NAME).toString();
+        if (config != null && name != null) {
+            try {
+                domain = TransactionDomain.getDomain(name);
+            } catch(Throwable t) {
+                // Tyrex throws exceptions if required classes aren't found.
+                log("Error loading Tyrex TransactionDomain", t);
+                throw new NamingException
+                    ("Exception loading TransactionDomain: " + t.getMessage());
+            }
+            if ((domain == null)
+                || (domain.getState() == TransactionDomain.TERMINATED)) {
+                URL configURL = Thread.currentThread().getContextClassLoader()
+                    .getResource(config);
+                if (configURL == null)
+                    throw new NamingException
+                        ("Could not load Tyrex domain config file");
+                try {
+                    domain = 
+                        TransactionDomain.createDomain(configURL.toString());
+                } catch(DomainConfigurationException dce) {
+                    throw new NamingException
+                        ("Could not create TransactionDomain: " 
+                         + dce.getMessage());
+                }
+            }
+
+        } else {
+            throw new NamingException
+                ("Specified config file or domain name "
+                 + "parameters are invalid.");
+        }
+
+        if (domain.getState() == TransactionDomain.READY) {
+            try {
+                domain.recover();
+            } catch( RecoveryException re ) {
+                throw new NamingException
+                    ("Could not activate TransactionDomain: " 
+                     + re.getMessage() );
+            }
+        }
+
+        return domain;
+    }
+
+
+
+    // -------------------------------------------------------- Private Methods
+
+
+    private void log(String message) {
+        System.out.print("TyrexFactory:  ");
+        System.out.println(message);
+    }
+
+
+    private void log(String message, Throwable exception) {
+        log(message);
+        exception.printStackTrace(System.out);
+    }
+
+
+}

Added: incubator/directory/naming/trunk/factory/src/java/org/apache/directory/naming/factory/TyrexResourceFactory.java
==============================================================================
--- (empty file)
+++ incubator/directory/naming/trunk/factory/src/java/org/apache/directory/naming/factory/TyrexResourceFactory.java	Sun Dec  7 13:00:05 2003
@@ -0,0 +1,181 @@
+/*
+ * $Header: /home/cvs/jakarta-commons-sandbox/naming/factory/src/java/org/apache/commons/naming/factory/TyrexResourceFactory.java,v 1.3 2003/11/30 05:16:47 psteitz Exp $
+ * $Revision: 1.3 $
+ * $Date: 2003/11/30 05:16:47 $
+ *
+ * ====================================================================
+ *
+ * The Apache Software License, Version 1.1
+ *
+ * Copyright (c) 1999 The Apache Software Foundation.  All rights
+ * reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. The end-user documentation included with the redistribution, if
+ *    any, must include the following acknowledgement:
+ *       "This product includes software developed by the
+ *        Apache Software Foundation (http://www.apache.org/)."
+ *    Alternately, this acknowledgement may appear in the software itself,
+ *    if and wherever such third-party acknowledgements normally appear.
+ *
+ * 4. The names "The Jakarta Project", "Tomcat", and "Apache Software
+ *    Foundation" must not be used to endorse or promote products derived
+ *    from this software without prior written permission. For written
+ *    permission, please contact apache@apache.org.
+ *
+ * 5. Products derived from this software may not be called "Apache"
+ *    nor may "Apache" appear in their names without prior written
+ *    permission of the Apache Software Foundation.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation.  For more
+ * information on the Apache Software Foundation, please see
+ * <http://www.apache.org/>.
+ *
+ * [Additional notices, if required by prior licensing conditions]
+ *
+ */
+
+
+package org.apache.directory.naming.factory;
+
+import java.util.Hashtable;
+import java.util.Iterator;
+import javax.naming.Name;
+import javax.naming.Context;
+import javax.naming.NamingException;
+import javax.naming.Reference;
+import javax.naming.RefAddr;
+import javax.naming.spi.ObjectFactory;
+import java.net.URL;
+import org.apache.directory.naming.ResourceRef;
+import tyrex.tm.TransactionDomain;
+import tyrex.resource.Resources;
+import tyrex.resource.ResourceConfig;
+
+/**
+ * Object factory for Tyrex Resources.
+ * <p>
+ * This class retrieves Tyrex resources that are configured in the
+ * TransactionDomain.  The type of Resource returned is specified in
+ * Tyrex's domain configuration file.</p>
+ * <p>
+ * Tyrex is an open-source transaction manager, developed by Assaf Arkin and
+ * exolab.org. See the <a href="http://tyrex.exolab.org/">Tyrex homepage</a>
+ * for more details about Tyrex and downloads.</p>
+ *
+ * @author David Haraburda
+ * @version $Revision: 1.3 $ $Date: 2003/11/30 05:16:47 $
+ */
+
+public class TyrexResourceFactory
+    extends TyrexFactory {
+
+
+    // ----------------------------------------------------------- Constructors
+
+
+    // -------------------------------------------------------------- Constants
+
+
+    public static final String RESOURCE_NAME = "name";
+    public static final String DEFAULT_RESOURCE_NAME = "tomcat";
+
+
+    // ----------------------------------------------------- Instance Variables
+
+
+    // --------------------------------------------------------- Public Methods
+
+
+    // -------------------------------------------------- ObjectFactory Methods
+
+
+    /**
+     * Create a new Resource instance.  The type of Resource is dependant
+     * upon Tyrex's domain configuration.
+     *
+     * @param obj The reference object describing the Resource
+     */
+    public Object getObjectInstance(Object obj, Name name, Context nameCtx,
+                                    Hashtable environment)
+        throws NamingException {
+
+        if (obj instanceof ResourceRef) {
+            Reference ref = (Reference) obj;
+
+            if (ref.getClassName().equals("tyrex.resource.Resource")) {
+
+                try {
+
+                    Resources resources = 
+                        getTransactionDomain().getResources();
+                    RefAddr nameAddr = ref.get(RESOURCE_NAME);
+                    if (nameAddr != null) {
+                        return resources
+                            .getResource(nameAddr.getContent().toString())
+                            .getClientFactory();
+                    } else {
+                        return resources.getResource(DEFAULT_RESOURCE_NAME)
+                            .getClientFactory();
+                    }
+
+                } catch (Throwable t) {
+                    log("Cannot create Tyrex Resource, Exception", t);
+                    throw new NamingException
+                        ("Exception creating Tyrex Resource: " 
+                         + t.getMessage());
+                }
+
+            }
+
+        }
+
+        return null;
+
+    }
+
+
+    // -------------------------------------------------------- Private Methods
+
+
+    private void log(String message) {
+        System.out.print("TyrexResourceFactory:  ");
+        System.out.println(message);
+    }
+
+
+    private void log(String message, Throwable exception) {
+        log(message);
+        exception.printStackTrace(System.out);
+    }
+
+
+}
+
+

Added: incubator/directory/naming/trunk/factory/src/java/org/apache/directory/naming/factory/TyrexTransactionFactory.java
==============================================================================
--- (empty file)
+++ incubator/directory/naming/trunk/factory/src/java/org/apache/directory/naming/factory/TyrexTransactionFactory.java	Sun Dec  7 13:00:05 2003
@@ -0,0 +1,159 @@
+/*
+ * $Header: /home/cvs/jakarta-commons-sandbox/naming/factory/src/java/org/apache/commons/naming/factory/TyrexTransactionFactory.java,v 1.3 2003/11/30 05:16:47 psteitz Exp $
+ * $Revision: 1.3 $
+ * $Date: 2003/11/30 05:16:47 $
+ *
+ * ====================================================================
+ *
+ * The Apache Software License, Version 1.1
+ *
+ * Copyright (c) 1999 The Apache Software Foundation.  All rights 
+ * reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. The end-user documentation included with the redistribution, if
+ *    any, must include the following acknowledgement:
+ *       "This product includes software developed by the 
+ *        Apache Software Foundation (http://www.apache.org/)."
+ *    Alternately, this acknowledgement may appear in the software itself,
+ *    if and wherever such third-party acknowledgements normally appear.
+ *
+ * 4. The names "The Jakarta Project", "Tomcat", and "Apache Software
+ *    Foundation" must not be used to endorse or promote products derived
+ *    from this software without prior written permission. For written 
+ *    permission, please contact apache@apache.org.
+ *
+ * 5. Products derived from this software may not be called "Apache"
+ *    nor may "Apache" appear in their names without prior written
+ *    permission of the Apache Software Foundation.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation.  For more
+ * information on the Apache Software Foundation, please see
+ * <http://www.apache.org/>.
+ *
+ * [Additional notices, if required by prior licensing conditions]
+ *
+ */ 
+
+
+package org.apache.directory.naming.factory;
+
+import java.net.URL;
+import java.util.Hashtable;
+import javax.naming.Name;
+import javax.naming.Context;
+import javax.naming.NamingException;
+import javax.naming.Reference;
+import javax.naming.RefAddr;
+import javax.naming.spi.ObjectFactory;
+import javax.transaction.UserTransaction;
+
+import org.apache.directory.naming.TransactionRef;
+
+import tyrex.tm.TransactionDomain;
+
+/**
+ * Object factory for Tyrex User transactions.
+ * <p>
+ * Tyrex is an open-source transaction manager, developed by Assaf Arkin and
+ * exolab.org. See the <a href="http://tyrex.exolab.org/">Tyrex homepage</a>
+ * for more details about Tyrex and downloads.</p>
+ * 
+ * @author David Haraburda
+ * @author Remy Maucherat
+ * @version $Revision: 1.3 $ $Date: 2003/11/30 05:16:47 $
+ */
+
+public class TyrexTransactionFactory
+    extends TyrexFactory {
+
+
+    // ----------------------------------------------------------- Constructors
+
+
+    // -------------------------------------------------------------- Constants
+
+
+    // ----------------------------------------------------- Instance Variables
+
+
+    // --------------------------------------------------------- Public Methods
+
+
+    // -------------------------------------------------- ObjectFactory Methods
+
+
+    /**
+     * Crete a new UserTransaction.
+     * 
+     * @param obj The reference object
+     */
+    public Object getObjectInstance(Object obj, Name name, Context nameCtx,
+                                    Hashtable environment)
+        throws NamingException {
+        
+        if (obj instanceof TransactionRef) {
+            Reference ref = (Reference) obj;
+            if (ref.getClassName()
+                .equals("javax.transaction.UserTransaction")) {
+                
+                try {
+                    return getTransactionDomain().getUserTransaction();
+                } catch (Throwable t) {
+                    log("Cannot create Transaction, Exception", t);
+                    throw new NamingException
+                        ("Exception creating Transaction: " + t.getMessage());
+                }
+                
+            }
+            
+        }
+        
+        return null;
+        
+    }
+
+
+    // -------------------------------------------------------- Private Methods
+
+
+    private void log(String message) {
+        System.out.print("TyrexTransactionFactory:  ");
+        System.out.println(message);
+    }
+
+
+    private void log(String message, Throwable exception) {
+        log(message);
+        exception.printStackTrace(System.out);
+    }
+
+
+}
+

Added: incubator/directory/naming/trunk/factory/src/java/org/apache/directory/naming/factory/package.html
==============================================================================
--- (empty file)
+++ incubator/directory/naming/trunk/factory/src/java/org/apache/directory/naming/factory/package.html	Sun Dec  7 13:00:05 2003
@@ -0,0 +1,7 @@
+<body>
+
+<p>This package contains object factories used by the naming service.</p>
+
+<p></p>
+
+</body>

Added: incubator/directory/naming/trunk/factory/src/test/org/apache/directory/naming/config/XmlConfiguratorTest.java
==============================================================================
--- (empty file)
+++ incubator/directory/naming/trunk/factory/src/test/org/apache/directory/naming/config/XmlConfiguratorTest.java	Sun Dec  7 13:00:05 2003
@@ -0,0 +1,168 @@
+/*
+ * $Header: /home/cvs/jakarta-commons-sandbox/naming/factory/src/test/org/apache/commons/naming/config/XmlConfiguratorTest.java,v 1.2 2003/12/01 02:02:45 brett Exp $
+ * $Revision: 1.2 $
+ * $Date: 2003/12/01 02:02:45 $
+ *
+ * ====================================================================
+ *
+ * The Apache Software License, Version 1.1
+ *
+ * Copyright (c) 1999 The Apache Software Foundation.  All rights 
+ * reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. The end-user documentation included with the redistribution, if
+ *    any, must include the following acknowlegement:  
+ *       "This product includes software developed by the 
+ *        Apache Software Foundation (http://www.apache.org/)."
+ *    Alternately, this acknowlegement may appear in the software itself,
+ *    if and wherever such third-party acknowlegements normally appear.
+ *
+ * 4. The names "The Jakarta Project", "Tomcat", and "Apache Software
+ *    Foundation" must not be used to endorse or promote products derived
+ *    from this software without prior written permission. For written 
+ *    permission, please contact apache@apache.org.
+ *
+ * 5. Products derived from this software may not be called "Apache"
+ *    nor may "Apache" appear in their names without prior written
+ *    permission of the Apache Group.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation.  For more
+ * information on the Apache Software Foundation, please see
+ * <http://www.apache.org/>.
+ *
+ * [Additional notices, if required by prior licensing conditions]
+ *
+ */ 
+
+
+package org.apache.directory.naming.config;
+
+import java.sql.Connection;
+import java.sql.ResultSet;
+import java.sql.Statement;
+
+import javax.naming.Context;
+import javax.naming.InitialContext;
+import javax.sql.DataSource;
+
+import junit.framework.TestCase;
+
+/**
+ * Test case for the XML configuration methods, testing environment entries
+ * and database connection resource factories.
+ * 
+ * @author <a href="brett@apache.org">Brett Porter</a>
+ * @version $Id: XmlConfiguratorTest.java,v 1.2 2003/12/01 02:02:45 brett Exp $
+ */
+public class XmlConfiguratorTest extends TestCase
+{
+    public XmlConfiguratorTest(String name) {
+        super(name);
+    }
+
+    /*
+     * @see TestCase#setUp()
+     */
+    protected void setUp() throws Exception {
+        super.setUp();
+        XmlConfigurator.loadConfiguration(getClass().getResourceAsStream("/test-jndi.xml"));
+    }
+
+    /*
+     * @see TestCase#tearDown()
+     */
+    protected void tearDown() throws Exception {
+        super.tearDown();
+        XmlConfigurator.destroyInitialContext();
+    }
+
+    /**
+     * Test for correctly configured environment entries.
+     * @throws Exception as tests do
+     */
+    public void testEnvironment() throws Exception {
+        Context ctx = new InitialContext();
+        Context env = (Context) ctx.lookup("java:comp/env");
+        String host = (String) env.lookup("config/host");
+        Integer port = (Integer) env.lookup("config/port");
+
+        assertEquals("Check host", "www.apache.org", host);
+        assertEquals("Check port", new Integer(80), port);
+    }
+  
+    /**
+     *  Test config as a subcontext of a different root.
+     *  @throws Exception if it fails
+     */
+    public void testDuplicateSubcontextName() throws Exception {
+        Context ctx = new InitialContext();
+        Context env = (Context) ctx.lookup("java:comp/env");
+        String user = (String) env.lookup("jdbc/config/pool/user");
+
+        assertEquals("Check user", "dbuser", user);
+    }
+
+    /**
+     * Test for correctly configured and operational database connection
+     * resource factories.
+     * @throws Exception as tests do
+     */
+    public void testJdbc() throws Exception {
+        Context ctx = new InitialContext();
+        Context env = (Context) ctx.lookup("java:comp/env");
+        DataSource ds = (DataSource) env.lookup("jdbc/pool");
+        Connection con = null;
+        Statement stat = null; 
+        ResultSet rs = null;
+        try {
+            con = ds.getConnection();
+            stat = con.createStatement();
+            stat.executeUpdate("DROP TABLE DUAL IF EXISTS");
+            stat.executeUpdate("CREATE TABLE DUAL(value char(50))");
+            stat.executeUpdate("INSERT INTO DUAL VALUES(1)");
+            rs = stat.executeQuery("SELECT * FROM DUAL");
+            while (rs.next()) {
+               assertEquals("Check you get back what you put into the DB", 1, rs.getInt(1));
+            }
+        }
+        finally {
+            if (rs != null) { 
+                rs.close(); 
+            }
+            if (stat != null) { 
+                stat.close(); 
+            }
+            if (con != null) { 
+                con.close(); 
+            }
+        }
+    }
+}
+

Added: incubator/directory/naming/trunk/factory/src/test/test-jndi.xml
==============================================================================
--- (empty file)
+++ incubator/directory/naming/trunk/factory/src/test/test-jndi.xml	Sun Dec  7 13:00:05 2003
@@ -0,0 +1,33 @@
+<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/port" value="80" type="java.lang.Integer" />
+
+    <environment name="jdbc/config/pool/user" value="dbuser" type="java.lang.String" />
+
+    <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>
+</naming>

Added: incubator/directory/naming/trunk/maven.log
==============================================================================
--- (empty file)
+++ incubator/directory/naming/trunk/maven.log	Sun Dec  7 13:00:05 2003
@@ -0,0 +1,6 @@
+2003-12-07 13:37:43,223 INFO  com.werken.werkz.jelly.PostGoalTag - Running post goal: clean:clean
+2003-12-07 13:37:43,306 INFO  org.apache.maven.verifier.DependencyVerifier - Attempting to download commons-naming-core-SNAPSHOT.jar.
+2003-12-07 13:37:44,928 INFO  com.werken.werkz.jelly.PostGoalTag - Running post goal: clean:clean
+2003-12-07 13:37:44,955 INFO  org.apache.maven.cli.App - Total time: 5 seconds
+2003-12-07 13:37:44,972 INFO  org.apache.maven.cli.App - Finished at: Sun Dec 07 13:37:44 MST 2003
+2003-12-07 13:37:44,990 INFO  org.apache.maven.cli.App - 

Added: incubator/directory/naming/trunk/project.properties
==============================================================================
--- (empty file)
+++ incubator/directory/naming/trunk/project.properties	Sun Dec  7 13:00:05 2003
@@ -0,0 +1,9 @@
+maven.checkstyle.properties=checkstyle.xml
+maven.junit.fork=true
+maven.xdoc.date = left
+maven.xdoc.poweredby.image=maven-feather.png
+maven.multiproject.ignoreFailures=false
+maven.multiproject.navigation=aggregate
+maven.multiproject.type=jar
+maven.multiproject.includes=*/project.xml
+

Added: incubator/directory/naming/trunk/project.xml
==============================================================================
--- (empty file)
+++ incubator/directory/naming/trunk/project.xml	Sun Dec  7 13:00:05 2003
@@ -0,0 +1,165 @@
+<?xml version="1.0"?>
+<project>
+  
+  <version>3</version>
+  <name>directory-naming</name>
+  <id>directory-naming</id>
+  <groupId>directory-naming</groupId>
+  <currentVersion>SNAPSHOT</currentVersion>
+
+  <organization>
+    <name>Apache Software Foundation</name>
+    <url>http://www.apache.org</url>
+    <logo>http://incubator.apache.org/images/apache-incubator.png</logo>
+  </organization>
+  <logo></logo>
+
+  <inceptionYear>2003</inceptionYear>
+  <package>org.apache.directory.naming</package>
+
+  <shortDescription>Apache Directory Naming Component</shortDescription>
+
+  <!-- Gump integration -->
+  <gumpRepositoryId>Directory-naming</gumpRepositoryId>
+
+  <description>
+      Apache Directory Naming is a re-usable JNDI component.
+  </description>
+
+  <url>http://incubator.apache.org/directory/naming/</url>
+  <!-- <cvsWebUrl>http://cvs.apache.org/viewcvs/jakarta-commons-sandbox/naming/</cvsWebUrl>
+  <issueTrackingUrl>http://nagoya.apache.org:8080/scarab/servlet/scarab/</issueTrackingUrl> -->
+  <siteAddress>incubator.apache.org</siteAddress>
+  <siteDirectory>/www/incubator.apache.org/directory/naming/</siteDirectory>
+  <distributionDirectory>/www/incubator.apache.org/builds/directory/naming/</distributionDirectory>
+
+  <mailingLists>
+    <mailingList>
+      <name>Directory User List</name>
+      <subscribe>directory-user-subscribe@incubator.apache.org</subscribe>
+      <unsubscribe>directory-user-unsubscribe@incubator.apache.org</unsubscribe>
+      <archive>http://nagoya.apache.org:8080/eyebrowse/SummarizeList?listName=directory-user@incubator.apache.org</archive>
+    </mailingList>
+    <mailingList>
+      <name>Directory Developer List</name>
+      <subscribe>directory-dev-subscribe@incubator.apache.org</subscribe>
+      <unsubscribe>directory-dev-unsubscribe@incubator.apache.org</unsubscribe>
+      <archive>http://nagoya.apache.org:8080/eyebrowse/SummarizeList?listName=directory-dev@incubator.apache.org</archive>
+    </mailingList>
+  </mailingLists>
+
+  <developers>
+    <developer>
+      <name>Henri Yandell</name>
+      <id>bayard</id>
+      <email>bayard@apache.org</email>
+      <organization></organization>
+      <roles>
+        <role>Java Developer</role>
+      </roles>
+    </developer>
+    <developer>
+      <name>Phil Steitz</name>
+      <id>psteitz</id>
+      <email>psteitz@apache.org</email>
+      <organization></organization>
+      <roles>
+        <role>Java Developer</role>
+      </roles>
+    </developer>
+    <developer>
+      <name>Brett Porter</name>
+      <id>brett</id>
+      <email>brett@apache.org</email>
+      <organization>f2 network</organization>
+      <roles>
+        <role>Java Developer</role>
+      </roles>
+      <timezone>+10</timezone>
+    </developer>
+  </developers>
+
+
+  <!-- Need to mark these as compile-time/run-time -->
+
+  <dependencies>
+  
+    <dependency>
+      <id>commons-collections</id>
+      <version>2.1</version>
+    </dependency>
+    
+    <dependency>
+      <id>junit</id>
+      <version>3.7</version>
+    </dependency>
+    
+    <dependency>
+      <id>mx4j+jmx</id>
+      <version>1.1.1</version>
+    </dependency>
+
+  </dependencies>
+  
+  <build>
+
+    <nagEmailAddress>commons-dev@jakarta.apache.org</nagEmailAddress>
+    <sourceDirectory>${basedir}/src/java</sourceDirectory>
+    <unitTestSourceDirectory>${basedir}/src/test</unitTestSourceDirectory>
+    <integrationUnitTestSourceDirectory/>
+    <aspectSourceDirectory/>
+
+    <!-- Unit test classes -->
+    <unitTest>
+      <includes>
+        <include>**/*Test*</include>
+      </includes>
+      <resources>
+        <resource>
+          <directory>${basedir}/src/test</directory>
+          <includes>
+            <include>**/*.xml</include>
+            <include>**/*.properties</include>
+          </includes>
+        </resource>
+      </resources>
+    </unitTest>
+
+   
+    <!-- J A R  R E S O U R C E S -->
+    <!-- Resources that are packaged up inside the JAR file -->
+    <resources>
+      <resource>
+        <directory>${basedir}/src/java</directory>
+        <includes>
+          <include>**/*.properties</include>
+        </includes>
+      </resource>
+      <resource>
+        <directory>${basedir}/src/conf</directory>
+        <includes>
+          <include>**/*.dtd</include>
+        </includes>
+      </resource>
+    </resources>
+  </build>
+  
+  <reports>
+     <!-- <report>maven-changelog-plugin</report> -->
+     <!-- <report>maven-changes-plugin</report> -->
+     <report>maven-checkstyle-plugin</report>
+     <!-- <report>maven-clover-plugin</report> -->
+     <!-- <report>maven-developer-activity-plugin</report> -->
+     <!-- <report>maven-file-activity-plugin</report> -->
+     <report>maven-javadoc-plugin</report>
+     <!-- <report>maven-jellydoc-plugin</report> -->
+     <report>maven-junit-report-plugin</report>
+     <report>maven-jxr-plugin</report>
+     <!-- <report>maven-license-plugin</report> -->
+     <!-- <report>maven-linkcheck-plugin</report> -->
+     <!-- <report>maven-statcvs-plugin</report> -->
+     <report>maven-tasklist-plugin</report> 
+  </reports>
+  
+</project>
+

Added: incubator/directory/naming/trunk/velocity.log
==============================================================================
--- (empty file)
+++ incubator/directory/naming/trunk/velocity.log	Sun Dec  7 13:00:05 2003
@@ -0,0 +1,42 @@
+Sun Dec 07 13:35:45 MST 2003  [debug] AvalonLogSystem initialized using logfile 'velocity.log'
+Sun Dec 07 13:35:45 MST 2003   [info] ************************************************************** 
+Sun Dec 07 13:35:45 MST 2003   [info] Starting Jakarta Velocity v1.4-dev
+Sun Dec 07 13:35:45 MST 2003   [info] RuntimeInstance initializing.
+Sun Dec 07 13:35:45 MST 2003   [info] Default Properties File: org/apache/velocity/runtime/defaults/velocity.properties
+Sun Dec 07 13:35:45 MST 2003   [info] Trying to use logger class org.apache.velocity.runtime.log.AvalonLogSystem
+Sun Dec 07 13:35:45 MST 2003   [info] Using logger class org.apache.velocity.runtime.log.AvalonLogSystem
+Sun Dec 07 13:35:45 MST 2003   [info] Default ResourceManager initializing. (class org.apache.velocity.runtime.resource.ResourceManagerImpl)
+Sun Dec 07 13:35:45 MST 2003   [info] Resource Loader Instantiated: org.apache.velocity.runtime.resource.loader.FileResourceLoader
+Sun Dec 07 13:35:45 MST 2003   [info] FileResourceLoader : initialization starting.
+Sun Dec 07 13:35:45 MST 2003   [info] FileResourceLoader : adding path '/home/phil/.maven/plugins/maven-xdoc-plugin-1.4/plugin-resources/templates'
+Sun Dec 07 13:35:45 MST 2003   [info] FileResourceLoader : initialization complete.
+Sun Dec 07 13:35:45 MST 2003   [info] ResourceCache : initialized. (class org.apache.velocity.runtime.resource.ResourceCacheImpl)
+Sun Dec 07 13:35:45 MST 2003   [info] Default ResourceManager initialization complete.
+Sun Dec 07 13:35:45 MST 2003   [info] Loaded System Directive: org.apache.velocity.runtime.directive.Literal
+Sun Dec 07 13:35:45 MST 2003   [info] Loaded System Directive: org.apache.velocity.runtime.directive.Macro
+Sun Dec 07 13:35:45 MST 2003   [info] Loaded System Directive: org.apache.velocity.runtime.directive.Parse
+Sun Dec 07 13:35:45 MST 2003   [info] Loaded System Directive: org.apache.velocity.runtime.directive.Include
+Sun Dec 07 13:35:45 MST 2003   [info] Loaded System Directive: org.apache.velocity.runtime.directive.Foreach
+Sun Dec 07 13:35:45 MST 2003   [info] Created: 20 parsers.
+Sun Dec 07 13:35:45 MST 2003   [info] Velocimacro : initialization starting.
+Sun Dec 07 13:35:45 MST 2003   [info] Velocimacro : adding VMs from VM library template : VM_global_library.vm
+Sun Dec 07 13:35:45 MST 2003  [error] ResourceManager : unable to find resource 'VM_global_library.vm' in any resource loader.
+Sun Dec 07 13:35:45 MST 2003   [info] Velocimacro : error using  VM library template VM_global_library.vm : org.apache.velocity.exception.ResourceNotFoundException: Unable to find resource 'VM_global_library.vm'
+Sun Dec 07 13:35:45 MST 2003   [info] Velocimacro :  VM library template macro registration complete.
+Sun Dec 07 13:35:45 MST 2003   [info] Velocimacro : allowInline = true : VMs can be defined inline in templates
+Sun Dec 07 13:35:45 MST 2003   [info] Velocimacro : allowInlineToOverride = false : VMs defined inline may NOT replace previous VM definitions
+Sun Dec 07 13:35:45 MST 2003   [info] Velocimacro : allowInlineLocal = false : VMs defined inline will be  global in scope if allowed.
+Sun Dec 07 13:35:45 MST 2003   [info] Velocimacro : messages on  : VM system will output logging messages
+Sun Dec 07 13:35:45 MST 2003   [info] Velocimacro : autoload off  : VM system will not automatically reload global library macros
+Sun Dec 07 13:35:45 MST 2003   [info] Velocimacro : initialization complete.
+Sun Dec 07 13:35:45 MST 2003   [info] Velocity successfully started.
+Sun Dec 07 13:35:45 MST 2003   [info] ResourceManager : found cvs-usage.xml with loader org.apache.velocity.runtime.resource.loader.FileResourceLoader
+Sun Dec 07 13:35:45 MST 2003  [error] RHS of #set statement is null. Context will not be modified. cvs-usage.xml [line 10, column 5]
+Sun Dec 07 13:35:45 MST 2003   [info] ResourceManager : found index.xml with loader org.apache.velocity.runtime.resource.loader.FileResourceLoader
+Sun Dec 07 13:35:45 MST 2003   [info] ResourceManager : found maven-reports.xml with loader org.apache.velocity.runtime.resource.loader.FileResourceLoader
+Sun Dec 07 13:35:45 MST 2003   [info] ResourceManager : found dependencies.xml with loader org.apache.velocity.runtime.resource.loader.FileResourceLoader
+Sun Dec 07 13:35:45 MST 2003   [info] ResourceManager : found issue-tracking.xml with loader org.apache.velocity.runtime.resource.loader.FileResourceLoader
+Sun Dec 07 13:35:45 MST 2003   [info] Velocimacro : added new VM : #displayLink( label link ) : source = mail-lists.xml
+Sun Dec 07 13:35:45 MST 2003   [info] ResourceManager : found mail-lists.xml with loader org.apache.velocity.runtime.resource.loader.FileResourceLoader
+Sun Dec 07 13:35:45 MST 2003   [info] ResourceManager : found project-info.xml with loader org.apache.velocity.runtime.resource.loader.FileResourceLoader
+Sun Dec 07 13:35:45 MST 2003   [info] ResourceManager : found team-list.xml with loader org.apache.velocity.runtime.resource.loader.FileResourceLoader

Added: incubator/directory/naming/trunk/xdocs/building.xml
==============================================================================
--- (empty file)
+++ incubator/directory/naming/trunk/xdocs/building.xml	Sun Dec  7 13:00:05 2003
@@ -0,0 +1,52 @@
+<?xml version="1.0"?>
+<document>
+ <properties>
+  <title>Building Naming</title>
+ </properties>
+
+ <body>
+
+ <section name="Maven targets">
+   <p>
+     Naming consists of two subprojects: core and factory.  These can be built separately
+     by executing maven build targets from the /core or /factory directories. All subprojects can be
+     built using the following targets, executed from the top level directory/naming directory:
+     <ul>
+        <li>multiproject:clean -- cleans all subprojects</li>
+        <li>multiproject:install -- builds, tests and jars all subprojects</li>
+        <li>multiproject:site -- generates an integrated site including all subprojects</li>
+        <li>clean -- cleans top level project</li>
+     </ul>
+   </p>
+    
+ </section>
+ <section name="Dependencies">
+   <p>
+     The dependencies common to both subprojects are the ones that appear in the top level 
+     project.xml, viz.:
+     <ul>
+        <li>Common Collections 2.1</li>
+        <li>mx4j+jmx 1.1.1</li>
+        <li>junit 3.7</li>
+     </ul>
+     The core subproject has no dependencies beyond these.  The factory subproject depends on
+     core and has the following additional dependencies, specified in factory/project.xml 
+     (see <a href="multiproject/directory-naming-factory/dependencies.html">dependencies</a>):
+     <ul>
+        <li>jta-spec 1.0.1 (runtime only, must be added to local repo, 
+            since not available on ibiblio)</li>
+        <li>javamail 1.2  (must be added to local repo, since not available on ibiblio)</li>
+        <li>tyrex 1.0 </li>
+        <li>commons-dbcp 1.0 and commons-pool 1.0.1 (only required if using the default 
+            resource factory to obtain database connections)</li>
+        <li>commons-digester 1.4.1 (for reading XML configuration files)</li>
+        <li>commons-logging 1.0.3</li>
+        <li>commons-beanutils 1.6.1 (runtime only for digester)</li>
+        <li>commons-lang 1.0.1</li>
+        <li>hsqldb 1.7.1 (testing only - used to setup a simple database to perform resource factory testing)</li>
+     </ul>
+    </p>
+ </section>
+ </body>
+</document>
+

Added: incubator/directory/naming/trunk/xdocs/index.xml
==============================================================================
--- (empty file)
+++ incubator/directory/naming/trunk/xdocs/index.xml	Sun Dec  7 13:00:05 2003
@@ -0,0 +1,19 @@
+<?xml version="1.0"?>
+<document>
+ <properties>
+  <title>Naming</title>
+ </properties>
+
+ <body>
+
+ <section name="What is Naming?">
+   <p>
+     Naming is a lightweight, in-memory JNDI service provider.  The 
+     initial code base was extracted from the Jakarta Tomcat JNDI implementation.
+   </p>
+    
+ </section>
+ 
+ </body>
+</document>
+

Added: incubator/directory/naming/trunk/xdocs/navigation.xml
==============================================================================
--- (empty file)
+++ incubator/directory/naming/trunk/xdocs/navigation.xml	Sun Dec  7 13:00:05 2003
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<project name="Naming" href="http://incubator.apache.org/directory/naming/">
+
+  <title>Naming</title>
+
+  <body>
+
+    <link name="Index" href="/" />
+
+    <menu name="Naming">
+      <item name="Overview"              href="/index.html"/>
+      <item name="Building"              href="/building.html"/>
+    </menu>
+    
+    <menu name="Projects">
+    #foreach ($reactorProject in $reactorProjects)
+      <item name="$reactorProject.name" href="/${aggregateDir}${reactorProject.artifactId}/index.html"/>
+    #end
+    </menu>
+  </body>
+</project>