You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@commons.apache.org by jo...@apache.org on 2012/09/26 12:04:14 UTC

svn commit: r1390365 [1/2] - in /commons/sandbox/jndi/trunk/commons-jndi: ./ src/ src/main/ src/main/java/ src/main/java/org/ src/main/java/org/apache/ src/main/java/org/apache/commons/ src/main/java/org/apache/commons/jndi/ src/main/java/org/apache/co...

Author: jochen
Date: Wed Sep 26 10:04:12 2012
New Revision: 1390365

URL: http://svn.apache.org/viewvc?rev=1390365&view=rev
Log:
Initial import

Added:
    commons/sandbox/jndi/trunk/commons-jndi/.classpath   (with props)
    commons/sandbox/jndi/trunk/commons-jndi/.project   (with props)
    commons/sandbox/jndi/trunk/commons-jndi/pom.xml   (with props)
    commons/sandbox/jndi/trunk/commons-jndi/src/
    commons/sandbox/jndi/trunk/commons-jndi/src/main/
    commons/sandbox/jndi/trunk/commons-jndi/src/main/java/
    commons/sandbox/jndi/trunk/commons-jndi/src/main/java/org/
    commons/sandbox/jndi/trunk/commons-jndi/src/main/java/org/apache/
    commons/sandbox/jndi/trunk/commons-jndi/src/main/java/org/apache/commons/
    commons/sandbox/jndi/trunk/commons-jndi/src/main/java/org/apache/commons/jndi/
    commons/sandbox/jndi/trunk/commons-jndi/src/main/java/org/apache/commons/jndi/CommonsJNDIContextFactory.java
    commons/sandbox/jndi/trunk/commons-jndi/src/main/java/org/apache/commons/jndi/impl/
    commons/sandbox/jndi/trunk/commons-jndi/src/main/java/org/apache/commons/jndi/impl/AbstractContext.java
    commons/sandbox/jndi/trunk/commons-jndi/src/main/java/org/apache/commons/jndi/impl/ContextBindings.java
    commons/sandbox/jndi/trunk/commons-jndi/src/main/java/org/apache/commons/jndi/impl/ContextLoader.java
    commons/sandbox/jndi/trunk/commons-jndi/src/main/java/org/apache/commons/jndi/impl/ContextNames.java
    commons/sandbox/jndi/trunk/commons-jndi/src/main/java/org/apache/commons/jndi/impl/DefaultContextLoader.java
    commons/sandbox/jndi/trunk/commons-jndi/src/main/java/org/apache/commons/jndi/impl/DelegatingContext.java
    commons/sandbox/jndi/trunk/commons-jndi/src/main/java/org/apache/commons/jndi/impl/InitialMemoryContext.java
    commons/sandbox/jndi/trunk/commons-jndi/src/main/java/org/apache/commons/jndi/impl/MemoryContext.java
    commons/sandbox/jndi/trunk/commons-jndi/src/main/java/org/apache/commons/jndi/impl/SimpleNameParser.java
    commons/sandbox/jndi/trunk/commons-jndi/src/main/java/org/apache/commons/jndi/reader/
    commons/sandbox/jndi/trunk/commons-jndi/src/main/java/org/apache/commons/jndi/reader/PropertyReader.java
    commons/sandbox/jndi/trunk/commons-jndi/src/main/java/org/apache/commons/jndi/reader/StreamContextReader.java
    commons/sandbox/jndi/trunk/commons-jndi/src/main/java/org/apache/commons/jndi/reader/XmlPropertyReader.java
    commons/sandbox/jndi/trunk/commons-jndi/src/main/java/org/apache/commons/jndi/reader/XmlReader.java
    commons/sandbox/jndi/trunk/commons-jndi/src/main/java/org/apache/commons/jndi/types/
    commons/sandbox/jndi/trunk/commons-jndi/src/main/java/org/apache/commons/jndi/types/CommonsJNDIDataSource.java
    commons/sandbox/jndi/trunk/commons-jndi/src/main/java/org/apache/commons/jndi/types/ObjectWrapper.java
    commons/sandbox/jndi/trunk/commons-jndi/src/main/java/org/apache/commons/jndi/util/
    commons/sandbox/jndi/trunk/commons-jndi/src/main/java/org/apache/commons/jndi/util/Reflection.java
    commons/sandbox/jndi/trunk/commons-jndi/src/main/java/org/apache/commons/jndi/util/Strings.java
    commons/sandbox/jndi/trunk/commons-jndi/src/main/resources/
    commons/sandbox/jndi/trunk/commons-jndi/src/site/
    commons/sandbox/jndi/trunk/commons-jndi/src/site/apt/
    commons/sandbox/jndi/trunk/commons-jndi/src/site/apt/index.apt
    commons/sandbox/jndi/trunk/commons-jndi/src/site/apt/usage.apt
    commons/sandbox/jndi/trunk/commons-jndi/src/site/site.xml   (with props)
    commons/sandbox/jndi/trunk/commons-jndi/src/test/
    commons/sandbox/jndi/trunk/commons-jndi/src/test/filtered-resources/
    commons/sandbox/jndi/trunk/commons-jndi/src/test/filtered-resources/db.properties.xml
    commons/sandbox/jndi/trunk/commons-jndi/src/test/java/
    commons/sandbox/jndi/trunk/commons-jndi/src/test/java/org/
    commons/sandbox/jndi/trunk/commons-jndi/src/test/java/org/apache/
    commons/sandbox/jndi/trunk/commons-jndi/src/test/java/org/apache/commons/
    commons/sandbox/jndi/trunk/commons-jndi/src/test/java/org/apache/commons/jndi/
    commons/sandbox/jndi/trunk/commons-jndi/src/test/java/org/apache/commons/jndi/reader/
    commons/sandbox/jndi/trunk/commons-jndi/src/test/java/org/apache/commons/jndi/reader/PropertyReaderTest.java
    commons/sandbox/jndi/trunk/commons-jndi/src/test/java/org/apache/commons/jndi/types/
    commons/sandbox/jndi/trunk/commons-jndi/src/test/java/org/apache/commons/jndi/types/CommonsJNDIDataSourceTest.java
    commons/sandbox/jndi/trunk/commons-jndi/src/test/java/org/apache/commons/jndi/util/
    commons/sandbox/jndi/trunk/commons-jndi/src/test/java/org/apache/commons/jndi/util/Interface.java
    commons/sandbox/jndi/trunk/commons-jndi/src/test/java/org/apache/commons/jndi/util/ReflectionTest.java
    commons/sandbox/jndi/trunk/commons-jndi/src/test/java/org/apache/commons/jndi/util/SimpleBean.java
    commons/sandbox/jndi/trunk/commons-jndi/src/test/java/org/apache/commons/jndi/util/SubClass.java
    commons/sandbox/jndi/trunk/commons-jndi/src/test/java/org/apache/commons/jndi/util/SuperClass.java
    commons/sandbox/jndi/trunk/commons-jndi/src/test/resources/
    commons/sandbox/jndi/trunk/commons-jndi/src/test/resources/org/
    commons/sandbox/jndi/trunk/commons-jndi/src/test/resources/org/apache/
    commons/sandbox/jndi/trunk/commons-jndi/src/test/resources/org/apache/commons/
    commons/sandbox/jndi/trunk/commons-jndi/src/test/resources/org/apache/commons/jndi/
    commons/sandbox/jndi/trunk/commons-jndi/src/test/resources/org/apache/commons/jndi/reader/
    commons/sandbox/jndi/trunk/commons-jndi/src/test/resources/org/apache/commons/jndi/reader/SimpleContext.properties

Added: commons/sandbox/jndi/trunk/commons-jndi/.classpath
URL: http://svn.apache.org/viewvc/commons/sandbox/jndi/trunk/commons-jndi/.classpath?rev=1390365&view=auto
==============================================================================
Binary file - no diff available.

Propchange: commons/sandbox/jndi/trunk/commons-jndi/.classpath
------------------------------------------------------------------------------
    svn:mime-type = application/xml

Added: commons/sandbox/jndi/trunk/commons-jndi/.project
URL: http://svn.apache.org/viewvc/commons/sandbox/jndi/trunk/commons-jndi/.project?rev=1390365&view=auto
==============================================================================
Binary file - no diff available.

Propchange: commons/sandbox/jndi/trunk/commons-jndi/.project
------------------------------------------------------------------------------
    svn:mime-type = application/xml

Added: commons/sandbox/jndi/trunk/commons-jndi/pom.xml
URL: http://svn.apache.org/viewvc/commons/sandbox/jndi/trunk/commons-jndi/pom.xml?rev=1390365&view=auto
==============================================================================
Binary file - no diff available.

Propchange: commons/sandbox/jndi/trunk/commons-jndi/pom.xml
------------------------------------------------------------------------------
    svn:mime-type = application/xml

Added: commons/sandbox/jndi/trunk/commons-jndi/src/main/java/org/apache/commons/jndi/CommonsJNDIContextFactory.java
URL: http://svn.apache.org/viewvc/commons/sandbox/jndi/trunk/commons-jndi/src/main/java/org/apache/commons/jndi/CommonsJNDIContextFactory.java?rev=1390365&view=auto
==============================================================================
--- commons/sandbox/jndi/trunk/commons-jndi/src/main/java/org/apache/commons/jndi/CommonsJNDIContextFactory.java (added)
+++ commons/sandbox/jndi/trunk/commons-jndi/src/main/java/org/apache/commons/jndi/CommonsJNDIContextFactory.java Wed Sep 26 10:04:12 2012
@@ -0,0 +1,97 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.commons.jndi;
+
+import java.util.Hashtable;
+
+import javax.naming.Context;
+import javax.naming.NamingException;
+import javax.naming.spi.InitialContextFactory;
+
+import org.apache.commons.jndi.impl.ContextLoader;
+import org.apache.commons.jndi.impl.DefaultContextLoader;
+import org.apache.commons.jndi.impl.InitialMemoryContext;
+
+
+public class CommonsJNDIContextFactory implements InitialContextFactory {
+	/**
+	 * Default constructor required to get
+	 * {@link Class#newInstance()} working.
+	 */
+	public CommonsJNDIContextFactory() {
+	}
+
+	@Override
+	public Context getInitialContext(Hashtable<?,?> pEnv)
+			throws NamingException {
+		return createContext(pEnv);
+	}
+
+    private static Context createContext(Hashtable<?,?> pEnv) throws NamingException {
+		String url = requireProperty(Context.PROVIDER_URL, pEnv);
+		final Context ctx;
+		if (url.startsWith("mem:")) {
+			ctx = new InitialMemoryContext(pEnv);
+			url = url.substring("mem:".length());
+		} else {
+			throw new NamingException("Invalid JNDI provider URL, expected (mem:), got " + url);
+		}
+		final String cl = getProperty("org.apache.commons.jndi.context.loader", pEnv);
+		final ContextLoader loader;
+		if (cl == null || cl.trim().length() == 0) {
+			loader = new DefaultContextLoader();
+		} else {
+			try {
+				loader = (ContextLoader) Class.forName(cl).newInstance();
+			} catch (ClassNotFoundException e) {
+			    final NamingException ne = new NamingException("ContextLoader class" + cl
+						+ ", specified by property org.apache.commons.jndi.context.loader, not found.");
+			    ne.initCause(e);
+			    throw ne;
+			} catch (InstantiationException e) {
+				final NamingException ne = new NamingException("Unable to instantiate"
+						+ " context loader class " + cl + ": " + e.getMessage());
+				ne.initCause(e);
+				throw ne;
+			} catch (IllegalAccessException e) {
+				final NamingException ne = new NamingException("Illegal access to"
+						+ " context loader class " + cl + ": " + e.getMessage());
+				ne.initCause(e);
+				throw ne;
+			}
+		}
+		loader.load(ctx, url);
+    	return ctx;
+    }
+
+    private static String getProperty(String pProperty, Hashtable<?,?> pEnv) {
+    	final Object o = pEnv.get(pProperty);
+    	if (o == null) {
+    		return System.getProperty(pProperty);
+    	} else {
+    		return o.toString();
+    	}
+    }
+    private static String requireProperty(String pProperty, Hashtable<?,?> pEnv)
+    		throws NamingException {
+    	final String val = getProperty(pProperty, pEnv);
+    	if (val == null) {
+    		throw new NamingException("Undefined property: " + pProperty);
+    	}
+    	return val;
+    }
+}

Added: commons/sandbox/jndi/trunk/commons-jndi/src/main/java/org/apache/commons/jndi/impl/AbstractContext.java
URL: http://svn.apache.org/viewvc/commons/sandbox/jndi/trunk/commons-jndi/src/main/java/org/apache/commons/jndi/impl/AbstractContext.java?rev=1390365&view=auto
==============================================================================
--- commons/sandbox/jndi/trunk/commons-jndi/src/main/java/org/apache/commons/jndi/impl/AbstractContext.java (added)
+++ commons/sandbox/jndi/trunk/commons-jndi/src/main/java/org/apache/commons/jndi/impl/AbstractContext.java Wed Sep 26 10:04:12 2012
@@ -0,0 +1,738 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.commons.jndi.impl;
+
+import java.lang.reflect.UndeclaredThrowableException;
+import java.util.HashMap;
+import java.util.Hashtable;
+import java.util.Iterator;
+import java.util.Map;
+
+import javax.naming.Context;
+import javax.naming.ContextNotEmptyException;
+import javax.naming.InvalidNameException;
+import javax.naming.Name;
+import javax.naming.NameAlreadyBoundException;
+import javax.naming.NameNotFoundException;
+import javax.naming.NameParser;
+import javax.naming.NamingEnumeration;
+import javax.naming.NamingException;
+import javax.naming.NotContextException;
+
+import org.apache.commons.jndi.types.ObjectWrapper;
+
+/**
+ * The heart of the system, the abstract implementation of context for 
+ * simple-jndi.  There are no abstract methods in this class, but it is
+ * not meant to be instantiated, but extended instead.
+ *
+ * @author Robert M. Zigweid
+ * @since Simple-JNDI 0.11
+ * @version $Rev: 2708 $ $Date: 2010-09-19 03:09:03 +0200 (So, 19 Sep 2010) $
+ */
+@SuppressWarnings({"rawtypes", "unchecked"})
+public abstract class AbstractContext 
+        implements Cloneable, Context  {
+
+    // table is used as a read-write cache which sits 
+    // above the file-store
+    private Hashtable table = new Hashtable();
+    private Hashtable env = new Hashtable();
+    private NameParser nameParser;
+    /* 
+     * The name full name of this context. 
+     */
+    private Name nameInNamespace = null;
+    private boolean nameLock = false;
+    private boolean closing;
+
+    /* **********************************************************************
+     * Constructors.                                                        *
+     * Even though this class cannot be instantiated, it provides default   *
+     * implemenation for doing so in hopes of making Contexts that extend   *
+     * this class easier.                                                   *
+     * **********************************************************************/
+    /**
+     * Creates a AbstractContext.
+     */
+    protected AbstractContext() {
+        this((Hashtable)null);
+    }
+    
+    /**
+     * Creates a AbstractContext.
+     * 
+     * @param env a Hashtable containing the Context's environemnt.
+     */
+    protected AbstractContext(Hashtable env) {
+        /* By default allow system properties to override. */
+        this(env, true, null);
+    }
+    
+    /**
+     * Creates a AbstractContext.
+     * 
+     * @param env a Hashtable containing the Context's environment.
+     * @param systemOverride allow System Parameters to override the
+     *        environment that is passed in.
+     */
+    protected AbstractContext(Hashtable env, boolean systemOverride) {
+        this(env, systemOverride, null);
+    }
+
+    /**
+     * Creates a AbstractContext.
+     * 
+     * @param env a Hashtable containing the Context's environment.
+     * @param parser the NameParser being used by the Context.
+     */
+    protected AbstractContext(Hashtable env, NameParser parser) {
+        this(env, true, parser);
+    }
+
+    /**
+     * Creates a AbstractContext.
+     * 
+     * @param systemOverride allow System Parameters to override the
+     *        environment that is passed in.
+     */
+    protected AbstractContext(boolean systemOverride) {
+        this(null, systemOverride, null);
+    }
+
+    /**
+     * Creates a AbstractContext.
+     * 
+     * @param systemOverride allow System Parameters to override the
+     *        environment that is passed in.
+     * @param parser the NameParser being used by the Context.
+     */
+    protected AbstractContext(boolean systemOverride, NameParser parser) {
+        this(null, systemOverride, parser);
+    }
+
+    /**
+     * Creates a AbstractContext.
+     * 
+     * @param parser the NameParser being used by the Context.
+     */
+    protected AbstractContext(NameParser parser) {
+        this(null, true, parser);
+    }
+
+    /**
+     * Creates a AbstractContext.
+     * 
+     * @param env a Hashtable containing the Context's environment.
+     * @param systemOverride allow System Parameters to override the
+     *        environment that is passed in.
+     * @param parser the NameParser being used by the Context.
+     */
+    protected AbstractContext(Hashtable env, boolean systemOverride, NameParser parser) {
+        if(env != null) {
+            this.env = (Hashtable)env.clone();
+        }
+        
+        if(parser == null) {
+            try {
+                nameParser = new SimpleNameParser(this);
+            } catch (NamingException e) {
+            	throw new UndeclaredThrowableException(e);
+            }
+        }
+        try {
+            nameInNamespace = nameParser.parse("");
+        } catch (NamingException e) {
+        	throw new UndeclaredThrowableException(e);
+        }
+    }
+
+    /**
+     * Create a new context based upon the environment of the passed context.
+     * @param that
+     */
+    protected AbstractContext(AbstractContext that) {
+        this(that.env);
+    }
+
+    
+    /* **********************************************************************
+     * Implementation of methods specified by java.lang.naming.Context      *
+     * **********************************************************************/
+    /** 
+     * Return the named object.  
+     * This implementation looks for things in the following order:<br/>
+     * <ol>
+     * <li>The empty element to duplicate the context.</li>
+     * <li>A named object in the environment.</li>
+     * <li>A named object in the Context's store</li>
+     * <li>A named sub-Context of this Context</li>
+     * </ol>
+     * Unlike many implementations of the JNDI specification, this 
+     * implementation returns null when a name is not found, rather than 
+     * throwing an exception. The specification does not appear to state 
+     * which way it should be. 
+     *
+     * @see javax.naming.Context#lookup(javax.naming.Name)
+     */
+    public Object lookup(Name name) throws NamingException {
+        /* 
+         * The string form of the name will be used in several places below 
+         * if not matched in the hashtable.
+         */
+        String stringName = name.toString();
+        /*
+         * If name is empty then this context is to be cloned.  This is 
+         * required based upon the javadoc of Context.  UGH!
+         */
+        if(name.size() == 0) {
+            Object ret = null;
+            try {
+                ret = (AbstractContext)this.clone();
+            } catch(CloneNotSupportedException e) {
+            	throw new UndeclaredThrowableException(e);
+            }
+            if(ret != null) {
+                return ret;
+            }
+        }
+
+        /* Lookup system properties */
+        final String value = System.getProperty(stringName);
+        if(value != null) {
+            return value;
+        }
+
+        Name objName = name.getPrefix(1);
+        Object val = table.get(objName);
+        if (val != null  &&  val instanceof Context) {
+        	return ((Context) val).lookup(name.getSuffix(1));
+        }
+        
+        /* Lookup the object in this context */
+        if(table.containsKey(name)) {
+            val = table.get(objName);
+            return val instanceof ObjectWrapper ? ((ObjectWrapper) val).getInstance() : val;
+        }
+        
+        /* Look it up in the environment. */
+        if(env.containsKey(stringName)) {
+            return env.get(stringName);
+        }
+
+        /*
+         * XXX: Is this right?  Should a NamingException be thrown here 
+         *      instead because nothing could be found?
+         */
+        return null;
+    }
+
+    /**
+     * @see javax.naming.Context#lookup(java.lang.String)
+     */
+    public Object lookup(String name) throws NamingException {
+        return lookup(nameParser.parse(name));
+    }
+
+    /**
+     * @see javax.naming.Context#^(javax.naming.Name, java.lang.Object)
+     */
+    public void bind(Name name, Object object) throws NamingException {
+        // See the above XXX; namely we assume that JNDI isn't used to 
+        // store keys. This is here to stop the underlying Hashtable 
+        // barfing. 
+        if (object == null) {
+            return;
+        }
+
+        /* 
+         * If the name of obj doesn't start with the name of this context, 
+         * it is an error, throw a NamingException
+         */
+        if(name.size() > 1) {
+            Name prefix = name.getPrefix(1);
+            Object value = table.get(prefix);
+            if (value != null  &&  value instanceof Context) {
+            	((Context) value).bind(name.getSuffix(1), object);
+            }
+        }
+        if(name.size() == 0) {
+            throw new InvalidNameException("Cannot bind to an empty name");
+        }
+        /* Determine if the name is already bound */
+        if(table.containsKey(name)) {
+            throw new javax.naming.NameAlreadyBoundException("Name " + name.toString()
+                + " already bound to object " + table.get(name)
+                + " Use rebind() to override");
+        }
+        if (env.contains(name.toString())) {
+            throw new javax.naming.NameAlreadyBoundException("Name " + name.toString()
+                    + " already bound to property " + env.get(name.toString()) 
+                    + " Use rebind() to override");        	
+        }
+        
+        table.put(name, object);
+    }
+
+    /**
+     * @see javax.naming.Context#bind(java.lang.String, java.lang.Object)
+     */
+    public void bind(String name, Object object) throws NamingException {
+        bind(nameParser.parse(name), object);
+    }
+
+    /**
+     * @see javax.naming.Context#rebind(javax.naming.Name, java.lang.Object)
+     */
+    public void rebind(Name name, Object object) throws NamingException {
+        if(name.isEmpty()) {
+            throw new InvalidNameException("Cannot bind to empty name");
+        }
+        /* Look up the target context first. */
+        Object targetContext = lookup(name.getPrefix(name.size() - 1));
+        if(targetContext == null || !(targetContext instanceof Context)) {
+            throw new NamingException("Cannot bind object.  Target context does not exist.");
+        }
+        unbind(name);
+        bind(name, object);
+    }
+
+    /**
+     * @see javax.naming.Context#rebind(java.lang.String, java.lang.Object)
+     */
+    public void rebind(String name, Object object) throws NamingException {
+        rebind(nameParser.parse(name), object);
+    }
+
+    /**
+     * @see javax.naming.Context#unbind(javax.naming.Name)
+     */
+    public void unbind(Name name) throws NamingException {
+        if(name.isEmpty()) {
+            throw new InvalidNameException("Cannot unbind an empty name");
+        }
+
+        if(name.size() == 1) {
+            if(table.containsKey(name)) {
+                table.remove(name);
+            }
+            return;
+        }
+        
+        /* Look up the target context first. */
+        Object targetContext = lookup(name.getPrefix(name.size() - 1));
+        if(targetContext == null || !(targetContext instanceof Context)) {
+            throw new NamingException("Cannot unbind object.  Target context does not exist.");
+        }
+        ((Context)targetContext).unbind(name.getSuffix(name.size() - 1));
+    }
+
+    /**
+     * @see javax.naming.Context#unbind(java.lang.String)
+     */
+    public void unbind(String name) throws NamingException {
+        unbind(nameParser.parse(name));
+    }
+
+    /**
+     * @see javax.naming.Context#rename(javax.naming.Name, javax.naming.Name)
+     */
+    public void rename(Name oldName, Name newName) throws NamingException {
+        /* Confirm that this works.  We might have to catch the exception */
+        Object old = lookup(oldName);
+        if(newName.isEmpty()) {
+            throw new InvalidNameException("Cannot bind to empty name");
+        }
+        
+        if(old == null) {
+            throw new NamingException("Name '" + oldName + "' not found.");
+        }
+
+        /* If the new name is bound throw a NameAlreadyBoundException */
+        if(lookup(newName) != null) {
+            throw new NameAlreadyBoundException("Name '" + newName + "' already bound");
+        }
+
+        unbind(oldName);
+        unbind(newName);
+        bind(newName, old);
+    }
+
+    /**
+     * @see javax.naming.Context#rename(java.lang.String, java.lang.String)
+     */
+    public void rename(String oldName, String newName) throws NamingException {
+        rename(nameParser.parse(oldName), nameParser.parse(newName));
+    }
+    /* End of Write-functionality */
+
+    /* Start of List functionality */
+    /**
+     * @see javax.naming.Context#list(javax.naming.Name)
+     */
+    public NamingEnumeration list(Name name) throws NamingException {
+//      if name is a directory, we should do the same as we do above
+//      if name is a properties file, we should return the keys (?)
+//      issues: default.properties ?
+        if(name == null || name.isEmpty()) {
+            /* 
+             * Because there are two mappings that need to be used here, 
+             * create a new mapping and add the two maps to it.  This also 
+             * adds the safety of cloning the two maps so the original is
+             * unharmed.
+             */
+            Map enumStore = new HashMap();
+            enumStore.putAll(env);
+            enumStore.putAll(table);
+            NamingEnumeration enumerator = new ContextNames(enumStore);
+            return enumerator;
+        }
+        /* Look for a subcontext */
+        Name subName = name.getPrefix(1);
+        Object value = table.get(subName);
+        if(value != null) {
+        	if (value instanceof Context) {
+        		return ((Context) value).list(name.getSuffix(1));
+        	} else {
+        		/* Nope, actual object */
+        		throw new NotContextException(name + " cannot be listed");
+        	}
+        }
+
+        /* 
+         * Couldn't find the subcontext and it wasn't pointing at us, throw
+         * an exception.
+         */
+        throw new NamingException("Name not found, or not a subcontext:" + name);
+    }
+
+
+    /**
+     * @see javax.naming.Context#list(java.lang.String)
+     */
+    public NamingEnumeration list(String name) throws NamingException {
+        return list(nameParser.parse(name));
+    }
+
+    /**
+     * @see javax.naming.Context#listBindings(javax.naming.Name)
+     */
+    public NamingEnumeration listBindings(Name name) throws NamingException {
+        if(name == null || name.isEmpty()) {
+            /* 
+             * Because there are two mappings that need to be used here, 
+             * create a new mapping and add the two maps to it.  This also 
+             * adds the safety of cloning the two maps so the original is
+             * unharmed.
+             */
+            Map enumStore = new HashMap();
+            enumStore.putAll(env);
+            enumStore.putAll(table);
+            return new ContextBindings(enumStore);
+        }
+        /* Look for a subcontext */
+        Name subName = name.getPrefix(1);
+        Object value = table.get(subName);
+        if (value != null) {
+        	if (value instanceof Context) {
+                return ((Context)value).listBindings(name.getSuffix(1));        		
+        	} else {
+                throw new NamingException("Not a subcontext:" + subName);
+        	}
+        }
+        /* 
+         * Couldn't find the subcontext and it wasn't pointing at us, throw
+         * an exception.
+         */
+        throw new NamingException("Name not found, or not a subcontext:" + name);
+    }
+
+    /**
+     * @see javax.naming.Context#listBindings(java.lang.String)
+     */
+	public NamingEnumeration listBindings(String name) throws NamingException {
+        return listBindings(nameParser.parse(name));
+    }
+    /* End of List functionality */
+
+    /**
+     * @see javax.naming.Context#destroySubcontext(javax.naming.Name)
+     */
+    public void destroySubcontext(Name name) throws NamingException {
+    	Context subContext = null;
+    	Object value;
+    	Name prefix;
+        if(name.size() > 1) {
+        	prefix = name.getPrefix(1);
+        	value = table.get(prefix);
+            /* TODO: Better message might be necessary */
+            throw new NameNotFoundException();
+        } else {
+        	prefix = name;
+        	value = table.get(name);
+        }
+        if (value != null) {
+        	if (value instanceof Context) {
+        		subContext = (Context) value;
+        	}
+    		throw new NamingException("Not a subcontext: " + prefix);
+        }
+        if (subContext == null) {
+        	throw new NamingException("Name not found: " + prefix);
+        }
+        /* Look to see if the context is empty */
+        NamingEnumeration names = subContext.list("");
+        if(names.hasMore()) {
+        	throw new ContextNotEmptyException();
+        }
+        subContext.close();
+        table.remove(prefix);
+    }
+
+    /**
+     * @see javax.naming.Context#destroySubcontext(java.lang.String)
+     */
+    public void destroySubcontext(String name) throws NamingException {
+        destroySubcontext(nameParser.parse(name));
+    }
+
+    /**
+     * @see javax.naming.Context#createSubcontext(javax.naming.Name)
+     */
+    public Context createSubcontext(Name name) throws NamingException {
+        if(name.size() > 1) {
+        	Object value = table.get(name.getPrefix(1));
+        	if (value == null) {
+                throw new NameNotFoundException("The subcontext " + name.getPrefix(1) + " was not found.");
+        	} else if (value instanceof Context) {
+                return ((Context) value).createSubcontext(name.getSuffix(1));
+            } else {
+            	throw new NamingException("Not a subcontext: " +  name.getPrefix(1));
+            }
+        }
+        
+        if (lookup(name) != null) {
+            throw new NameAlreadyBoundException("Name already bound: " + name);
+        }
+
+        Name contextName = getNameParser(getNameInNamespace())
+            .parse(getNameInNamespace());
+        contextName.addAll(name);
+        MemoryContext newContext = new MemoryContext(this);
+        newContext.setNameInNamespace(contextName);
+        table.put(name, newContext);
+        return newContext;
+    }
+    
+    /**
+     * @see javax.naming.Context#createSubcontext(java.lang.String)
+     */
+    public Context createSubcontext(String name) throws NamingException {
+        return createSubcontext(nameParser.parse(name));
+    }
+    
+
+    /**
+     * @see javax.naming.Context#lookupLink(javax.naming.Name)
+     */
+    public Object lookupLink(Name name) throws NamingException {
+        return lookup(name);
+    }
+
+    /**
+     * @see javax.naming.Context#lookupLink(java.lang.String)
+     */
+    public Object lookupLink(String name) throws NamingException {
+        return lookup(nameParser.parse(name));
+    }
+
+    /**
+     * @see javax.naming.Context#getNameParser(javax.naming.Name)
+     */
+    public NameParser getNameParser(Name name) throws NamingException {
+        /* 
+         * XXX: Not sure this conditional is adequate.  It might still cause
+         *      problems with foo.foo name structures.
+         */
+        if (name == null ||
+            name.isEmpty() || 
+            (name.size() == 1 && name.toString().equals(getNameInNamespace()))) {
+            return nameParser;
+        }
+        Name subName = name.getPrefix(1);
+        Object value = table.get(subName);
+        if (value != null  &&  (value instanceof Context)) {
+            return ((Context)value).getNameParser(name.getSuffix(1));
+        }
+        throw new NotContextException("Name not found, or not a context: " + name);
+    }
+
+    /**
+     * @see javax.naming.Context#getNameParser(java.lang.String)
+     */
+    public NameParser getNameParser(String name) throws NamingException {
+        return getNameParser(nameParser.parse(name));
+    }
+
+    /**
+     * @see javax.naming.Context#composeName(javax.naming.Name, javax.naming.Name)
+     */
+    public Name composeName(Name name, Name prefix) throws NamingException {
+        // XXX: NO IDEA IF THIS IS RIGHT
+        if(name == null || prefix == null) {
+            throw new NamingException("Arguments must not be null");
+        }
+        Name retName = (Name)prefix.clone();
+        retName.addAll(name);
+        return retName;
+    }
+
+    /**
+     * @see javax.naming.Context#composeName(java.lang.String, java.lang.String)
+     */
+    public String composeName(String name, String prefix) throws NamingException {
+        Name retName = composeName(nameParser.parse(name), nameParser.parse(prefix));
+        /* toString pretty much is guaranteed to exist */
+        return retName.toString();
+    }
+
+    /**
+     * @see javax.naming.Context#addToEnvironment(java.lang.String, java.lang.Object)
+     */
+    public Object addToEnvironment(String name, Object object) throws NamingException {
+        if(this.env == null) {
+            return null;
+        }
+        return this.env.put(name, object);
+    }
+
+    /**
+     * @see javax.naming.Context#removeFromEnvironment(java.lang.String)
+     */
+    public Object removeFromEnvironment(String name) throws NamingException {
+        if(this.env == null) {
+            return null;
+        }
+        return this.env.remove(name);
+    }
+
+    /**
+     * @see javax.naming.Context#getEnvironment()
+     */
+    public Hashtable getEnvironment() throws NamingException {
+        if(this.env == null) {
+            return new Hashtable();
+        }
+        return (Hashtable)this.env.clone();
+    }
+
+    /**
+     * @see javax.naming.Context#close()
+     */
+    public void close() throws NamingException {
+        /* Don't try anything if we're already in the process of closing */
+        // BUG: closing is never actually set
+        if(closing) {
+            return;
+        }
+        Iterator it = table.entrySet().iterator();
+        while(it.hasNext()) {
+        	Map.Entry entry = (Map.Entry) it.next();
+        	Name key = (Name) entry.getKey();
+        	Object value = (Object) entry.getValue();
+        	if (value != null  &&  value instanceof Context) {
+        		((Context) value).close();
+        	}
+    		it.remove();
+        }
+        this.env = null;
+        this.table = null;
+    }
+
+    /**
+     * @see javax.naming.Context#getNameInNamespace()
+     */
+    public String getNameInNamespace() throws NamingException {
+        return nameInNamespace.toString();
+    }
+
+    /* **********************************************************************
+     * Implementation other methods used by the Context.                    *
+     * **********************************************************************/
+    /**
+     * Determine whether or not the context is empty.  Objects bound directly
+     * to the context or subcontexts are all that is considered.  The 
+     * environment of the context is not considered.
+     *    
+     * @return true of the context is empty, else false.
+     */
+    public boolean isEmpty() {
+        return (table.size() > 0);
+    }
+
+    /**
+     * Set the name of the Context.  This is only used from createSubcontext. 
+     * It might get replaced by adding more constructors, but there is really
+     * no reason to expose it publicly anyway.
+     * 
+     * @param name the Name of the context.
+     * @throws NamingException if the subContext already has a name.
+     */
+    public void setNameInNamespace(Name name) throws NamingException {
+        if(nameLock) {
+            if(nameInNamespace != null || !nameInNamespace.isEmpty()) {
+                throw new NamingException("Name already set.");
+            }
+        }
+        nameInNamespace = name;
+        nameLock = true;
+    }
+    
+    /**
+     * Set the name of the Context.  This is only used from createSubcontext. 
+     * It might get replaced by adding more constructors, but there is really
+     * no reason to expose it publicly anyway.
+     * 
+     * @param name a String representation of the Name of the context.
+     * @throws NamingException if the subContext already has a name.
+     */
+    protected void setNameInNamespace(String name) throws NamingException {
+        setNameInNamespace(nameParser.parse(name));
+    }
+
+    /**
+     * Convenience method returning the subcontexts that this context parents.
+     * @return a Hashtable of context objects that are parented by this 
+     *         context.
+     */
+    protected Hashtable getSubContexts() {
+    	final Hashtable t = new Hashtable();
+    	Iterator it =table.entrySet().iterator();
+    	while(it != null) {
+        	Map.Entry entry = (Map.Entry) it.next();
+        	Name key = (Name) entry.getKey();
+        	Object value = (Object) entry.getValue();
+        	if (value != null  &&  value instanceof Context) {
+        		t.put(key, value);
+        	}
+    	}
+    	return t;
+    }
+
+}
+
+

Added: commons/sandbox/jndi/trunk/commons-jndi/src/main/java/org/apache/commons/jndi/impl/ContextBindings.java
URL: http://svn.apache.org/viewvc/commons/sandbox/jndi/trunk/commons-jndi/src/main/java/org/apache/commons/jndi/impl/ContextBindings.java?rev=1390365&view=auto
==============================================================================
--- commons/sandbox/jndi/trunk/commons-jndi/src/main/java/org/apache/commons/jndi/impl/ContextBindings.java (added)
+++ commons/sandbox/jndi/trunk/commons-jndi/src/main/java/org/apache/commons/jndi/impl/ContextBindings.java Wed Sep 26 10:04:12 2012
@@ -0,0 +1,122 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.commons.jndi.impl;
+
+import java.util.Iterator;
+import java.util.Map;
+
+import javax.naming.Binding;
+import javax.naming.NamingEnumeration;
+import javax.naming.NamingException;
+
+/**
+ * This class represents a NamingEnumeration of the bindings of a Context. 
+ * Originally authored by Henri Yandell and modified to make more flexable with other 
+ * Context implementations.
+ * 
+ * @author Robert M. Zigweid and Henri Yandell
+ */
+@SuppressWarnings("rawtypes")
+public class ContextBindings implements NamingEnumeration {
+    
+    /**
+     * A Map of the bindings of a Context.
+     */
+	private Map bindings = null;
+    
+    /**
+     * The iterator utilized in the Enumeration
+     */
+    private Iterator iterator = null;
+
+    /**
+     * Creates a ContextBindings object based upon an a Map of names and the objects 
+     * the names are bound to.  If <code>table</code> is modified after instantiation 
+     * of ContextBindings, behavior is undefined and should be considered invalid.
+     * 
+     * @param table The table upon which the ContextBindings is based.
+     */
+    public ContextBindings(Map table) {
+        bindings = table;
+        iterator = bindings.keySet().iterator();
+    }
+
+    /**
+     * Returns <code>true</code> if there are more elements available, otherwise
+     * <code>false</code>.
+     * 
+     * @return <code>true</code> if there are more elements available, otherwise <code>
+     *         false</code>
+     */
+    public boolean hasMoreElements() {
+        return iterator.hasNext();
+    }
+
+    /**
+     * Returns <code>true</code> if there are more elements available, otherwise
+     * <code>false</code>.
+     * 
+     * @return <code>true</code> if there are more elements available, otherwise <code>
+     *         false</code>
+     * @throws NamingException if a naming exception is encountered
+     */
+    public boolean hasMore() throws NamingException {
+        if(bindings == null) {
+            throw new NamingException();
+        }
+        return hasMoreElements();
+    }
+
+    /**
+     * Returns a {@link Binding Binding} created from the next available name.
+     * 
+     * @return a Binding representing the binding of the name and the object bound to the
+     *         name
+     */
+    public Object nextElement() {
+        if(bindings == null) { 
+            return null;
+        }
+        Object name = iterator.next();
+        /* What comes out of the iterator should be a CompoundName */
+        return new Binding(name.toString(), bindings.get(name));
+    }
+
+    /**
+     * Returns a {@link Binding Binding} created from the next available name.
+     * 
+     * @return a Binding representing the binding of the name and the object bound to the
+     *         name
+     * @throws NamingException if a naming exception occurs
+     */
+    public Object next() throws NamingException {
+        if(bindings == null) {
+            throw new NamingException();
+        }
+        return nextElement();
+    }
+
+    /**
+     * Close the ContextBindings instance, rendering it inoperable.
+     */
+    public void close() {
+        bindings = null;
+        iterator = null;
+    }
+
+}
+

Added: commons/sandbox/jndi/trunk/commons-jndi/src/main/java/org/apache/commons/jndi/impl/ContextLoader.java
URL: http://svn.apache.org/viewvc/commons/sandbox/jndi/trunk/commons-jndi/src/main/java/org/apache/commons/jndi/impl/ContextLoader.java?rev=1390365&view=auto
==============================================================================
--- commons/sandbox/jndi/trunk/commons-jndi/src/main/java/org/apache/commons/jndi/impl/ContextLoader.java (added)
+++ commons/sandbox/jndi/trunk/commons-jndi/src/main/java/org/apache/commons/jndi/impl/ContextLoader.java Wed Sep 26 10:04:12 2012
@@ -0,0 +1,24 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.commons.jndi.impl;
+
+import javax.naming.Context;
+import javax.naming.NamingException;
+
+public interface ContextLoader {
+	void load(Context pCtx, String pURL) throws NamingException;
+}

Added: commons/sandbox/jndi/trunk/commons-jndi/src/main/java/org/apache/commons/jndi/impl/ContextNames.java
URL: http://svn.apache.org/viewvc/commons/sandbox/jndi/trunk/commons-jndi/src/main/java/org/apache/commons/jndi/impl/ContextNames.java?rev=1390365&view=auto
==============================================================================
--- commons/sandbox/jndi/trunk/commons-jndi/src/main/java/org/apache/commons/jndi/impl/ContextNames.java (added)
+++ commons/sandbox/jndi/trunk/commons-jndi/src/main/java/org/apache/commons/jndi/impl/ContextNames.java Wed Sep 26 10:04:12 2012
@@ -0,0 +1,71 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.commons.jndi.impl;
+
+import java.util.Map;
+
+import javax.naming.Binding;
+import javax.naming.NameClassPair;
+import javax.naming.NamingException;
+
+/**
+ * This class represents a NamingEnumeration of the class names of a Context. 
+ * Originally authored by Henri Yandell and modified to make more flexable with other 
+ * Context implementations.
+ * 
+ * @author Robert M. Zigweid and Henri Yandell
+ * @version $Rev: 1978 $ $Date: 2005-08-30 03:30:33 +0200 (Di, 30 Aug 2005) $
+ */
+public class ContextNames extends ContextBindings {
+
+    /**
+     * Creates a ContextNames object based upon an a Map of names and the objects 
+     * the names are bound to.  If <code>table</code> is modified after instantiation 
+     * of ContextBindings, behavior is undefined and should be considered invalid.
+     * 
+     * @param table The table upon which the ContextBindings is based.
+     */
+    public ContextNames(Map<?,?> table) {
+        super(table);
+    }
+
+    /**
+     * Returns a {@link NameClassPair} created from the next available name.
+     * 
+     * @return a NameClassPair representing the binding of the name and the
+     *         object bound to the name
+     */
+    public Object nextElement() {
+        return super.nextElement();
+    }
+
+    /**
+     * Returns a {@link NameClassPair} created from the next available name.
+     * 
+     * @return a NameClassPair representing the binding of the name and the
+     *         object bound to the name
+     * 
+     * @throws NamingException if a naming exception occurs
+     */
+    public Object next() throws NamingException {
+        Binding binding = null;
+        binding = (Binding)super.next();
+        return new NameClassPair(binding.getName(), 
+            binding.getObject().getClass().getName());
+    }
+}
+

Added: commons/sandbox/jndi/trunk/commons-jndi/src/main/java/org/apache/commons/jndi/impl/DefaultContextLoader.java
URL: http://svn.apache.org/viewvc/commons/sandbox/jndi/trunk/commons-jndi/src/main/java/org/apache/commons/jndi/impl/DefaultContextLoader.java?rev=1390365&view=auto
==============================================================================
--- commons/sandbox/jndi/trunk/commons-jndi/src/main/java/org/apache/commons/jndi/impl/DefaultContextLoader.java (added)
+++ commons/sandbox/jndi/trunk/commons-jndi/src/main/java/org/apache/commons/jndi/impl/DefaultContextLoader.java Wed Sep 26 10:04:12 2012
@@ -0,0 +1,116 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.commons.jndi.impl;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.MalformedURLException;
+import java.net.URL;
+
+import javax.naming.Context;
+import javax.naming.NamingException;
+
+import org.apache.commons.jndi.reader.PropertyReader;
+import org.apache.commons.jndi.reader.StreamContextReader;
+import org.apache.commons.jndi.reader.XmlPropertyReader;
+import org.apache.commons.jndi.reader.XmlReader;
+
+
+/**
+ * Default implementation of {@link ContextLoader}. Implements the following logic:
+ * <p>
+ * <ul>
+ *   <li>If the String {@code pURL} points to a file, reads the context
+ *     from the given file.</li>
+ *   <li>Otherwise, converts {@code pURL} into an instance of {@link java.net.URL},
+ *     and reads the context from that URL.</li>
+ *   <li>More precisely, the context is read by an instance of
+ *     {@link StreamContextReader}. The readers type depends on {@code pURL},
+ *     like this:
+ *     <ul>
+ *       <li>If the file name, or URL path ends with ".properties.xml",
+ *         uses an instance of {@link XmlPropertyReader}. In other words,
+ *         the stream is expected to contain a property file in XML
+ *         format, as specified by <a href="http://java.sun.com/dtd/properties.dtd">the Java properties DTD</a>.
+ *       <li>Otherwise, if the file name, or URL path, ends with ".xml",
+ *       uses an instance of {@link XmlReader}. In other words, the
+ *         stream is expected to contain an XMl file, as specified by the
+ *         Commons JNDI XSD.</li>
+ *       <li>Otherwise, uses an instance of {@link PropertyReader}. In other
+ *       words, the stream is expected to contain a standard property file,
+ *       as specified by {@link java.util.Properties}.
+ * @author jwi
+ */
+public class DefaultContextLoader implements ContextLoader {
+
+	@Override
+	public void load(Context pCtx, String pURL) throws NamingException {
+		final File f = new File(pURL);
+		final URL url;
+		try {
+			if (f.isFile()) {
+				url = f.toURI().toURL();
+			} else if (pURL.startsWith("resource://")) {
+				final String res = pURL.substring("resource://".length()+1);
+				url = Thread.currentThread().getContextClassLoader().getResource(res);
+				if (url == null) {
+					throw new NamingException("Unable to locate resource: " + res
+							+ " via ContextClassLoader");
+				}
+			} else {
+				url = new URL(pURL);
+			}
+		} catch (MalformedURLException e) {
+			throw new NamingException("Invalid URL for loading context: " + pURL);
+		}
+		final StreamContextReader scr;
+		final String p = url.getPath();
+		if (p == null) {
+			scr = new PropertyReader();
+		} else if (p.endsWith(".properties.xml")) {
+			scr = new XmlPropertyReader();
+		} else if (p.endsWith(".xml")) {
+			scr = new XmlReader();
+		} else {
+			scr = new PropertyReader();
+		}
+		InputStream is = null;
+		NamingException ne = null;
+		try {
+			is = url.openStream();
+			scr.load(pCtx, is);
+			is.close();
+			is = null;
+		} catch (IOException e) {
+			ne = new NamingException("Failed to read context from URL "
+					+ url + ": " + e.getMessage());
+			ne.initCause(e);
+		} catch (NamingException e) {
+			ne = e;
+		} finally {
+			if (is != null) {
+				try { is.close(); } catch (Throwable t) { /* Ignore me */ }
+				
+			}
+		}
+		if (ne != null) {
+			throw ne;
+		}
+	}
+
+}

Added: commons/sandbox/jndi/trunk/commons-jndi/src/main/java/org/apache/commons/jndi/impl/DelegatingContext.java
URL: http://svn.apache.org/viewvc/commons/sandbox/jndi/trunk/commons-jndi/src/main/java/org/apache/commons/jndi/impl/DelegatingContext.java?rev=1390365&view=auto
==============================================================================
--- commons/sandbox/jndi/trunk/commons-jndi/src/main/java/org/apache/commons/jndi/impl/DelegatingContext.java (added)
+++ commons/sandbox/jndi/trunk/commons-jndi/src/main/java/org/apache/commons/jndi/impl/DelegatingContext.java Wed Sep 26 10:04:12 2012
@@ -0,0 +1,192 @@
+/*
+ * Copyright (c) 2003-2005, Henri Yandell
+ * All rights reserved.
+ * 
+ * Redistribution and use in source and binary forms, with or 
+ * without modification, are permitted provided that the 
+ * following conditions are met:
+ * 
+ * + Redistributions of source code must retain the above copyright notice, 
+ *   this list of conditions and the following disclaimer.
+ * 
+ * + 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.
+ * 
+ * + Neither the name of Simple-JNDI nor the names of its contributors 
+ *   may be used to endorse or promote products derived from this software 
+ *   without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
+ * AND ANY EXPRESS 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 COPYRIGHT OWNER OR 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.
+ */
+package org.apache.commons.jndi.impl;
+
+import java.util.Hashtable;
+
+import javax.naming.Context;
+import javax.naming.Name;
+import javax.naming.NameParser;
+import javax.naming.NamingEnumeration;
+import javax.naming.NamingException;
+
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/**
+ * Standard delegating pattern for JNDI Contexts.
+ * Sub-classes of this may filter calls to the JNDI code. 
+ */
+public abstract class DelegatingContext implements Context {
+
+    private Context target;
+
+    public DelegatingContext(Context ctxt) {
+        this.target = ctxt;
+    }
+
+    public Object lookup(Name name) throws NamingException {
+        return this.target.lookup(name);
+    }
+
+    public Object lookup(String name) throws NamingException {
+        return this.target.lookup(name);
+    }
+
+    public void bind(Name name, Object value) throws NamingException {
+        this.target.bind(name, value);
+    }
+
+    public void bind(String name, Object value) throws NamingException {
+        this.target.bind(name, value);
+    }
+
+    public void rebind(Name name, Object value) throws NamingException {
+        this.target.rebind(name, value);
+    }
+
+    public void rebind(String name, Object value) throws NamingException {
+        this.target.rebind(name, value);
+    }
+
+    public void unbind(Name name) throws NamingException {
+        this.target.unbind(name);
+    }
+
+    public void unbind(String name) throws NamingException {
+        this.target.unbind(name);
+    }
+
+    public void rename(Name name, Name name2) throws NamingException {
+        this.target.rename(name, name2);
+    }
+
+    public void rename(String name, String name2) throws NamingException {
+        this.target.rename(name, name2);
+    }
+
+    public NamingEnumeration list(Name name) throws NamingException {
+        return this.target.list(name);
+    }
+
+    public NamingEnumeration list(String name) throws NamingException {
+        return this.target.list(name);
+    }
+
+    public NamingEnumeration listBindings(Name name) throws NamingException {
+        return this.target.listBindings(name);
+    }
+
+    public NamingEnumeration listBindings(String name) throws NamingException {
+        return this.target.listBindings(name);
+    }
+
+    public void destroySubcontext(Name name) throws NamingException {
+        this.target.destroySubcontext(name);
+    }
+
+    public void destroySubcontext(String name) throws NamingException {
+        this.target.destroySubcontext(name);
+    }
+
+    public Context createSubcontext(Name name) throws NamingException {
+        return this.target.createSubcontext(name);
+    }
+
+    public Context createSubcontext(String name) throws NamingException {
+        return this.target.createSubcontext(name);
+    }
+
+    public Object lookupLink(Name name) throws NamingException {
+        return this.target.lookupLink(name);
+    }
+
+    public Object lookupLink(String name) throws NamingException {
+        return this.target.lookupLink(name);
+    }
+
+    public NameParser getNameParser(Name name) throws NamingException {
+        return this.target.getNameParser(name);
+    }
+
+    public NameParser getNameParser(String name) throws NamingException {
+        return this.target.getNameParser(name);
+    }
+
+    public Name composeName(Name name, Name name2) throws NamingException {
+        return this.target.composeName(name, name2);
+    }
+
+    public String composeName(String name, String name2) throws NamingException {
+        return this.target.composeName(name, name2);
+    }
+
+    public Object addToEnvironment(String key, Object value) throws NamingException {
+        return this.target.addToEnvironment(key, value);
+    }
+
+    public Object removeFromEnvironment(String key) throws NamingException {
+        return this.target.removeFromEnvironment(key);
+    }
+
+    public Hashtable<?,?> getEnvironment() throws NamingException {
+        return this.target.getEnvironment();
+    }
+
+    public void close() throws NamingException {
+        this.target.close();
+    }
+
+    public String getNameInNamespace() throws NamingException {
+        return this.target.getNameInNamespace();
+    }
+
+    protected Context getTarget() {
+        return this.target;
+    }
+
+}
+

Added: commons/sandbox/jndi/trunk/commons-jndi/src/main/java/org/apache/commons/jndi/impl/InitialMemoryContext.java
URL: http://svn.apache.org/viewvc/commons/sandbox/jndi/trunk/commons-jndi/src/main/java/org/apache/commons/jndi/impl/InitialMemoryContext.java?rev=1390365&view=auto
==============================================================================
--- commons/sandbox/jndi/trunk/commons-jndi/src/main/java/org/apache/commons/jndi/impl/InitialMemoryContext.java (added)
+++ commons/sandbox/jndi/trunk/commons-jndi/src/main/java/org/apache/commons/jndi/impl/InitialMemoryContext.java Wed Sep 26 10:04:12 2012
@@ -0,0 +1,31 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.commons.jndi.impl;
+
+import java.util.Hashtable;
+
+import javax.naming.NamingException;
+
+public class InitialMemoryContext extends DelegatingContext {
+	public InitialMemoryContext() throws NamingException {
+		super(new MemoryContext());
+	}
+
+	public InitialMemoryContext(Hashtable<?,?> pEnv) throws NamingException {
+		super(new MemoryContext(pEnv));
+	}
+}

Added: commons/sandbox/jndi/trunk/commons-jndi/src/main/java/org/apache/commons/jndi/impl/MemoryContext.java
URL: http://svn.apache.org/viewvc/commons/sandbox/jndi/trunk/commons-jndi/src/main/java/org/apache/commons/jndi/impl/MemoryContext.java?rev=1390365&view=auto
==============================================================================
--- commons/sandbox/jndi/trunk/commons-jndi/src/main/java/org/apache/commons/jndi/impl/MemoryContext.java (added)
+++ commons/sandbox/jndi/trunk/commons-jndi/src/main/java/org/apache/commons/jndi/impl/MemoryContext.java Wed Sep 26 10:04:12 2012
@@ -0,0 +1,37 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.commons.jndi.impl;
+
+import java.util.Hashtable;
+
+
+@SuppressWarnings({ "unchecked" })
+public class MemoryContext extends AbstractContext {
+	public MemoryContext() {
+		super();
+		// TODO Auto-generated constructor stub
+	}
+
+	public MemoryContext(AbstractContext pParent) {
+		super(pParent);
+		// TODO Auto-generated constructor stub
+	}
+
+	public MemoryContext(Hashtable<?,?> pEnv) {
+		super(pEnv);
+	}
+}

Added: commons/sandbox/jndi/trunk/commons-jndi/src/main/java/org/apache/commons/jndi/impl/SimpleNameParser.java
URL: http://svn.apache.org/viewvc/commons/sandbox/jndi/trunk/commons-jndi/src/main/java/org/apache/commons/jndi/impl/SimpleNameParser.java?rev=1390365&view=auto
==============================================================================
--- commons/sandbox/jndi/trunk/commons-jndi/src/main/java/org/apache/commons/jndi/impl/SimpleNameParser.java (added)
+++ commons/sandbox/jndi/trunk/commons-jndi/src/main/java/org/apache/commons/jndi/impl/SimpleNameParser.java Wed Sep 26 10:04:12 2012
@@ -0,0 +1,79 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.commons.jndi.impl;
+
+import java.util.Hashtable;
+import java.util.Properties;
+
+import javax.naming.CompoundName;
+import javax.naming.Context;
+import javax.naming.InvalidNameException;
+import javax.naming.Name;
+import javax.naming.NameParser;
+import javax.naming.NamingException;
+
+/**
+ * The NameParser for the Simple-JNDI.  
+ * 
+ * @author Robert M. Zigweid
+ * @version $LastChangedRevision $ $LastChangedDate: 2007-06-25 04:01:53 +0200 (Mo, 25 Jun 2007) $
+ * @since OSJava Threads 2.0
+ */
+@SuppressWarnings("rawtypes")
+public class SimpleNameParser implements NameParser {
+    /*
+     * The properties utilized by the SimpleNameParser when constructing new
+     * names.
+     */
+    private final Properties props;
+    
+    /**
+     * Creates a ThreadNameParser.  Any relevant information that is needed, 
+     * such as the environment that is passed to {@link CompoundName CompundName}
+     * objects that are created.
+     * 
+     * @param parent ThreadContext that utilizes the name parser.
+     * @throws NamingException if a naming exception is found.
+     */
+	@SuppressWarnings("unchecked")
+	public SimpleNameParser(Context pParent) throws NamingException {
+        /* Properties from the parent context are in a HashTable. */
+        final Hashtable env = pParent.getEnvironment();
+        props = new Properties();
+        props.putAll(env);
+    }
+
+    /** 
+     * Parses a name into its components.<br/>
+     * (Copied from {@link javax.naming.NameParser#parse(java.lang.String)}
+     * 
+     * @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.
+     * @throws InvalidNameException If the name does not conform to syntax 
+     *         defined for the namespace.
+     * @throws NamingException If a naming exception was encountered.
+     */
+    public Name parse(String name) 
+        throws InvalidNameException, NamingException {
+        if(name == null) {
+            name = "";
+        }
+        Name ret = new CompoundName(name, props);
+        return ret;
+    }
+}

Added: commons/sandbox/jndi/trunk/commons-jndi/src/main/java/org/apache/commons/jndi/reader/PropertyReader.java
URL: http://svn.apache.org/viewvc/commons/sandbox/jndi/trunk/commons-jndi/src/main/java/org/apache/commons/jndi/reader/PropertyReader.java?rev=1390365&view=auto
==============================================================================
--- commons/sandbox/jndi/trunk/commons-jndi/src/main/java/org/apache/commons/jndi/reader/PropertyReader.java (added)
+++ commons/sandbox/jndi/trunk/commons-jndi/src/main/java/org/apache/commons/jndi/reader/PropertyReader.java Wed Sep 26 10:04:12 2012
@@ -0,0 +1,187 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.commons.jndi.reader;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.Enumeration;
+import java.util.Properties;
+import java.util.StringTokenizer;
+
+import javax.naming.Context;
+import javax.naming.NamingException;
+import javax.sql.DataSource;
+
+import org.apache.commons.jndi.impl.MemoryContext;
+import org.apache.commons.jndi.types.CommonsJNDIDataSource;
+import org.apache.commons.jndi.types.ObjectWrapper;
+import org.apache.commons.jndi.util.Reflection;
+import org.apache.commons.jndi.util.Strings;
+
+
+
+
+/** Reads context contents from a standard property file,
+ * as specified by {@link java.util.Properties}.
+ * The following properties are used:
+ * <p>
+ * <table>
+ *   <tr><th>Name</th><th>Description</th></tr>
+ *   <tr><th>&lt;prefix.&gt;objects</th>
+ *       <td>Contains a list of object names, which are defined in the
+ *         context. The list entries are separated by blanks, or commas.
+ *         All object names must themselves be valid property names.</td>
+ *       </tr>
+ *   <tr><th>&lt;prefix.&gt;&lt;objectName.&gt;type</th>
+ *       <td>For any context object: Specifies the objects type. Either
+ *         a fully qualified class name, or any of "datasource", "context",
+ *         "properties", "mailSession", or "resource".</td></tr>
+ *   <tr><th>&lt;prefix.&gt;&lt;objectName.&gt;name</th>
+ *       <td>Forr any context object: Specifies the objects name. This
+ *         property isn't actually required, and the default name is
+ *         &lt;objectName&gt;.</td></tr>
+ *   <tr><th>&lt;prefix.&gt;&lt;objectName.&gt;propertyName</th>
+ *         Configures the value of the property named &lt;propertyName&gt;.
+ *         </td></tr>
+ * </table> 
+ */
+public class PropertyReader implements StreamContextReader {
+	private String prefix = "";
+
+	public String getPrefix() {
+		return prefix;
+	}
+
+	public void setPrefix(String prefix) {
+		this.prefix = prefix;
+	}
+
+	@Override
+	public void load(Context pCtx, InputStream pStream) throws IOException,
+			NamingException {
+		final Properties props = new Properties();
+		load(props, pStream);
+		load(pCtx, props);
+	}
+	
+	protected void load(Context pCtx, Properties pProps)
+			throws NamingException {
+		String p = getPrefix();
+		if (p == null) {
+			p = "";
+		}
+		if (p.length() > 0  &&  p.charAt(p.length()-1) != '.') {
+			p = p + ".";
+		}
+		String objectsProp = p + "objects";
+		final String objects = (String) pProps.get(objectsProp);
+		if (objects == null) {
+			throw new NamingException("Invalid properties, expected property "
+					+ objectsProp + " to be present.");
+		}
+		final StringTokenizer st = new StringTokenizer(objects, ", \r\t\n");
+		while (st.hasMoreTokens()) {
+			String name = st.nextToken();
+			String pre = p;
+			if (name != null  && name.length() > 0) {
+				pre = pre + name + ".";
+			} else {
+				throw new NamingException("Invalid object name '" + name
+						+ "', derived from property " + objectsProp);
+			}
+			final Object o;
+			final String typeProp = pre + ":type";
+			final String type = (String) pProps.get(typeProp);
+			if (type == null) {
+				throw new NamingException("Missing object type (property"
+						+ typeProp + " for object named " + name); 
+			} else if ("datasource".equals(type)  || DataSource.class.getName().equals(type)) {
+				o = new CommonsJNDIDataSource();
+			} else if ("context".equals(type)  || Context.class.getName().equals(type)) {
+				o = new MemoryContext();
+			} else if ("string".equals(type)  ||  String.class.getName().equals(type)) {
+				o = new ObjectWrapper(){
+					private String value;
+					@SuppressWarnings("unused")
+					public String getValue() {
+						return value;
+					}
+
+					@SuppressWarnings("unused")
+					public void setValue(String value) {
+						this.value = value;
+					}
+
+					@Override
+					public Object getInstance() {
+						return value;
+					}
+				};
+			} else if (type.indexOf('.') > -1) {
+				try {
+					o = Class.forName(type).newInstance();
+				} catch (ClassNotFoundException e) {
+					final NamingException ne = new NamingException("Class not found: " + e.getMessage());
+					ne.initCause(e);
+					throw ne;
+				} catch (InstantiationException e) {
+					final NamingException ne = new NamingException("Failed to instantiate class: " + type);
+					ne.initCause(e);
+					throw ne;
+				} catch (IllegalAccessException e) {
+					final NamingException ne = new NamingException("Illegal access to class: " + type);
+					ne.initCause(e);
+					throw ne;
+				}
+			} else {
+				throw new NamingException("Invalid data type: " + type
+						+ ", expected datasource, or fully qualified class name");
+			}
+			final String nameProp = (String) pre + ":name";
+			final String realName = Strings.notEmpty((String) pProps.get(nameProp), name);
+			if (o instanceof Context) {
+				final PropertyReader reader = new PropertyReader();
+				reader.setPrefix(pre);
+				reader.load((Context) o, pProps);
+			} else {
+				Enumeration<?> en = pProps.propertyNames();
+				while (en.hasMoreElements()) {
+					String key = (String) en.nextElement();
+					if (key.startsWith(pre)) {
+						String value = pProps.getProperty(key);
+						if (key.length() > pre.length()) {
+							key = key.substring(pre.length());
+							if (key.indexOf(':') == -1  &&  key.indexOf('.') == -1) {
+								Reflection.set(o, key, value);
+							}
+						}
+					}
+				}
+			}
+			if (pCtx.lookup(realName) == null) {
+				pCtx.bind(realName, o);
+			} else {
+				pCtx.rebind(realName, o);
+			}
+		}
+	}
+
+	protected void load(Properties pProperties, InputStream pStream) throws IOException {
+		pProperties.load(pStream);
+		
+	}
+}

Added: commons/sandbox/jndi/trunk/commons-jndi/src/main/java/org/apache/commons/jndi/reader/StreamContextReader.java
URL: http://svn.apache.org/viewvc/commons/sandbox/jndi/trunk/commons-jndi/src/main/java/org/apache/commons/jndi/reader/StreamContextReader.java?rev=1390365&view=auto
==============================================================================
--- commons/sandbox/jndi/trunk/commons-jndi/src/main/java/org/apache/commons/jndi/reader/StreamContextReader.java (added)
+++ commons/sandbox/jndi/trunk/commons-jndi/src/main/java/org/apache/commons/jndi/reader/StreamContextReader.java Wed Sep 26 10:04:12 2012
@@ -0,0 +1,27 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.commons.jndi.reader;
+
+import java.io.IOException;
+import java.io.InputStream;
+
+import javax.naming.Context;
+import javax.naming.NamingException;
+
+public interface StreamContextReader {
+	void load(Context pCtx, InputStream pStream) throws IOException, NamingException;
+}

Added: commons/sandbox/jndi/trunk/commons-jndi/src/main/java/org/apache/commons/jndi/reader/XmlPropertyReader.java
URL: http://svn.apache.org/viewvc/commons/sandbox/jndi/trunk/commons-jndi/src/main/java/org/apache/commons/jndi/reader/XmlPropertyReader.java?rev=1390365&view=auto
==============================================================================
--- commons/sandbox/jndi/trunk/commons-jndi/src/main/java/org/apache/commons/jndi/reader/XmlPropertyReader.java (added)
+++ commons/sandbox/jndi/trunk/commons-jndi/src/main/java/org/apache/commons/jndi/reader/XmlPropertyReader.java Wed Sep 26 10:04:12 2012
@@ -0,0 +1,29 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.commons.jndi.reader;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.Properties;
+
+public class XmlPropertyReader extends PropertyReader {
+	@Override
+	protected void load(Properties pProperties, InputStream pStream)
+			throws IOException {
+		pProperties.loadFromXML(pStream);
+	}
+}

Added: commons/sandbox/jndi/trunk/commons-jndi/src/main/java/org/apache/commons/jndi/reader/XmlReader.java
URL: http://svn.apache.org/viewvc/commons/sandbox/jndi/trunk/commons-jndi/src/main/java/org/apache/commons/jndi/reader/XmlReader.java?rev=1390365&view=auto
==============================================================================
--- commons/sandbox/jndi/trunk/commons-jndi/src/main/java/org/apache/commons/jndi/reader/XmlReader.java (added)
+++ commons/sandbox/jndi/trunk/commons-jndi/src/main/java/org/apache/commons/jndi/reader/XmlReader.java Wed Sep 26 10:04:12 2012
@@ -0,0 +1,34 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.commons.jndi.reader;
+
+import java.io.IOException;
+import java.io.InputStream;
+
+import javax.naming.Context;
+import javax.naming.NamingException;
+
+public class XmlReader implements StreamContextReader {
+
+	@Override
+	public void load(Context pCtx, InputStream pStream) throws IOException,
+			NamingException {
+		// TODO Auto-generated method stub
+		
+	}
+
+}

Added: commons/sandbox/jndi/trunk/commons-jndi/src/main/java/org/apache/commons/jndi/types/CommonsJNDIDataSource.java
URL: http://svn.apache.org/viewvc/commons/sandbox/jndi/trunk/commons-jndi/src/main/java/org/apache/commons/jndi/types/CommonsJNDIDataSource.java?rev=1390365&view=auto
==============================================================================
--- commons/sandbox/jndi/trunk/commons-jndi/src/main/java/org/apache/commons/jndi/types/CommonsJNDIDataSource.java (added)
+++ commons/sandbox/jndi/trunk/commons-jndi/src/main/java/org/apache/commons/jndi/types/CommonsJNDIDataSource.java Wed Sep 26 10:04:12 2012
@@ -0,0 +1,132 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.commons.jndi.types;
+
+import java.io.PrintWriter;
+import java.sql.Connection;
+import java.sql.DriverManager;
+import java.sql.SQLException;
+import java.util.Properties;
+import java.util.logging.Logger;
+
+import javax.sql.DataSource;
+
+public class CommonsJNDIDataSource implements DataSource {
+	private String driver, user, password, url;
+	private Properties props;
+	int loginTimeout;
+	PrintWriter logWriter;
+
+	public String getDriver() {
+		return driver;
+	}
+
+	public void setDriver(String driver) {
+		this.driver = driver;
+	}
+
+	public String getUser() {
+		return user;
+	}
+
+	public void setUser(String user) {
+		this.user = user;
+	}
+
+	public String getPassword() {
+		return password;
+	}
+
+	public void setPassword(String password) {
+		this.password = password;
+	}
+
+	public String getUrl() {
+		return url;
+	}
+
+	public void setUrl(String url) {
+		this.url = url;
+	}
+
+	@Override
+	public PrintWriter getLogWriter() throws SQLException {
+		return logWriter;
+	}
+
+	@Override
+	public int getLoginTimeout() throws SQLException {
+		return loginTimeout;
+	}
+
+	@Override
+	public void setLogWriter(PrintWriter pLogWriter) throws SQLException {
+		logWriter = pLogWriter;
+	}
+
+	@Override
+	public void setLoginTimeout(int pLoginTimeout) throws SQLException {
+		loginTimeout = pLoginTimeout;
+	}
+
+	@Override
+	public boolean isWrapperFor(Class<?> pClass) throws SQLException {
+		return false;
+	}
+
+	@Override
+	public <T> T unwrap(Class<T> arg0) throws SQLException {
+		return null;
+	}
+
+	@Override
+	public Connection getConnection() throws SQLException {
+		return getConnection(user, password);
+	}
+
+	@Override
+	public Connection getConnection(String pUser, String pPassword)
+			throws SQLException {
+		final Properties p = props == null ? new Properties() : new Properties(props);
+		if (driver == null) {
+			throw new SQLException("Driver is null");
+		}
+		if (url == null) {
+			throw new SQLException("JDBC URL is null");
+		}
+		if (user != null) {
+			p.setProperty("user", pUser);
+		}
+		if (password != null) {
+			p.setProperty("password", pPassword);
+		}
+		try {
+			Class.forName(driver);
+		} catch (ClassNotFoundException e) {
+			throw new SQLException("Driver class not found: " + driver, e);
+		}
+		return DriverManager.getConnection(url, p);
+	}
+
+	/**
+	 * Method required by JDK 1.7, but not present in 1.6. No @Override,
+	 * so we can compile with both.
+	 */
+	public Logger getParentLogger() {
+		return Logger.getLogger("org.apache.commons.jndi");
+	}
+}

Added: commons/sandbox/jndi/trunk/commons-jndi/src/main/java/org/apache/commons/jndi/types/ObjectWrapper.java
URL: http://svn.apache.org/viewvc/commons/sandbox/jndi/trunk/commons-jndi/src/main/java/org/apache/commons/jndi/types/ObjectWrapper.java?rev=1390365&view=auto
==============================================================================
--- commons/sandbox/jndi/trunk/commons-jndi/src/main/java/org/apache/commons/jndi/types/ObjectWrapper.java (added)
+++ commons/sandbox/jndi/trunk/commons-jndi/src/main/java/org/apache/commons/jndi/types/ObjectWrapper.java Wed Sep 26 10:04:12 2012
@@ -0,0 +1,21 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.commons.jndi.types;
+
+public interface ObjectWrapper {
+	Object getInstance();
+}