donaldp     01/04/28 21:00:17

  Added:       cadastre .cvsignore build.xml
               cadastre/src/java/org/apache/avalon/cadastre
                        AbstractContext.java AbstractLocalContext.java
                        AbstractNamespace.java
                        AbstractNamingEnumeration.java
                        AbstractURLContext.java ArrayNamingEnumeration.java
                        DefaultNameParser.java DefaultNamespace.java
                        Namespace.java NamingProvider.java
                        RemoteContext.java
               cadastre/src/java/org/apache/avalon/cadastre/memory
                        MemoryContext.java MemoryInitialContextFactory.java
                        MemoryNamingEnumeration.java
               cadastre/src/java/org/apache/avalon/cadastre/rmi
                        RMIInitialContextFactory.java
                        RMINamingProvider.java
               cadastre/src/java/org/apache/avalon/cadastre/rmi/server
                        RMINamingProviderImpl.java
               cadastre/src/test/org/apache/avalon/cadastre
                        AbstractContextTestlet.java
               cadastre/src/test/org/apache/avalon/cadastre/rmi
                        RMIContextTestlet.java
               cadastre/src/test/org/apache/avalon/cadastre/rmi/server
                        Main.java
  Log:
  Check in cadestre
  A basic JNDI framework.
  
  Revision  Changes    Path
  1.1                  jakarta-commons-sandbox/cadastre/.cvsignore
  
  Index: .cvsignore
  ===================================================================
  emacs-jprj.el
  build
  dist
  
  
  
  1.1                  jakarta-commons-sandbox/cadastre/build.xml
  
  Index: build.xml
  ===================================================================
  <?xml version="1.0"?>
  
  <!--
  ==============================================================================
  
   Cadastre build file
  
  Authors:
   Peter Donald <[EMAIL PROTECTED]>
  
  ==============================================================================
  -->
  
  <project default="main" basedir=".">
  
    <!--
      Give user a chance to override without editing this file
      (and without typing -D each time he compiles it)
    -->
    <property file=".ant.properties"/>
    <property file="${user.home}/.ant.properties"/>
  
    <property name="name" value="cadastre"/>
    <property name="Name" value="Cadastre"/>
    <property name="version" value="0.01"/>
    <property name="year" value="1999-2001"/>
  
    <!--
      these are here only for those who use jikes compiler. For other
      developers this part makes no difference.
    -->
    <property name="build.compiler.emacs" value="on"/>
    <property name="build.compiler.warnings" value="true"/>
    <property name="build.compiler.pedantic" value="true"/>
    <property name="build.compiler.depend" value="true"/>
    <property name="build.compiler.fulldepend" value="true"/>
  
    <property name="debug" value="off"/>
    <property name="optimize" value="off"/>
    <property name="deprecation" value="off"/>
  
    <!--
         ===================================================================
         Set the properties for intermediate directory
         ===================================================================
    -->
    <property name="build.dir" value="build"/>
    <property name="build.lib" value="${build.dir}/lib"/>
    <property name="build.src" value="${build.dir}/src"/>
    <property name="build.classes" value="${build.dir}/classes"/>
    <property name="build.javadocs" value="${build.dir}/javadocs"/>
    <property name="build.docs" value="${build.dir}/docs"/>
    <property name="build.xdocs" value="${build.dir}/xdocs"/>
  
    <!--
         ===================================================================
         Set the properties for source directories
         ===================================================================
    -->
    <property name="src.dir" value="src"/>
    <property name="test.dir" value="${src.dir}/test"/>
    <property name="java.dir" value="${src.dir}/java"/>
    <property name="lib.dir" value="lib"/>
    <property name="docs.dir" value="docs"/>
    <property name="www.dir" value="www"/>
    <property name="javadocs.dir" value="${docs.dir}/framework/api"/>
    <property name="skins.dir" value="${src.dir}/skins"/>
    <property name="avalon.skin" value="${skins.dir}/avalon/"/>
    <property name="xdocs.dir" value="${src.dir}/xdocs"/>
    <property name="stylesheets.dir" value="${skins.dir}"/> 
  
    <property name="dist.name" value="${Name}-${version}"/>
    <property name="dist.base" value="distributions"/>
  
    <path id="project.class.path">
      <pathelement path="${java.class.path}" />
      <pathelement path="${testlet.location}" />
  <!--
      <fileset dir="${lib.dir}">
        <include name="*.jar" />
      </fileset>
  -->
      <pathelement path="${build.classes}" />
    </path>
  
    <!--
         ===================================================================
                                    Main target
         ===================================================================
    -->
    <target name="main" depends="dist-lite" />
  
    <!--
         ===================================================================
                                    Help on usage
         ===================================================================
    -->
    <target name="usage">
      <echo message=""/>
      <echo message="${Name} Build file"/>
      <echo message="-------------------------------------------------------------"/>
      <echo message=""/>
      <echo message=" available targets are:"/>
      <echo message=""/>
      <echo message="   jar          --> generates the ${Name} jar files"/>
      <echo message="   test         --> perform unit tests"/>
      <echo message="   compile      --> compiles the source code"/>
      <echo message="   javadocs     --> generates the API documentation (java 1.2+ 
only)"/>
      <echo message="   docs         --> generates the ${Name} Documentation"/>
      <echo message="   main or jars --> generates the ${Name} distribution without 
the javadocs (default)"/>
      <echo message="   dist         --> generates the ${Name} distribution"/>
      <echo message="   clean        --> cleans up the created directories"/>
      <echo message="   real-clean   --> cleans up all genereated files and 
directories"/>
      <echo message="   proposal     --> generates the ${Name} proposal distribution 
without the javadocs"/>
      <echo message=""/>
      <echo message="-------------------------------------------------------------"/>
      <echo message=""/>
    </target>
  
    <target name="help" depends="usage"/>
  
   <!--
         ===================================================================
         Set up dist properties
         ===================================================================
    -->
    <target name="setup-properties" >
  
      <property name="dist.dir" value="dist"/>
      <property name="dist.bin" value="${dist.dir}/bin"/>
      <property name="dist.apps" value="${dist.dir}/apps"/>
      <property name="dist.lib" value="${dist.dir}/lib"/>
      <property name="dist.docs" value="${dist.dir}/docs"/>
      <property name="dist.javadocs" value="${dist.dir}/docs/api"/>
  
      <property name="src.dist.dir" value="dist-src"/>
      <property name="src.dist.src" value="${src.dist.dir}/src"/>
      <property name="src.dist.docs" value="${src.dist.dir}/docs"/>
      <property name="src.dist.javadocs" value="${src.dist.dir}/docs/api"/>
      <property name="src.dist.lib" value="${src.dist.dir}/lib"/>
      <property name="src.dist.tools" value="${src.dist.dir}/tools"/>
    </target>
  
    <!--
         ===================================================================
                           Prepares the build directory
         ===================================================================
    -->
    <target name="prepare" depends="setup-properties">
      <tstamp/>
      <mkdir dir="${build.dir}"/>
  
      <available property="testlet.present" 
                 classname="org.apache.testlet.Testlet" 
                 classpathref="project.class.path" />
    </target>
  
    <!--
         ===================================================================
                          Compiles the source code
         ===================================================================
    -->
    <target name="compile" depends="prepare">
  
      <mkdir dir="${build.classes}"/>
  
      <javac srcdir="${java.dir}"
             destdir="${build.classes}"
             debug="${debug}"
             optimize="${optimize}"
             deprecation="${deprecation}">
        <classpath refid="project.class.path" />
      </javac>
  
      <javac srcdir="${test.dir}"
             destdir="${build.classes}"
             debug="${debug}"
             optimize="${optimize}"
             deprecation="${deprecation}">
        <classpath refid="project.class.path" />
        <exclude name="**/*" unless="testlet.present" />
      </javac>
  
      <rmic base="${build.classes}" 
            classname="org.apache.avalon.cadastre.rmi.server.RMINamingProviderImpl" 
            stubVersion="1.2">
        <classpath refid="project.class.path" />
      </rmic>
  
    </target>
  
    <!--
         ===================================================================
         Create the API documentation
         ===================================================================
    -->
    <target name="javadocs">
  
      <delete dir="${build.javadocs}"/>
      <mkdir dir="${build.javadocs}"/>
  
      <javadoc packagenames="org.apache.*"
               sourcepath="${java.dir}"
               destdir="${build.javadocs}">
        <classpath refid="project.class.path" />
        <doclet name="com.sun.tools.doclets.standard.Standard">
         <param name="-author"/>
         <param name="-version"/>
         <param name="-use"/>
         <param name="-doctitle" value="${Name}"/>
         <param name="-windowtitle" value="${Name} API"/>
         <param name="-bottom" 
                value="&quot;Copyright &#169; 2001 Apache Jakarta Project. All Rights 
Reserved.&quot;"/>
        </doclet>
      </javadoc>
  
    </target>
  
    <!--
         ===================================================================
                             Creates all the .jar files
         ===================================================================
    -->
    <target name="jars" depends="compile">
  
      <mkdir dir="${build.lib}"/>
      <jar jarfile="${build.lib}/cadastre.jar" basedir="${build.classes}">
        <include name="org/apache/avalon/cadastre/**"/>
        <exclude name="**/test/*"/>
      </jar>
  
    </target>
  
    <target name="dist-lite" depends="jars">
  
  <!--
      <copy file="src/script/run.sh" todir="${build.dir}" />
      <chmod perm="u+x" file="${build.dir}/run.sh" />
  -->
     
    </target>
  
    <target name="test" depends="dist-lite"> 
      <echo message="Testing ... 1. 2. 3. Testing" /> 
  
      <test showSuccess="true" showBanner="false" showTrace="true" 
forceShowTrace="true" > 
        <classpath refid="project.class.path" />
        <testlet>org.apache.avalon.cadastre.rmi.RMIContextTestlet</testlet>
      </test> 
    </target> 
  
    <!--
         ===================================================================
                   Cleans up build and distribution directories
         ===================================================================
    -->
    <target name="clean" depends="setup-properties">
      <delete dir="${build.dir}" />
      <delete dir="${dist.dir}" />
      <delete>
        <fileset dir="." includes="**/*~" defaultexcludes="no"/>
      </delete>
    </target>
  
  </project>
  
  
  
  1.1                  
jakarta-commons-sandbox/cadastre/src/java/org/apache/avalon/cadastre/AbstractContext.java
  
  Index: AbstractContext.java
  ===================================================================
  /*
   * Copyright (C) The Apache Software Foundation. All rights reserved.
   *
   * This software is published under the terms of the Apache Software License
   * version 1.1, a copy of which has been included with this distribution in
   * the LICENSE file.
   */
  package org.apache.avalon.cadastre;
  
  import java.util.Hashtable;
  import javax.naming.*;
  import javax.naming.Context;
  
  /**
   * Abstract JNDI Context that can be inherited from to 
   * provide a particular type of Context.
   *
   * @author <a href="mailto:[EMAIL PROTECTED]";>Peter Donald</a>
   * @version $Revision: 1.1 $
   */
  public abstract class AbstractContext
      implements Context
  {
      protected Hashtable  m_environment;
  
      public AbstractContext()
      {
          this( new Hashtable() );
      }
  
      public AbstractContext( final Hashtable environment )
      {
          m_environment = environment;
      }
  
      protected abstract NameParser getNameParser()
          throws NamingException;
  
      /**
       * Add a key-value pair to environment
       *
       * @param key the key
       * @param value the value
       * @return the value
       */
      public Object addToEnvironment( final String key, final Object value ) 
          throws NamingException
      {
          if( null == m_environment ) m_environment = new Hashtable( 5, 0.75f );
          return m_environment.put( key, value );
      }
  
      /**
       * Release resources associated with context.
       *
       */
      public void close() 
      {
          m_environment = null;
      }
  
      protected boolean isSelf( final Name name )
      {
          return ( name.isEmpty() || name.get( 0 ).equals( "" ) );
      }
  
      /**
       * Bind an object to a name.
       *
       * @param name the name to bind to
       * @param object the object
       * @exception NamingException if an error occurs such as bad name or invalid 
binding
       */
      public void bind( final String name, final Object object ) 
          throws NamingException
      {
          bind( getNameParser().parse( name ), object );
      }
  
      /**
       * Bind an object to a name.
       *
       * @param name the name to bind to
       * @param object the object
       * @exception NamingException if an error occurs such as bad name or invalid 
binding
       */
      public void bind( final Name name, final Object object ) 
          throws NamingException 
      {
          bind( name, object, false );
      }
  
      /**
       * Helper method to bind
       */
      protected abstract void bind( Name name, Object object, boolean rebind )
          throws NamingException;
  
      /**
       * Compose a name form a name and a prefix.
       *
       * @param name the name
       * @param prefix the prefix
       * @return the composed name
       * @exception NamingException if a badly formatted name for context
       */
      public String composeName( final String name, final String prefix ) 
          throws NamingException
      {
          final NameParser nameParser = getNameParser();
          final Name result = 
              composeName( nameParser.parse( name ), nameParser.parse( prefix ) );
          return result.toString();
      }
  
      /**
       * Compose a name form a name and a prefix.
       *
       * @param name the name
       * @param prefix the prefix
       * @return the composed name
       * @exception NamingException if a badly formatted name for context
       */
      public Name composeName( final Name name, final Name prefix ) 
          throws NamingException
      {
          final Name result = (Name)(prefix.clone());
          result.addAll( name );
          return result;
      }
  
      /**
       * Create a Subcontext.
       *
       * @param name the name of subcontext
       * @return the created context
       * @exception NamingException if an error occurs (ie context exists, badly 
formated name etc)
       */
      public Context createSubcontext( final String name ) 
          throws NamingException
      {
          return createSubcontext( getNameParser().parse( name ) );
      }
  
      /**
       * Destroy a Subcontext.
       *
       * @param name the name of subcontext to destroy
       * @exception NamingException if an error occurs such as malformed name or 
context not exiting or not empty
       */
      public void destroySubcontext( final String name ) 
          throws NamingException
      {
          destroySubcontext( getNameParser().parse( name ) );
      }
  
      /**
       * Return a copy of environment.
       *
       * @return the environment
       */
      public Hashtable getEnvironment() 
          throws NamingException
      {
          if( null == m_environment ) return new Hashtable( 3, 0.75f );
          else return (Hashtable)m_environment.clone();
      }
  
      /**
       * Get the NameParser for the named context.
       *
       * @param name 
       * @return the NameParser
       * @exception NamingException if an error occurs
       */
      public NameParser getNameParser( final String name ) 
          throws NamingException
      {
          return getNameParser( getNameParser().parse( name ) );
      }
  
      /**
       * Get the NameParser for the named context.
       *
       * @param name 
       * @return the NameParser
       * @exception NamingException if an error occurs
       */
      public NameParser getNameParser( final Name name ) 
          throws NamingException
      {
          if( name.isEmpty() )
          {
              return getNameParser();
          }
  
          Object object = lookup( name );
          if( !(object instanceof Context) ) 
          {
              object = lookup( getPathName( name ) );
          }
  
          final Context context = (Context)object;
          final NameParser parser = context.getNameParser( "" );
          context.close();
          return parser; 
      }
  
      /**
       * Enumerates the names bound in the named context, along with the objects bound 
to them.
       *
       * @param name the name of the context
       * @return the enumeration
       * @exception NamingException if an error occurs
       */
      public NamingEnumeration list( final String name ) 
          throws NamingException
      {
          return list( getNameParser().parse( name ) );
      }
  
      /**
       * Enumerates the names bound in the named context, along with the objects bound 
to them.
       *
       * @param name the name of the context
       * @return the enumeration
       * @exception NamingException if an error occurs
       */
      public NamingEnumeration listBindings( final String name ) 
          throws NamingException
      {
          return listBindings( getNameParser().parse( name ) );
      }
  
      /**
       * Get the object named.
       *
       * @param name the name
       * @return the object
       * @exception NamingException if an error occurs (ie object name is inavlid or 
unbound)
       */
      public Object lookup( final String name ) 
          throws NamingException
      {
          return lookup( getNameParser().parse( name ) );
      }
  
      /**
       * Get the object named following all links.
       *
       * @param name the name
       * @return the object
       * @exception NamingException if an error occurs (ie object name is inavlid or 
unbound)
       */
      public Object lookupLink( final String name ) 
          throws NamingException 
      {
          return lookupLink( getNameParser().parse( name ) );
      }
  
      /**
       * Get the object named following all links.
       *
       * @param name the name
       * @return the object
       * @exception NamingException if an error occurs (ie object name is inavlid or 
unbound)
       */
      public Object lookupLink( final Name name ) 
          throws NamingException
      {
          return lookup( name );
      }
  
      /**
       * Binds a name to an object, overwriting any existing binding.
       *
       * @param name the name
       * @param object the object
       * @exception NamingException if an error occurs
       */
      public void rebind( final String name, final Object object ) 
          throws NamingException
      {
          rebind( getNameParser().parse( name ), object );
      }
  
      /**
       * Binds a name to an object, overwriting any existing binding.
       *
       * @param name the name
       * @param object the object
       * @exception NamingException if an error occurs
       */
      public void rebind( final Name name, final Object object ) 
          throws NamingException
      {
          bind( name, object, true );
      }
  
      /**
       * Remove a key-value pair form environment and return it.
       *
       * @param key the key
       * @return the value
       */
      public Object removeFromEnvironment( final String key ) 
          throws NamingException
      {
          if( null == m_environment ) return null;
          return m_environment.remove( key );
      }
  
      /**
       * Rename a already bound object
       *
       * @param oldName the old name
       * @param newName the new name
       * @exception NamingException if an error occurs
       */
      public void rename( final String oldName, final String newName ) 
          throws NamingException
      {
          rename( getNameParser().parse( oldName ), getNameParser().parse( newName ) );
      }
  
      public void rename( final Name oldName, final Name newName )
          throws NamingException
      {
          if( isSelf( oldName ) || isSelf( newName ) )
          {
              throw new InvalidNameException( "Failed to rebind self" );
          }
          else if( oldName.equals( newName ) )
          {
              throw new InvalidNameException( "Failed to rebind identical names" );
          }
  
          bind( newName, lookup( oldName ) );
          unbind( oldName );
      }
  
      /**
       * Unbind a object from a name.
       *
       * @param name the name
       * @exception NamingException if an error occurs
       */
      public void unbind( final String name ) 
          throws NamingException
      {
          unbind( getNameParser().parse( name ) );
      }
  
      protected Name getPathName( final Name name )
          throws NamingException
      {
          return name.getPrefix( name.size() - 1 );
      }
  
      protected Name getLeafName( final Name name )
          throws NamingException
      {
          return name.getSuffix( name.size() - 1 );
      }
  }
  
  
  
  1.1                  
jakarta-commons-sandbox/cadastre/src/java/org/apache/avalon/cadastre/AbstractLocalContext.java
  
  Index: AbstractLocalContext.java
  ===================================================================
  /*
   * Copyright (C) The Apache Software Foundation. All rights reserved.
   *
   * This software is published under the terms of the Apache Software License
   * version 1.1, a copy of which has been included with this distribution in
   * the LICENSE file.
   */
  package org.apache.avalon.cadastre;
  
  import java.util.Hashtable;
  import javax.naming.Context;
  import javax.naming.InvalidNameException;
  import javax.naming.NamingEnumeration;
  import javax.naming.Name;
  import javax.naming.NameParser;
  import javax.naming.ContextNotEmptyException;
  import javax.naming.NameAlreadyBoundException;
  import javax.naming.NamingException;
  import javax.naming.NotContextException;
  import javax.naming.Reference;
  import javax.naming.Referenceable;
  import javax.naming.OperationNotSupportedException;
  
  /**
   * Abstract local JNDI Context that can be inherited from to 
   * provide a particular type of Context. These contexts are assumed to be 
   * on the same machine.
   *
   * @author <a href="mailto:[EMAIL PROTECTED]";>Peter Donald</a>
   * @version $Revision: 1.1 $
   */
  public abstract class AbstractLocalContext
      extends AbstractContext
  {
      protected Context    m_parent;
      protected Namespace  m_namespace;
  
      public AbstractLocalContext( final Namespace namespace,
                                   final Hashtable environment, 
                                   final Context parent )
      {
          super( environment );
          m_namespace = namespace;
          m_parent = parent;
      }
  
      protected boolean isDestroyableContext( final Object object )
          throws NamingException
      {
          return getClass().isInstance( object );
      }
  
      protected abstract Context newContext()
          throws NamingException;
  
      protected abstract Context cloneContext()
          throws NamingException;
  
      /**
       * Helper method to bind
       */
      protected void bind( final Name name, Object object, final boolean rebind )
          throws NamingException 
      {
          if( isSelf( name ) )
          {
              throw new InvalidNameException( "Failed to bind self" );
          }
  
          if( 1 == name.size() )
          {
              boolean alreadyBound = false;
              try 
              {
                  localLookup( name );
                  alreadyBound = true;
              }
              catch( final NamingException ne ) {}
  
              if( !rebind && alreadyBound )
              {
                  throw new NameAlreadyBoundException( name.get( 0 ) );
              }
              else
              {
                  //Should this occur here or in the factories ???
                  if( object instanceof Referenceable )
                  {
                      object = ((Referenceable)object).getReference();
                  }
  
                  // Call getStateToBind for using any state factories
                  final Name atom = name.getPrefix( 1 );
                  object = m_namespace.getStateToBind( object, atom, this, 
m_environment );
  
                  doLocalBind( name, object );
              }
          }
          else
          {
              final Context context = lookupSubContext( getPathName( name ) );
              if( rebind ) 
              {
                  context.rebind( getLeafName( name ), object );
              }
              else
              {
                  context.bind( getLeafName( name ), object );
              }
          }
      }
  
      protected abstract void doLocalBind( Name name, Object object )
          throws NamingException;
  
      public void close() 
      {
          m_parent = null;
          m_namespace = null;
      }
  
      /**
       * Create a Subcontext.
       *
       * @param name the name of subcontext
       * @return the created context
       * @exception NamingException if an error occurs (ie context exists, badly 
formated name etc)
       */
      public Context createSubcontext( final Name name ) 
          throws NamingException
      {
          final Context context = newContext();
          bind( name, context );       
          return context;
      }
  
      public void destroySubcontext( final Name name ) 
          throws NamingException
      {
          if( isSelf( name ) )
          {
              throw new InvalidNameException( "Failed to destroy self" );
          }
  
          if( 1 == name.size() )
          {
              Object object = null;
              try
              {
                  object = localLookup( name );
              }
              catch( final NamingException ne ) 
              {
                  return;
              }                
  
              checkUnbindContext( name, object );
  
              doLocalUnbind( name );
          }
          else
          {
              final Context context = lookupSubContext( getPathName( name ) );
              
              Object object = null;
  
              final Name atom = getLeafName( name );
              try
              {
                  object = context.lookup( atom );
              }
              catch( final NamingException ne )
              {
                  return;
              }
  
              checkUnbindContext( atom, object );
  
              context.destroySubcontext( atom );
          }
      }
  
      protected void checkUnbindContext( final Name name, final Object entry )
          throws NamingException
      {
          if( !isDestroyableContext( entry ) )
          {
              throw new NotContextException( name.toString() );
          }
          
          final Context context = (Context)entry;
          if( context.list( "" ).hasMoreElements() )
          {
              throw new ContextNotEmptyException( name.toString() );
          }
      }
  
      public String getNameInNamespace() 
          throws NamingException
      {
          throw new OperationNotSupportedException( "Namespace has no notion of a 
'full name'" );
      }
  
      protected NameParser getNameParser() 
          throws NamingException
      {
          return m_namespace.getNameParser();
      }
  
      /**
       * Enumerates the names bound in the named context.
       *
       * @param name the name of the context
       * @return the enumeration
       * @exception NamingException if an error occurs
       */
      public NamingEnumeration list( final Name name )
          throws NamingException
      {
          if( isSelf( name ) )
          {
              return doLocalList();
          }
          else
          {
              // Perhaps 'name' names a context
              final Context context = lookupSubContext( name );
              return context.list( "" );
          }
      }
  
      protected abstract NamingEnumeration doLocalList()
          throws NamingException;
  
      protected abstract NamingEnumeration doLocalListBindings()
          throws NamingException;
  
      /**
       * Enumerates the names bound in the named context, along with the objects bound 
to them.
       *
       * @param name the name of the context
       * @return the enumeration
       * @exception NamingException if an error occurs
       */
      public NamingEnumeration listBindings( final Name name ) 
          throws NamingException
      {
          if( isSelf( name ) ) 
          {
              return doLocalListBindings();
          }
          else
          {
              // Perhaps 'name' names a context
              final Context context = lookupSubContext( name );
              return context.listBindings( "" );
          }
      }
  
      /**
       * Get the object named.
       *
       * @param name the name
       * @return the object
       * @exception NamingException if an error occurs (ie object name is inavlid or 
unbound)
       */
      public Object lookup( final Name name ) 
          throws NamingException
      {
          //if it refers to base context return a copy of it.
          if( isSelf( name ) )
          {
              return cloneContext();
          }
  
          if( 1 == name.size() )
          {
              return localLookup( name );
          }
          else
          {
              final Context context = lookupSubContext( getPathName( name ) );
              return context.lookup( getLeafName( name ) );
          }
      }
  
      /**
       * Lookup entry in local context.
       *
       * @param name the name in local context (size() == 1)
       * @return the bound object
       * @exception NamingException if an error occurs
       */
      protected Object localLookup( final Name name )
          throws NamingException
      {
          final Object value = doLocalLookup( name );
  
          // Call getObjectInstance for using any object factories
          try 
          {
              final Name atom = name.getPrefix( 1 );
              return m_namespace.getObjectInstance( value, atom, this, m_environment );
          } 
          catch( final Exception e )
          {
              final NamingException ne = new NamingException( "getObjectInstance 
failed" );
              ne.setRootCause( e );
              throw ne;
          }
      }
  
      /**
       * Actually lookup raw entry in local context.
       * When overidding this it is not neccesary to resolve references etc.
       *
       * @param name the name in local context (size() == 1)
       * @return the bound object
       * @exception NamingException if an error occurs
       */
      protected abstract Object doLocalLookup( Name name )
          throws NamingException;
  
      /**
       * Lookup a sub-context of current context.
       * Note that name must have 1 or more elements.
       *
       * @param name the name of subcontext
       * @return the sub-Context
       * @exception NamingException if an error occurs (like named entry is not a 
Context)
       */
      protected Context lookupSubContext( final Name name )
          throws NamingException
      {
          final Name atom = name.getPrefix( 1 );
          Object object = localLookup( atom );
  
          if( 1 != name.size() )
          {
              if( !(object instanceof Context) )
              {
                  throw new NotContextException( atom.toString() );
              }
  
              object = ((Context)object).lookup( name.getSuffix( 1 ) );
          }
  
          if( !(object instanceof Context) ) 
          {
              throw new NotContextException( name.toString() );
          }
  
          //((Context)object).close();            
          return (Context)object;
      }
  
      /**
       * Unbind a object from a name.
       *
       * @param name the name
       * @exception NamingException if an error occurs
       */
      public void unbind( final Name name ) 
          throws NamingException
      {
          if( isSelf( name ) )
          {
              throw new InvalidNameException( "Cannot unbind self" );
          }
          else if( 1 == name.size() )
          {
              doLocalUnbind( name );
          }
          else
          {
              final Context context = lookupSubContext( getPathName ( name ) );
              context.unbind( getLeafName( name ) );
          }
      }
  
      /**
       * Actually unbind raw entry in local context.
       *
       * @param name the name in local context (size() == 1)
       * @exception NamingException if an error occurs
       */
      protected abstract void doLocalUnbind( Name name )
          throws NamingException;
  }
  
  
  
  1.1                  
jakarta-commons-sandbox/cadastre/src/java/org/apache/avalon/cadastre/AbstractNamespace.java
  
  Index: AbstractNamespace.java
  ===================================================================
  /*
   * Copyright (C) The Apache Software Foundation. All rights reserved.
   *
   * This software is published under the terms of the Apache Software License
   * version 1.1, a copy of which has been included with this distribution in
   * the LICENSE file.
   */
  package org.apache.avalon.cadastre;
  
  import java.util.Hashtable;
  import javax.naming.NameParser;
  import javax.naming.Name;
  import javax.naming.Context;
  import javax.naming.NamingException;
  import javax.naming.spi.InitialContextFactory;
  import javax.naming.spi.ObjectFactory;
  import javax.naming.spi.StateFactory;
  
  /**
   * This is the class to extend that provides 
   * basic facilities for Namespace management.
   *
   * @author <a href="mailto:[EMAIL PROTECTED]";>Peter Donald</a>
   * @version $Revision: 1.1 $
   */
  public abstract class AbstractNamespace
      implements Namespace
  {
      protected ObjectFactory[]        m_objectFactorySet;
      protected StateFactory[]         m_stateFactorySet;
  
      public Object getStateToBind( final Object object,
                                    final Name name,
                                    final Context parent,
                                    final Hashtable environment )
          throws NamingException
      {
          //for thread safety so that member variable can be updated 
          //at any time
          final StateFactory[] stateFactorySet = m_stateFactorySet;
  
          for( int i = 0; i < stateFactorySet.length; i++ )
          {
              final Object result = 
                  stateFactorySet[ i ].getStateToBind( object, name, parent, 
environment );
              
              if( null != result )
              {
                  return result;
              }
          }
  
          return object;
      }
  
      public Object getObjectInstance( final Object object,
                                       final Name name,
                                       final Context parent,
                                       final Hashtable environment )
          throws Exception
      {
          //for thread safety so that member variable can be updated 
          //at any time
          final ObjectFactory[] objectFactorySet = m_objectFactorySet;
  
          for( int i = 0; i < objectFactorySet.length; i++ )
          {
              final Object result = 
                  objectFactorySet[ i ].getObjectInstance( object, name, parent, 
environment );
              
              if( null != result )
              {
                  return result;
              }
          }
  
          return object;
      }
  }
  
  
  
  1.1                  
jakarta-commons-sandbox/cadastre/src/java/org/apache/avalon/cadastre/AbstractNamingEnumeration.java
  
  Index: AbstractNamingEnumeration.java
  ===================================================================
  /*
   * Copyright (C) The Apache Software Foundation. All rights reserved.
   *
   * This software is published under the terms of the Apache Software License
   * version 1.1, a copy of which has been included with this distribution in
   * the LICENSE file.
   */
  package org.apache.avalon.cadastre;
  
  import java.util.Hashtable;
  import java.util.Iterator;
  import java.util.NoSuchElementException;
  import javax.naming.Binding;
  import javax.naming.Context;
  import javax.naming.Name;
  import javax.naming.NameClassPair;
  import javax.naming.NamingEnumeration;
  import javax.naming.NamingException;
  import javax.naming.spi.NamingManager;
   
  /**
   * Class for building NamingEnumerations.
   *
   * @author <a href="mailto:[EMAIL PROTECTED]";>Peter Donald</a>
   * @version $Revision: 1.1 $
   */
  public abstract class AbstractNamingEnumeration
      implements NamingEnumeration
  {
      protected Context      m_owner;
      protected Namespace    m_namespace;
  
      public AbstractNamingEnumeration( final Context owner, final Namespace namespace 
)
      {
          m_owner = owner;
          m_namespace = namespace;
      }
  
      public boolean hasMore() 
          throws NamingException
      {
          return hasMoreElements();
      }
  
      public Object nextElement()
      {
          try { return next(); }
          catch( final NamingException ne )
          {
              throw new NoSuchElementException( ne.toString() );
          }
      }
  
      protected Object resolve( final String name, final Object object )
          throws NamingException
      {
          // Call getObjectInstance for using any object factories
          try 
          {
              final Name atom = m_owner.getNameParser( name ).parse( name );
              return m_namespace.
                  getObjectInstance( object, atom, m_owner, m_owner.getEnvironment() );
          } 
          catch( final Exception e )
          {
              final NamingException ne = new NamingException( "getObjectInstance 
failed" );
              ne.setRootCause( e );
              throw ne;
          }
      }
  
      public void close()
      {
          m_namespace = null;
          m_owner = null;
      }
  }
  
  
  
  1.1                  
jakarta-commons-sandbox/cadastre/src/java/org/apache/avalon/cadastre/AbstractURLContext.java
  
  Index: AbstractURLContext.java
  ===================================================================
  /*
   * Copyright (C) The Apache Software Foundation. All rights reserved.
   *
   * This software is published under the terms of the Apache Software License
   * version 1.1, a copy of which has been included with this distribution in
   * the LICENSE file.
   */
  package org.apache.avalon.cadastre;
  
  import java.util.Hashtable;
  import javax.naming.*;
  import javax.naming.CompositeName;
  import javax.naming.Context;
  import javax.naming.Name;
  import javax.naming.NameParser;
  import javax.naming.spi.ResolveResult;
  
  /**
   * Abstract JNDI Context that can be inherited from to 
   * provide a particular type of Context.
   *
   * @author <a href="mailto:[EMAIL PROTECTED]";>Peter Donald</a>
   * @version $Revision: 1.1 $
   */
  public abstract class AbstractURLContext
      extends AbstractContext
      implements NameParser
  {
      protected final String   m_scheme;
  
      public AbstractURLContext( final String scheme, final Hashtable environment )
      {
          super( environment );
          m_scheme = scheme;
      }
  
      public Name parse( final String name )
          throws NamingException
      {
          return (new CompositeName().add( name ));
      }
  
      protected NameParser getNameParser()
          throws NamingException
      {
          return this;
      }
  
      /**
       * Helper method to bind
       */
      protected void bind( final Name name, final Object object, final boolean rebind )
          throws NamingException
      {
          final ResolveResult resolveResult = getBaseURLContext( name, m_environment );
          final Context context = (Context)resolveResult.getResolvedObj();
  
          try
          {
              if( rebind )
              {
                  context.rebind( resolveResult.getRemainingName(), object );
              }
              else
              {
                  context.bind( resolveResult.getRemainingName(), object );
              }
          }
          finally
          {
              context.close();
          }
      }
  
      /**
       * Create a Subcontext.
       *
       * @param name the name of subcontext
       * @return the created context
       * @exception NamingException if an error occurs (ie context exists, badly 
formated name etc)
       */
      public Context createSubcontext( final Name name ) 
          throws NamingException
      {
          final ResolveResult resolveResult = getBaseURLContext( name, m_environment );
          final Context context = (Context)resolveResult.getResolvedObj();
  
          try
          {
              return context.createSubcontext( resolveResult.getRemainingName() );
          }
          finally
          {
              context.close();
          }
      }
  
      public void destroySubcontext( final Name name ) 
          throws NamingException
      {
          final ResolveResult resolveResult = getBaseURLContext( name, m_environment );
          final Context context = (Context)resolveResult.getResolvedObj();
  
          try
          {
              context.destroySubcontext( resolveResult.getRemainingName() );
          }
          finally
          {
              context.close();
          }
      }
  
      public String getNameInNamespace() 
          throws NamingException
      {
          return "";
      }
  
      /**
       * Enumerates the names bound in the named context.
       *
       * @param name the name of the context
       * @return the enumeration
       * @exception NamingException if an error occurs
       */
      public NamingEnumeration list( final Name name )
          throws NamingException
      {
          final ResolveResult resolveResult = getBaseURLContext( name, m_environment );
          final Context context = (Context)resolveResult.getResolvedObj();
  
          try
          {
              return context.list( resolveResult.getRemainingName() );
          }
          finally
          {
              context.close();
          }
      }
  
      /**
       * Enumerates the names bound in the named context, along with the objects bound 
to them.
       *
       * @param name the name of the context
       * @return the enumeration
       * @exception NamingException if an error occurs
       */
      public NamingEnumeration listBindings( final Name name ) 
          throws NamingException
      {
          final ResolveResult resolveResult = getBaseURLContext( name, m_environment );
          final Context context = (Context)resolveResult.getResolvedObj();
  
          try
          {
              return context.listBindings( resolveResult.getRemainingName() );
          }
          finally
          {
              context.close();
          }
      }
  
      /**
       * Get the object named.
       *
       * @param name the name
       * @return the object
       * @exception NamingException if an error occurs (ie object name is inavlid or 
unbound)
       */
      public Object lookup( final Name name ) 
          throws NamingException
      {
          final ResolveResult resolveResult = getBaseURLContext( name, m_environment );
          final Context context = (Context)resolveResult.getResolvedObj();
  
          try
          {
              return context.lookup( resolveResult.getRemainingName() );
          }
          finally
          {
              context.close();
          }
      }
  
      /**
       * Unbind a object from a name.
       *
       * @param name the name
       * @exception NamingException if an error occurs
       */
      public void unbind( final Name name ) 
          throws NamingException
      {
          final ResolveResult resolveResult = getBaseURLContext( name, m_environment );
          final Context context = (Context)resolveResult.getResolvedObj();
  
          try
          {
              context.unbind( resolveResult.getRemainingName() );
          }
          finally
          {
              context.close();
          }
      }
  
      protected ResolveResult getBaseURLContext( final Name name, final Hashtable 
environment )
          throws NamingException
      {
          if( name.isEmpty() )
          {
              throw new InvalidNameException( "Unable to locate URLContext will empty 
name" );
          }
  
          final String nameString = name.toString();
          int index = nameString.indexOf( ':' );
  
          if( -1 == index )
          {
              throw new InvalidNameException( "Unable to build URLContext as it does 
not specify scheme" );
          }
  
          final String scheme = nameString.substring( 0, index );
          final int end = getEndIndexOfURLPart( nameString, index + 1 );
          final String urlPart = nameString.substring( index + 1, end );
          final String namePart = nameString.substring( end );
  
          if( !m_scheme.equals( scheme ) )
          {
              throw new InvalidNameException( "Bad Scheme use to build URLContext (" + 
scheme + "). " +
                                              "Expected " + m_scheme ); 
          }
  
          final Context context = newContext( urlPart );
  
          return new ResolveResult( context, new CompositeName( namePart ) );
      }
  
      /**
       * Find end index of url part in string.
       * Default implementation looks for
       * //.../[name-part]
       * ///[name-part]
       * //... (no name part)
       * [name-part]
       *
       * @param name the name
       * @param index the index where "scheme:" ends
       * @return the index where url ends
       * @exception NamingException if an error occurs
       */
      protected int getEndIndexOfURLPart( final String name, final int index )
          throws NamingException
      {
          int result = 0;
  
          //does it start with //
          if( name.startsWith( "//", index ) )
          {
              //does it have .../  following ???
              int end = name.indexOf( "/", index + 2 );
              
              if( -1 != end )
              {
                  result = end;
              }
              else
              {
                  result = name.length();
              }
          }
  
          return result;
      }
  
      /**
       * Return a new instance of the base context for a URL.
       * This must be implemented in particular URLContext.
       *
       * @param urlPart the part of url string not including "scheme:"
       * @return a base URLContext for urlPart
       * @exception NamingException if an error occurs
       */
      protected abstract Context newContext( String urlPart )
          throws NamingException;
  }
  
  
  
  1.1                  
jakarta-commons-sandbox/cadastre/src/java/org/apache/avalon/cadastre/ArrayNamingEnumeration.java
  
  Index: ArrayNamingEnumeration.java
  ===================================================================
  /*
   * Copyright (C) The Apache Software Foundation. All rights reserved.
   *
   * This software is published under the terms of the Apache Software License
   * version 1.1, a copy of which has been included with this distribution in
   * the LICENSE file.
   */
  package org.apache.avalon.cadastre;
  
  import java.util.NoSuchElementException;
  import javax.naming.Binding;
  import javax.naming.Context;
  import javax.naming.NamingException;  
  
  /**
   * Class for building NamingEnumerations.
   *
   * @author <a href="mailto:[EMAIL PROTECTED]";>Peter Donald</a>
   * @version $Revision: 1.1 $
   */
  final class ArrayNamingEnumeration
      extends AbstractNamingEnumeration
  {
      protected Object[]   m_items;
      protected int        m_index;
  
      public ArrayNamingEnumeration( final Context owner, 
                                     final Namespace namespace,
                                     final Object[] items )
      {
          super( owner, namespace );       
          m_items = items;
          //m_index = 0;
      }
  
      public boolean hasMoreElements()
      {
          return m_index < m_items.length;
      }
  
      public Object next() 
          throws NamingException
      {
          if( !hasMore() ) throw new NoSuchElementException();
          
          
          final Object object = m_items[ m_index++ ];
  
          if( object instanceof Binding )
          {
              final Binding binding = (Binding)object;
              final Object resolvedObject = resolve( binding.getName(), 
binding.getObject() );
              binding.setObject( resolvedObject );
          }
  
          return object;
      }
  
      public void close()
      {
          super.close();
          m_items = null;
      }
  }
  
  
  
  1.1                  
jakarta-commons-sandbox/cadastre/src/java/org/apache/avalon/cadastre/DefaultNameParser.java
  
  Index: DefaultNameParser.java
  ===================================================================
  /*
   * Copyright (C) The Apache Software Foundation. All rights reserved.
   *
   * This software is published under the terms of the Apache Software License
   * version 1.1, a copy of which has been included with this distribution in
   * the LICENSE file.
   */
  package org.apache.avalon.cadastre;
  
  import java.io.Serializable;
  import java.util.Properties;
  import javax.naming.CompoundName;
  import javax.naming.Name;
  import javax.naming.NameParser;
  import javax.naming.NamingException;
  
  public class DefaultNameParser
      implements Serializable, NameParser 
  {
      protected static Properties        c_syntax = new Properties();
  
      static 
      {
          c_syntax.put( "jndi.syntax.direction", "left_to_right" );
          c_syntax.put( "jndi.syntax.ignorecase", "false" );
          c_syntax.put( "jndi.syntax.separator", "/" );
      }
  
      public Name parse( final String name ) 
          throws NamingException 
      {
          return new CompoundName( name, c_syntax );
      }
  }
  
  
  
  1.1                  
jakarta-commons-sandbox/cadastre/src/java/org/apache/avalon/cadastre/DefaultNamespace.java
  
  Index: DefaultNamespace.java
  ===================================================================
  /*
   * Copyright (C) The Apache Software Foundation. All rights reserved.
   *
   * This software is published under the terms of the Apache Software License
   * version 1.1, a copy of which has been included with this distribution in
   * the LICENSE file.
   */
  package org.apache.avalon.cadastre;
  
  import java.util.Hashtable;
  import javax.naming.Context;
  import javax.naming.NameParser;
  import javax.naming.NamingException;
  import javax.naming.spi.InitialContextFactory;
  import javax.naming.spi.ObjectFactory;
  import javax.naming.spi.StateFactory;
  
  /**
   * This is the default namespace implementation.
   *
   * @author <a href="mailto:[EMAIL PROTECTED]";>Peter Donald</a>
   * @version $Revision: 1.1 $
   */
  public class DefaultNamespace
      extends AbstractNamespace
  {
      protected NameParser             m_nameParser;
  
      public DefaultNamespace( final NameParser nameParser )
      {
          this( nameParser, 
                new ObjectFactory[ 0 ], 
                new StateFactory[ 0 ] );
      }
  
      public DefaultNamespace( final NameParser nameParser, 
                               final ObjectFactory[] objectFactorySet,
                               final StateFactory[] stateFactorySet )
      {
          m_nameParser = nameParser;
          m_objectFactorySet = objectFactorySet;
          m_stateFactorySet = stateFactorySet;
      }
  
      public synchronized void addStateFactory( final StateFactory stateFactory )
      {
          //create new array of factory objects
          final StateFactory[] stateFactorySet = 
              new StateFactory[ m_stateFactorySet.length + 1 ];
  
          //copy old factory objects to new array
          System.arraycopy( m_stateFactorySet, 0, stateFactorySet, 0, 
m_stateFactorySet.length );
          
          //add in new factory at end
          stateFactorySet[ m_stateFactorySet.length ] = stateFactory;
  
          //update factory set
          m_stateFactorySet = stateFactorySet;        
      }
  
      public synchronized void addObjectFactory( final ObjectFactory objectFactory )
      {
          //create new array of factory objects
          final ObjectFactory[] objectFactorySet = 
              new ObjectFactory[ m_objectFactorySet.length + 1 ];
  
          //copy old factory objects to new array
          System.arraycopy( m_objectFactorySet, 0, objectFactorySet, 0, 
m_objectFactorySet.length );
          
          //add in new factory at end
          objectFactorySet[ m_objectFactorySet.length ] = objectFactory;
  
          //update factory set
          m_objectFactorySet = objectFactorySet;        
      }
  
      public NameParser getNameParser()
      {
          return m_nameParser;
      }
  }
  
  
  
  1.1                  
jakarta-commons-sandbox/cadastre/src/java/org/apache/avalon/cadastre/Namespace.java
  
  Index: Namespace.java
  ===================================================================
  /*
   * Copyright (C) The Apache Software Foundation. All rights reserved.
   *
   * This software is published under the terms of the Apache Software License
   * version 1.1, a copy of which has been included with this distribution in
   * the LICENSE file.
   */
  package org.apache.avalon.cadastre;
  
  import java.util.Hashtable;
  import javax.naming.NameParser;
  import javax.naming.NamingException;
  import javax.naming.spi.ObjectFactory;
  import javax.naming.spi.StateFactory;
  
  /**
   * Interface representing Namespace/NamingSystem.
   * Associated with each namespace is a name parser, 
   * object factories and state factories.
   *
   * @author <a href="mailto:[EMAIL PROTECTED]";>Peter Donald</a>
   * @version $Revision: 1.1 $
   */
  public interface Namespace
      extends ObjectFactory, StateFactory
  {
      NameParser getNameParser()
          throws NamingException;
  }
  
  
  
  1.1                  
jakarta-commons-sandbox/cadastre/src/java/org/apache/avalon/cadastre/NamingProvider.java
  
  Index: NamingProvider.java
  ===================================================================
  /*
   * Copyright (C) The Apache Software Foundation. All rights reserved.
   *
   * This software is published under the terms of the Apache Software License
   * version 1.1, a copy of which has been included with this distribution in
   * the LICENSE file.
   */
  package org.apache.avalon.cadastre;
  
  import javax.naming.Context;
  import javax.naming.Name;
  import javax.naming.Binding;
  import javax.naming.NameClassPair;
  import javax.naming.NameParser;
  import javax.naming.NamingException;
  
  /**
   * The underlying communication interface for remote contexts.
   *
   * @author <a href="mailto:[EMAIL PROTECTED]";>Peter Donald</a>
   * @version $Revision: 1.1 $
   */
  public interface NamingProvider
  {
      NameParser getNameParser()
          throws NamingException, Exception;
  
      void bind( Name name, String className, Object object )
          throws NamingException, Exception;
  
      void rebind( Name name, String className, Object object )
          throws NamingException, Exception;
  
      Context createSubcontext( Name name )
          throws NamingException, Exception;
  
      void destroySubcontext( Name name )
          throws NamingException, Exception;
  
      NameClassPair[] list( Name name )
          throws NamingException, Exception;
  
      Binding[] listBindings( Name name )
          throws NamingException, Exception;
  
      Object lookup( Name name ) 
          throws NamingException, Exception;
  
      void unbind( Name name ) 
          throws NamingException, Exception;
  }
  
  
  
  1.1                  
jakarta-commons-sandbox/cadastre/src/java/org/apache/avalon/cadastre/RemoteContext.java
  
  Index: RemoteContext.java
  ===================================================================
  /*
   * Copyright (C) The Apache Software Foundation. All rights reserved.
   *
   * This software is published under the terms of the Apache Software License
   * version 1.1, a copy of which has been included with this distribution in
   * the LICENSE file.
   */
  package org.apache.avalon.cadastre;
  
  import java.io.Serializable;
  import java.io.IOException;
  import java.util.Hashtable;
  import java.util.Iterator;
  import java.rmi.MarshalledObject;
  import javax.naming.*;
  import javax.naming.Context;
  
  /**
   * Context that hooks up to a remote source.
   *
   * @author <a href="mailto:[EMAIL PROTECTED]";>Peter Donald</a>
   * @version $Revision: 1.1 $
   */
  public class RemoteContext
      extends AbstractContext
      implements Serializable
  {
      public final static String  NAMESPACE_NAME   = 
"org.apache.avalon.cadastre.Namespace/NAME";
      public final static String  NAMESPACE        = 
"org.apache.avalon.cadastre.Namespace";
      public final static String  NAMING_PROVIDER  = 
"org.apache.avalon.cadastre.NamingProvider";
  
      protected transient NamingProvider    m_provider;
      protected transient NameParser        m_nameParser;
      protected transient Namespace         m_namespace;
  
      protected Name              m_baseName;
  
      //for deserialisation
      public RemoteContext()
      {
      }
  
      public RemoteContext( final Hashtable environment, final Name baseName )
          throws NamingException
      {
          super( environment );
          m_baseName = baseName;
      }
  
      /**
       * Helper method to bind
       */
      protected void bind( final Name name, Object object, final boolean rebind )
          throws NamingException 
      {
          if( isSelf( name ) )
          {
              throw new InvalidNameException( "Failed to bind self" );
          }
  
          String className = null;
  
          object = getNamespace().getStateToBind( object, name, this, m_environment );
  
          if( object instanceof Reference )
          {
              className = ((Reference)object).getClassName();
          }
          else if( object instanceof Referenceable )
          {
              object = ((Referenceable)object).getReference();
              className = ((Reference)object).getClassName();
          }
          else
          {
              className = object.getClass().getName();
  
              try { object = new MarshalledObject( object ); }
              catch( final IOException ioe )
              {
                  throw new NamingException( "Only Reference, Referenceables and " + 
                                             "Serializable objects can be bound " +
                                             "to context" );
              }
          } 
  
          try 
          {
              if( rebind )
              {
                  getProvider().rebind( getAbsoluteName( name ), className, object ); 
              }
              else
              {
                  getProvider().bind( getAbsoluteName( name ), className, object ); 
              }
          }
          catch( final Exception e )
          {
                  throw handleException( e );
          }
      }
  
      /**
       * Release resources associated with context.
       */
      public void close() 
      {
          m_namespace = null;
          m_environment = null;
          m_provider = null;
      }
  
      /**
       * Create a Subcontext.
       *
       * @param name the name of subcontext
       * @return the created context
       * @exception NamingException if an error occurs (ie context exists, badly 
formated name etc)
       */
      public Context createSubcontext( final Name name ) 
          throws NamingException
      {
          if( isSelf( name ) )
          {
              throw new InvalidNameException( "Failed to create null subcontext" );
          }
  
          Context result = null;
          try { result = getProvider().createSubcontext( getAbsoluteName( name ) ); }
          catch( final Exception e )
          {
              throw handleException( e );
          }
  
          fillInContext( result );
  
          return result;
      }
  
      public void destroySubcontext( final Name name ) 
          throws NamingException
      {
          if( isSelf( name ) )
          {
              throw new InvalidNameException( "Failed to destroy self" );
          }
  
          try { getProvider().destroySubcontext( getAbsoluteName( name ) ); }
          catch( final Exception e )
          {
              throw handleException( e );
          }
      }
  
      public String getNameInNamespace() 
          throws NamingException
      {
          return getAbsoluteName( getNameParser().parse( "" ) ).toString();
      }
  
      /**
       * Enumerates the names bound in the named context.
       *
       * @param name the name of the context
       * @return the enumeration
       * @exception NamingException if an error occurs
       */
      public NamingEnumeration list( final Name name )
          throws NamingException
      {
          try
          {
              final NameClassPair[] result = getProvider().list( getAbsoluteName( name 
) );
              return new ArrayNamingEnumeration( this, m_namespace, result );
          }
          catch( final Exception e )
          {
              throw handleException( e );
          }
      }
  
      /**
       * Enumerates the names bound in the named context, along with the objects bound 
to them.
       *
       * @param name the name of the context
       * @return the enumeration
       * @exception NamingException if an error occurs
       */
      public NamingEnumeration listBindings( final Name name ) 
          throws NamingException
      {
          try
          {
              final Binding[] result = getProvider().listBindings( getAbsoluteName( 
name ) );
  
              for( int i = 0; i < result.length; i++ )
              {
                  final Object object = result[ i ].getObject();
                  if( object instanceof Context )
                  {
                      fillInContext( (Context)object );
                  }
              }
              
              return new ArrayNamingEnumeration( this, m_namespace, result );
          }
          catch( final Exception e )
          {
              throw handleException( e );
          }
      }
  
      /**
       * Get the object named.
       *
       * @param name the name
       * @return the object
       * @exception NamingException if an error occurs (ie object name is inavlid or 
unbound)
       */
      public Object lookup( final Name name ) 
          throws NamingException
      {
          if( isSelf( name ) )
          {
              return new RemoteContext( m_environment, m_baseName );
          }
  
          //TODO: actually do a real-lookup 
          Object object = null;
          try
          { 
              object = getProvider().lookup( getAbsoluteName( name ) ); 
  
              if( object instanceof MarshalledObject )
              {
                  object = ((MarshalledObject)object).get();
              }
  
              object = getNamespace().getObjectInstance( object, name, this, 
m_environment );
              
              if( object instanceof Context )
              {
                  fillInContext( (Context)object );
              }
          }
          catch( final Exception e )
          {
              throw handleException( e );
          }
  
          return object;
      }
  
      /**
       * Unbind a object from a name.
       *
       * @param name the name
       * @exception NamingException if an error occurs
       */
      public void unbind( final Name name ) 
          throws NamingException
      {
          if( isSelf( name ) )
          {
              throw new InvalidNameException( "Failed to unbind self" );
          }
  
          try { getProvider().unbind( getAbsoluteName( name ) ); }
          catch( final Exception e )
          {
              throw handleException( e );
          }
      }
  
      protected void fillInContext( final Context object )
          throws NamingException
      {
          final Iterator keys = m_environment.keySet().iterator();
  
          while( keys.hasNext() )
          {
              final String key = (String)keys.next();
              final Object value = m_environment.get( key );
              object.addToEnvironment( key , value );
          }
      }
  
      protected Namespace getNamespace()
          throws NamingException
      {
          if( null == m_namespace )
          {
              final Object object = m_environment.get( RemoteContext.NAMESPACE );
  
              if( !(object instanceof Namespace) || null == object )
              {
                  throw new ConfigurationException( "Context does not contain 
Namespace" );
              }
              else
              {
                  m_namespace = (Namespace)object;
              }
          }
          
          return m_namespace;
      }
  
      protected NamingProvider getProvider()
          throws NamingException
      {
          if( null == m_provider )
          {
              final Object object = m_environment.get( RemoteContext.NAMING_PROVIDER );
  
              if( !(object instanceof NamingProvider) || null == object )
              {
                  throw new ConfigurationException( "Context does not contain 
provider" );
              }
              else
              {
                  m_provider = (NamingProvider)object;
              }
          }
          
          return m_provider;
      }
  
      protected NameParser getNameParser()
          throws NamingException
      {
          if( null == m_nameParser )
          {
              //Make sure provider is valid and returns nameparser
              try { m_nameParser = getProvider().getNameParser(); }
              catch( final Exception e )
              {
                  throw handleException( e );
              }
              
          }
          return m_nameParser;
      }
  
      protected Name getAbsoluteName( final Name name )
          throws NamingException
      {
          return composeName( name, m_baseName );
      }
  
      protected NamingException handleException( final Exception e )
      {
          if( e instanceof NamingException )
          {
              return (NamingException)e;
          }
          else
          {
              return new CommunicationException( e.toString() );
          }
      }
  }
  
  
  
  1.1                  
jakarta-commons-sandbox/cadastre/src/java/org/apache/avalon/cadastre/memory/MemoryContext.java
  
  Index: MemoryContext.java
  ===================================================================
  /*
   * Copyright (C) The Apache Software Foundation. All rights reserved.
   *
   * This software is published under the terms of the Apache Software License
   * version 1.1, a copy of which has been included with this distribution in
   * the LICENSE file.
   */
  package org.apache.avalon.cadastre.memory;
  
  import java.util.Enumeration;
  import java.util.HashMap;
  import java.util.Hashtable;
  import java.util.Map;
  import java.util.NoSuchElementException;
  import javax.naming.*;
  import javax.naming.Context;
  import org.apache.avalon.cadastre.AbstractLocalContext;
  import org.apache.avalon.cadastre.Namespace;
  
  /**
   * Start of a generic Context implementation.
   *
   * @author <a href="mailto:[EMAIL PROTECTED]";>Peter Donald</a>
   * @version $Revision: 1.1 $
   */
  public class MemoryContext
      extends AbstractLocalContext
  {
      protected Hashtable    m_bindings;
  
      protected MemoryContext( final Namespace namespace,
                               final Hashtable environment, 
                               final Context parent,
                               final Hashtable bindings )
      {
          super( namespace, environment, parent );
          m_bindings = bindings;
      }
  
      public MemoryContext( final Namespace namespace,
                            final Hashtable environment, 
                            final Context parent )
      {
          this( namespace, environment, parent, new Hashtable( 11 ) );
      }
  
      protected Context newContext()
          throws NamingException
      {
          return new MemoryContext( m_namespace, m_environment, m_parent );
      }
  
      protected Context cloneContext()
          throws NamingException
      {
          return new MemoryContext( m_namespace, m_environment, m_parent, m_bindings );
      }
  
      protected void doLocalBind( final Name name, final Object object )
          throws NamingException
      {
          m_bindings.put( name.get( 0 ), object );
      }
  
      protected NamingEnumeration doLocalList()
          throws NamingException
      {
          return new MemoryNamingEnumeration( this, m_namespace, m_bindings, false );
      }
  
      protected NamingEnumeration doLocalListBindings()
          throws NamingException
      {
          return new MemoryNamingEnumeration( this, m_namespace, m_bindings, true );
      }
  
      /**
       * Actually lookup raw entry in local context.
       * When overidding this it is not neccesary to resolve references etc.
       *
       * @param name the name in local context (size() == 1)
       * @return the bound object
       * @exception NamingException if an error occurs
       */
      protected Object doLocalLookup( final Name name )
          throws NamingException
      {
          final Object object = m_bindings.get( name.get( 0 ) );
          if( null == object ) throw new NameNotFoundException( name.get( 0 ) );
          return object;
      }
  
      /**
       * Actually unbind raw entry in local context.
       *
       * @param name the name in local context (size() == 1)
       * @exception NamingException if an error occurs
       */
      protected void doLocalUnbind( final Name name )
          throws NamingException
      {
          m_bindings.remove( name.get( 0 ) );
      }
  }
  
  
  
  
  1.1                  
jakarta-commons-sandbox/cadastre/src/java/org/apache/avalon/cadastre/memory/MemoryInitialContextFactory.java
  
  Index: MemoryInitialContextFactory.java
  ===================================================================
  /*
   * Copyright (C) The Apache Software Foundation. All rights reserved.
   *
   * This software is published under the terms of the Apache Software License
   * version 1.1, a copy of which has been included with this distribution in
   * the LICENSE file.
   */
  package org.apache.avalon.cadastre.memory;
  
  import java.util.Hashtable;
  import java.util.NoSuchElementException;
  import javax.naming.Context;
  import javax.naming.NamingException;
  import javax.naming.spi.InitialContextFactory;
  import org.apache.avalon.cadastre.DefaultNameParser;
  import org.apache.avalon.cadastre.DefaultNamespace;
  
  /**
   * Initial context factory for memorycontext.
   *
   * @author <a href="mailto:[EMAIL PROTECTED]";>Peter Donald</a>
   * @version $Revision: 1.1 $
   */
  public class MemoryInitialContextFactory
      implements InitialContextFactory
  {
      public Context getInitialContext( final Hashtable environment )
          throws NamingException
      {
          final DefaultNameParser parser = new DefaultNameParser();
          final DefaultNamespace namespace = new DefaultNamespace( parser );
          return new MemoryContext( namespace, environment, null );
      }
  }
  
  
  
  
  1.1                  
jakarta-commons-sandbox/cadastre/src/java/org/apache/avalon/cadastre/memory/MemoryNamingEnumeration.java
  
  Index: MemoryNamingEnumeration.java
  ===================================================================
  /*
   * Copyright (C) The Apache Software Foundation. All rights reserved.
   *
   * This software is published under the terms of the Apache Software License
   * version 1.1, a copy of which has been included with this distribution in
   * the LICENSE file.
   */
  package org.apache.avalon.cadastre.memory;
  
  import java.util.Hashtable;
  import java.util.Iterator;
  import java.util.NoSuchElementException;
  import javax.naming.Binding;
  import javax.naming.Context;
  import javax.naming.NameClassPair;
  import javax.naming.NamingException; 
  import org.apache.avalon.cadastre.AbstractNamingEnumeration;
  import org.apache.avalon.cadastre.Namespace;
  
  /**
   * Class for building NamingEnumerations.
   *
   * @author <a href="mailto:[EMAIL PROTECTED]";>Peter Donald</a>
   * @version $Revision: 1.1 $
   */
  final class MemoryNamingEnumeration
      extends AbstractNamingEnumeration
  {
      protected Hashtable    m_bindings;
      protected Iterator     m_names;
      protected boolean      m_returnBindings;
  
      public MemoryNamingEnumeration( final Context owner, 
                                      final Namespace namespace,
                                      final Hashtable bindings,
                                      final boolean returnBindings )
      {
          super( owner, namespace );
          m_returnBindings = returnBindings;
          m_bindings = bindings;
          m_names = m_bindings.keySet().iterator();
      }
  
      public boolean hasMoreElements()
      {
          return m_names.hasNext();
      }
  
      public Object next() 
          throws NamingException
      {
          if( !hasMore() ) throw new NoSuchElementException();
  
          final String name = (String)m_names.next();
          Object object = m_bindings.get( name );
          
          if( !m_returnBindings )
          {
              return new NameClassPair( name, object.getClass().getName() );
          }
          else
          {
              return new Binding( name, resolve( name, object ) );
          }
      }
  
      public void close()
      {
          super.close();
          m_bindings = null;
      }
  }
  
  
  
  1.1                  
jakarta-commons-sandbox/cadastre/src/java/org/apache/avalon/cadastre/rmi/RMIInitialContextFactory.java
  
  Index: RMIInitialContextFactory.java
  ===================================================================
  /*
   * Copyright (C) The Apache Software Foundation. All rights reserved.
   *
   * This software is published under the terms of the Apache Software License
   * version 1.1, a copy of which has been included with this distribution in
   * the LICENSE file.
   */
  package org.apache.avalon.cadastre.rmi;
  
  import java.io.BufferedInputStream;
  import java.io.IOException;
  import java.io.ObjectInputStream;
  import java.net.Socket;
  import java.rmi.MarshalledObject;
  import java.util.Hashtable;
  import javax.naming.ConfigurationException;
  import javax.naming.Context;
  import javax.naming.NamingException;
  import javax.naming.ServiceUnavailableException;
  import javax.naming.spi.InitialContextFactory;
  import org.apache.avalon.cadastre.DefaultNamespace;
  import org.apache.avalon.cadastre.Namespace;
  import org.apache.avalon.cadastre.NamingProvider;
  import org.apache.avalon.cadastre.RemoteContext;
  
  /**
   * Initial context factory for memorycontext.
   *
   * @author <a href="mailto:[EMAIL PROTECTED]";>Peter Donald</a>
   * @version $Revision: 1.1 $
   */
  public class RMIInitialContextFactory
      implements InitialContextFactory
  {
      public Context getInitialContext( final Hashtable environment )
          throws NamingException
      {
          final NamingProvider provider = newNamingProvider( environment );
          environment.put( RemoteContext.NAMING_PROVIDER, provider );
  
          final Namespace namespace = newNamespace( environment );
          environment.put( RemoteContext.NAMESPACE, namespace );
  
          return new RemoteContext( environment, namespace.getNameParser().parse( "" ) 
);
      }
  
      protected NamingProvider newNamingProvider( final Hashtable environment )
          throws NamingException
      {
          final String url = (String)environment.get( Context.PROVIDER_URL );
          if( null == url )
          {
              return newNamingProvider( "localhost", 1977 );
          }
          else
          {
              if( !url.startsWith( "rmi://" ) )
              {
                  throw new ConfigurationException( "Malformed url - " + url );
              }
  
              final int index = url.indexOf( ':', 6 );
              int end = index;
              
              int port = 1977;
  
              if( -1 == index ) 
              { 
                  end = url.length();
              }
              else
              {
                  port = Integer.parseInt( url.substring( index + 1 ) );
              }
  
              final String host = url.substring( 6, end );
  
              return newNamingProvider( host, port );
          }
      }
  
      protected NamingProvider newNamingProvider( final String host, final int port )
          throws NamingException
      {
          Socket socket = null;
  
          try
          {
              socket = new Socket( host, port );
  
              final ObjectInputStream input = 
                  new ObjectInputStream( new BufferedInputStream( 
socket.getInputStream() ) );
  
              final NamingProvider provider = 
                  ((NamingProvider)((MarshalledObject)input.readObject()).get());
  
              socket.close();
  
              return provider;
          } 
          catch( final Exception e )
          {
              final ServiceUnavailableException sue = 
                  new ServiceUnavailableException( e.getMessage() );
              sue.setRootCause( e );
              throw sue;
          }
          finally
          {
              if( null != socket )
              {
                  try { socket.close(); }
                  catch( final IOException ioe ) {}
              }
          }
      }
  
      protected Namespace newNamespace( final Hashtable environment )
          throws NamingException
      {
          try
          {
              final NamingProvider provider = 
                  (NamingProvider)environment.get( RemoteContext.NAMING_PROVIDER );
                  
              return new DefaultNamespace( provider.getNameParser() );
          }
          catch( final Exception e )
          {
              if( e instanceof NamingException ) 
              {
                  throw (NamingException)e;
              }
              else
              {
                  final ServiceUnavailableException sue = 
                      new ServiceUnavailableException( e.getMessage() );
                  sue.setRootCause( e );
                  throw sue;
              }
          }
      }
  }
  
  
  
  
  1.1                  
jakarta-commons-sandbox/cadastre/src/java/org/apache/avalon/cadastre/rmi/RMINamingProvider.java
  
  Index: RMINamingProvider.java
  ===================================================================
  /*
   * Copyright (C) The Apache Software Foundation. All rights reserved.
   *
   * This software is published under the terms of the Apache Software License
   * version 1.1, a copy of which has been included with this distribution in
   * the LICENSE file.
   */
  package org.apache.avalon.cadastre.rmi;
  
  import java.rmi.Remote;
  import org.apache.avalon.cadastre.NamingProvider;
  
  /**
   * The underlying communication interface for remote contexts.
   *
   * @author <a href="mailto:[EMAIL PROTECTED]";>Peter Donald</a>
   * @version $Revision: 1.1 $
   */
  public interface RMINamingProvider
      extends NamingProvider, Remote
  {
  }
  
  
  
  1.1                  
jakarta-commons-sandbox/cadastre/src/java/org/apache/avalon/cadastre/rmi/server/RMINamingProviderImpl.java
  
  Index: RMINamingProviderImpl.java
  ===================================================================
  /*
   * Copyright (C) The Apache Software Foundation. All rights reserved.
   *
   * This software is published under the terms of the Apache Software License
   * version 1.1, a copy of which has been included with this distribution in
   * the LICENSE file.
   */
  package org.apache.avalon.cadastre.rmi.server;
  
  import java.io.Serializable;
  import java.rmi.Remote;
  import java.util.ArrayList;
  import javax.naming.Binding;
  import javax.naming.CompositeName;
  import javax.naming.Context;
  import javax.naming.Name;
  import javax.naming.NameClassPair;
  import javax.naming.NameParser;
  import javax.naming.NamingEnumeration;
  import javax.naming.NamingException;
  import org.apache.avalon.cadastre.RemoteContext;
  import org.apache.avalon.cadastre.rmi.RMINamingProvider;
  
  /**
   * The RMI implementation of provider.
   *
   * @author <a href="mailto:[EMAIL PROTECTED]";>Peter Donald</a>
   * @version $Revision: 1.1 $
   */
  public class RMINamingProviderImpl
      implements Serializable, RMINamingProvider
  {
      protected Context           m_root;
  
      public RMINamingProviderImpl( final Context root )
      {
          m_root = root;
      }
  
      public NameParser getNameParser()
          throws NamingException
      {
          return m_root.getNameParser( new CompositeName() );
      }
  
      public void bind( final Name name, final String className, final Object object )
          throws NamingException
      {
          final Binding binding = new Binding( name.toString(), className, object, 
true );
          m_root.bind( name, binding );
      }
  
      public void rebind( final Name name, final String className, final Object object 
)
          throws NamingException
      {
          final Binding binding = new Binding( name.toString(), className, object, 
true );
          m_root.rebind( name, binding );
      }
  
      public Context createSubcontext( final Name name )
          throws NamingException
      {
          m_root.createSubcontext( name );
  
          final RemoteContext context = new RemoteContext( null, name );
          return context;
      }
  
      public void destroySubcontext( final Name name )
          throws NamingException
      {
          m_root.destroySubcontext( name );
      }
  
      public NameClassPair[] list( final Name name )
          throws NamingException
      {
          //Remember that the bindings returned by this 
          //actually have a nested Binding as an object
          final NamingEnumeration enum = m_root.listBindings( name );
          final ArrayList pairs = new ArrayList(); 
  
          while( enum.hasMore() )
          {
              final Binding binding = (Binding)enum.next();
              final Object object = binding.getObject();
  
              String className = null;
              
              //check if it is an entry or a context
              if( object instanceof Binding )
              {
                  //must be an entry
                  final Binding entry = (Binding)binding.getObject();
                  className = entry.getObject().getClass().getName();
              }
              else if( object instanceof Context )
              {
                  //must be a context
                  className = RemoteContext.class.getName();
              }
              else
              {
                  className = object.getClass().getName();
              }
  
              pairs.add( new NameClassPair( binding.getName(), className ) );
          }
  
          return (NameClassPair[])pairs.toArray( new NameClassPair[ 0 ] );
      }
  
      public Binding[] listBindings( final Name name )
          throws NamingException
      {
          //Remember that the bindings returned by this 
          //actually have a nested Binding as an object
          final NamingEnumeration enum = m_root.listBindings( name );
          final ArrayList bindings = new ArrayList(); 
  
          while( enum.hasMore() )
          {
              final Binding binding = (Binding)enum.next();
              Object object = binding.getObject();
              String className = null;
  
              //check if it is an entry or a context
              if( object instanceof Binding )
              {
                  //must be an entry
                  final Binding entry = (Binding)binding.getObject();
                  object = entry.getObject();
                  className = object.getClass().getName();
              }
              else if( object instanceof Context )
              {
                  //must be a context
                  className = RemoteContext.class.getName();
                  object = new RemoteContext( null, name );
              }
              else
              {
                  className = object.getClass().getName();
              }
  
              final Binding result = 
                  new Binding( binding.getName(), className, object );
              bindings.add( result );
          }
  
          return (Binding[])bindings.toArray( new Binding[ 0 ] );
      }
  
      public Object lookup( final Name name ) 
          throws NamingException
      {
          Object object = m_root.lookup( name );
  
          //check if it is an entry or a context
          if( object instanceof Binding )
          {
              object = ((Binding)object).getObject();
          }
          else if( object instanceof Context )
          {
              //must be a context
              object = new RemoteContext( null, name.getPrefix( name.size() - 1 ) );
          }
          
          return object;
      }
  
      public void unbind( final Name name ) 
          throws NamingException
      {
          m_root.unbind( name );
      }
  }
  
  
  
  1.1                  
jakarta-commons-sandbox/cadastre/src/test/org/apache/avalon/cadastre/AbstractContextTestlet.java
  
  Index: AbstractContextTestlet.java
  ===================================================================
  /*
   * Copyright (C) The Apache Software Foundation. All rights reserved.
   *
   * This software is published under the terms of the Apache Software License
   * version 1.1, a copy of which has been included with this distribution in
   * the LICENSE file.
   */
  package org.apache.avalon.cadastre;
  
  import java.util.Enumeration;
  import java.util.Hashtable;
  import javax.naming.*;
  import org.apache.testlet.*;
  
  /**
   * Unit testing for JNDI system
   *
   * @author <a href="mailto:[EMAIL PROTECTED]";>Peter Donald</a>
   * @version $Revision: 1.1 $
   */
  public abstract class AbstractContextTestlet
      extends AbstractTestlet
  {
      protected final static Object       O1 = "iO1";
      protected final static Object       O2 = "iO2";
      protected final static Object       O3 = "iO3";
      protected final static Object       O4 = "iO4";
      protected final static Object       O5 = "iO5";
      protected final static Object       O6 = "iO6";
      protected final static Object       O7 = "iO7";
      protected final static Object       O8 = "iO8";
  
      protected Context                   m_context;
  
      public void testBindToDirectContext()
          throws TestFailedException
      {
          try
          {
              m_context.bind( "O1", O1 );
              assert( "Make sure lookup returns correct object", 
                      m_context.lookup("O1").equals( O1 ) );
  
              m_context.bind( "O2", O2 );
              m_context.bind( "O3", O3 );
              m_context.bind( "O4", O4 );
              m_context.bind( "O5", O5 );
              m_context.bind( "O6", O6 );
              m_context.bind( "O7", O7 );
              m_context.bind( "O8", O8 );
  
              assert( "Make sure lookup O2 returns correct object", 
                      m_context.lookup("O2").equals( O2 ) );
              assert( "Make sure lookup O3 returns correct object", 
                      m_context.lookup("O3").equals( O3 ) );
              assert( "Make sure lookup O4 returns correct object", 
                      m_context.lookup("O4").equals( O4 ) );
              assert( "Make sure lookup O5 returns correct object", 
                      m_context.lookup("O5").equals( O5 ) );
              assert( "Make sure lookup O6 returns correct object", 
                      m_context.lookup("O6").equals( O6 ) );
              assert( "Make sure lookup O7 returns correct object", 
                      m_context.lookup("O7").equals( O7 ) );
              assert( "Make sure lookup O8 returns correct object", 
                      m_context.lookup("O8").equals( O8 ) );
          }
          catch( final NamingException ne )
          {
              throw new TestFailedException( ne.toString() );
          }   
      }
  
      public void testUnBindFromDirectContext()
          throws TestFailedException
      {
          testBindToDirectContext();
  
          try
          {
              m_context.unbind("O1");
              m_context.unbind("O2");
              m_context.unbind("O3");
              m_context.unbind("O4");
              m_context.unbind("O5");
              m_context.unbind("O6");
              m_context.unbind("O7");
              m_context.unbind("O8");
  
              final Enumeration enum = m_context.list("");
  
              if( enum.hasMoreElements() )
              {
                  throw new TestFailedException( "Failed to unbind all test elements: 
ie " + 
                                                 enum.nextElement() );
              }
          }
          catch( final NamingException ne )
          {
              throw new TestFailedException( ne.toString() );
          }
      }
  
      public void testBindToDirectSubContext()
          throws TestFailedException
      {
          try
          {
              m_context.createSubcontext( "x" );
              m_context.bind( "x/O1", O1 );
              assert( "Make sure lookup x/O1 returns correct object", 
                      m_context.lookup("x/O1").equals( O1 ) );
              assert( "Make sure lookup x/ returns correct object", 
                      m_context.lookup("x/") instanceof Context );
              assert( "Make sure lookup x returns correct object", 
                      m_context.lookup("x") instanceof Context );
  
              m_context.bind( "x/O2", O2 );
              assert( "Make sure lookup x/O2 returns correct object", 
                      m_context.lookup("x/O2").equals( O2 ) );
              assert( "Make sure lookup x/ returns correct object", 
                      m_context.lookup("x/") instanceof Context );
              assert( "Make sure lookup x returns correct object", 
                      m_context.lookup("x") instanceof Context );
  
              m_context.bind( "x/O3", O3 );
              assert( "Make sure lookup x/O3 returns correct object", 
                      m_context.lookup("x/O3").equals( O3 ) );
              assert( "Make sure lookup x/ returns correct object", 
                      m_context.lookup("x/") instanceof Context );
              assert( "Make sure lookup x returns correct object", 
                      m_context.lookup("x") instanceof Context );
          }
          catch( final NamingException ne )
          {
              throw new TestFailedException( ne.toString() );
          }   
      }
  
      public void testUnBindFromDirectSubContext()
          throws TestFailedException
      {
          testBindToDirectSubContext();
  
          try
          {
              m_context.unbind("x/O1");
              m_context.unbind("x/O2");
              m_context.unbind("x/O3");
  
              final Enumeration enum = m_context.list("x/");
  
              if( enum.hasMoreElements() )
              {
                  throw new TestFailedException( "Failed to unbind all test elements: 
ie " + 
                                                 enum.nextElement() );
              }
  
              //unbind a unbound name - OK
              m_context.unbind("a");
              m_context.unbind("x/a");
          }
          catch( final NamingException ne )
          {
              throw new TestFailedException( ne.toString() );
          }
      }
  
      public void testBindToArbitarySubContexts()
          throws TestFailedException
      {
          try
          {
              m_context.createSubcontext( "x" );
              m_context.createSubcontext( "x/y" );
              m_context.bind( "x/y/O1", O1 );
              assert( "Make sure lookup x/y/O1 returns correct object", 
                      m_context.lookup("x/y/O1").equals( O1 ) );
              assert( "Make sure lookup x/y/ returns correct object", 
                      m_context.lookup("x/y/") instanceof Context );
              assert( "Make sure lookup x/y returns correct object", 
                      m_context.lookup("x/y") instanceof Context );
              assert( "Make sure lookup x returns correct object", 
                      m_context.lookup("x") instanceof Context );
  
              try 
              {
                  m_context.bind( "x/y", O2 ); 
                  assert("Bound object to directory x/y.", false );
              }
              catch( final NamingException ne ) {}
  
              try 
              {
                  m_context.bind( "x/y/", O2 ); 
                  assert("Bound object to directory x/y/.", false );
              }
              catch( final NamingException ne ) {}
  
              try 
              {
                  m_context.bind( "x/", O2 ); 
                  assert("Bound object to directory x/.", false );
              }
              catch( final NamingException ne ) {}
  
              try 
              {
                  m_context.bind( "x", O2 ); 
                  assert("Bound object to directory x.", false );
              }
              catch( final NamingException ne ) {}
  
              try 
              {
                  m_context.createSubcontext( "z" );
                  m_context.bind( "z/", O2 ); 
                  assert("Bound object to empty name z/.", false );
              }
              catch( final NamingException ne ) {}
          }
          catch( final NamingException ne )
          {
              throw new TestFailedException( ne.toString() );
          }   
      }
  
      public void testUnBindFromArbitarySubContext()
          throws TestFailedException
      {
          testBindToArbitarySubContexts();
  
          try
          {
              m_context.unbind("x/y/O1");
  
              //unbind non-existants - OK
              m_context.unbind("x/O2");
              m_context.unbind("x/O3");
  
              final Enumeration enum = m_context.list("x/y");
  
              if( enum.hasMoreElements() )
              {
                  throw new TestFailedException( "Failed to unbind all test elements: 
ie " + 
                                                 enum.nextElement() );
              }
  
              //Not sure if the next is legal????
              /*
              try 
              {
                  m_context.unbind("x");
                  assert( "Unbound acontext!", false );
              }
              catch( final NamingException ne ) {}
              */
  
              //unbind a unbound name - OK
              m_context.unbind("a");
              m_context.unbind("x/a");
          }
          catch( final NamingException ne )
          {
              throw new TestFailedException( ne.toString() );
          }
      }
  
      public void testCreateSubContext()
          throws TestFailedException
      {
          try
          {
              m_context.createSubcontext( "x" );
              assert( "Make sure lookup x returns correct object", 
                      m_context.lookup("x") instanceof Context );
              m_context.createSubcontext( "x/y" );
              assert( "Make sure lookup x/y returns correct object", 
                      m_context.lookup("x/y") instanceof Context );
  
              try
              {
                  m_context.createSubcontext( "z/x/y" );
                  assert( "Created a subcontext when intermediate contexts not 
created", false );
              }
              catch( final NamingException ne ) {}
  
              try 
              {
                  m_context.createSubcontext( "x/y" );
                  assert("createSubContext when context alreadty exists.", false );
              }
              catch( final NamingException ne ) {}
          }
          catch( final NamingException ne )
          {
              throw new TestFailedException( ne.toString() );
          }   
      }
  
      public void testDestroySubContext()
          throws TestFailedException
      {
          testCreateSubContext();
  
          try
          {
              try 
              {
                  m_context.destroySubcontext( "x" );
                  assert("destroySubContext with existing subContexts.", false );
              }
              catch( final NamingException ne ) {}
  
              try 
              {
                  m_context.destroySubcontext( "x/y/" );
                  assert("destroySubContext with empty subContext name.", false );
              }
              catch( final NamingException ne ) {}
  
              m_context.destroySubcontext( "x/y" );
              m_context.destroySubcontext( "x" );
  
              try 
              {
                  m_context.lookup("z");
                  assert("subContext exists after delete.", false );
              }
              catch( final NamingException ne ) {}
          }
          catch( final NamingException ne )
          {
              throw new TestFailedException( ne.toString() );
          }   
      }
  
  
      public void testRenameToDirectContext()
          throws TestFailedException
      {
          try
          {
              m_context.bind( "O1", O1 );
              m_context.rename( "O1", "+O1" );
              assert( "Make sure lookup not null", 
                      m_context.lookup("+O1") != null );
              assert( "Make sure lookup +O1 returns correct object", 
                      m_context.lookup("+O1").equals( O1 ) );
  
              try 
              {
                  m_context.lookup("O1");
                  assert( "Old name still bound after rename", false );
              }
              catch( final NameNotFoundException nnfe ) {}
  
              m_context.bind( "O2", O2 );
              m_context.rename( "O2", "+O2" );
              assert( "Make sure lookup not null", 
                      m_context.lookup("+O2") != null );
              assert( "Make sure lookup +O2 returns correct object", 
                      m_context.lookup("+O2").equals( O2 ) );
  
              try 
              {
                  m_context.lookup("O2");
                  assert( "Old name O2 still bound after rename", false );
              }
              catch( final NameNotFoundException nnfe ) {}
  
              m_context.bind( "O3", O3 );
              m_context.rename( "O3", "+O3" );
              assert( "Make sure lookup not null", 
                      m_context.lookup("+O3") != null );
              assert( "Make sure lookup +O3 returns correct object", 
                      m_context.lookup("+O3").equals( O3 ) );
              try 
              {
                  m_context.lookup("O3");
                  assert( "Old name O3 still bound after rename", false );
              }
              catch( final NameNotFoundException nnfe ) {}
  
              m_context.bind( "O4", O4 );
              m_context.rename( "O4", "+O4" );
              assert( "Make sure lookup not null", 
                      m_context.lookup("+O4") != null );
              assert( "Make sure lookup +04 returns correct object", 
                      m_context.lookup("+O4").equals( O4 ) );
  
              try 
              {
                  m_context.lookup("O3");
                  assert( "Old name O3 still bound after rename", false );
              }
              catch( final NameNotFoundException nnfe ) {}
          }
          catch( final NamingException ne )
          {
              throw new TestFailedException( ne.toString() );
          }   
      }
  
      public void testReBind()
          throws TestFailedException
      {
          try
          {
              m_context.bind( "O1", O1 );
              assert( "Make sure lookup returns correct object", 
                      m_context.lookup("O1").equals( O1 ) );
  
              m_context.bind( "O2", O2 );
              m_context.bind( "O3", O3 );
              m_context.bind( "O4", O4 );
              m_context.bind( "O5", O5 );
              m_context.bind( "O6", O6 );
              m_context.bind( "O7", O7 );
              m_context.bind( "O8", O8 );
              assert( "Make sure lookup O2 returns correct object", 
                      m_context.lookup("O2").equals( O2 ) );
              assert( "Make sure lookup O3 returns correct object", 
                      m_context.lookup("O3").equals( O3 ) );
              assert( "Make sure lookup O4 returns correct object", 
                      m_context.lookup("O4").equals( O4 ) );
              assert( "Make sure lookup O5 returns correct object", 
                      m_context.lookup("O5").equals( O5 ) );
              assert( "Make sure lookup O6 returns correct object", 
                      m_context.lookup("O6").equals( O6 ) );
              assert( "Make sure lookup O7 returns correct object", 
                      m_context.lookup("O7").equals( O7 ) );
              assert( "Make sure lookup O8 returns correct object", 
                      m_context.lookup("O8").equals( O8 ) );
          }
          catch( final NamingException ne )
          {
              throw new TestFailedException( ne.toString() );
          } 
  
          try
          {
              m_context.rebind( "O1", O2 );
              assert( "Rebind of O1 returns correct object", 
                      m_context.lookup("O1").equals( O2 ) );
  
              m_context.rebind( "O2", O3 );
              m_context.rebind( "O3", O4 );
              m_context.rebind( "O4", O5 );
              m_context.rebind( "O5", O6 );
              m_context.rebind( "O6", O7 );
              m_context.rebind( "O7", O8 );
              m_context.rebind( "O8", O1 );
              assert( "Rebind of O2 returns correct object", 
                      m_context.lookup("O2").equals( O3 ) );
              assert( "Rebind of O3 returns correct object", 
                      m_context.lookup("O3").equals( O4 ) );
              assert( "Rebind of O4 returns correct object", 
                      m_context.lookup("O4").equals( O5 ) );
              assert( "Rebind of O5 returns correct object", 
                      m_context.lookup("O5").equals( O6 ) );
              assert( "Rebind of O6 returns correct object", 
                      m_context.lookup("O6").equals( O7 ) );
              assert( "Rebind of O7 returns correct object", 
                      m_context.lookup("O7").equals( O8 ) );
              assert( "Rebind of O8 returns correct object", 
                      m_context.lookup("O8").equals( O1 ) );
  
              m_context.bind( "x", O1 );
              assert( "Make sure lookup x returns correct object", 
                      m_context.lookup("x").equals( O1 ) );
              m_context.rebind( "x", O8 );
              assert( "Rebind of x returns correct object", 
                      m_context.lookup("x").equals( O8 ) );
          }
          catch( final NamingException ne )
          {
              throw new TestFailedException( ne.toString() );
          } 
          
          try 
          {
              m_context.createSubcontext( "x" );
              m_context.rebind( "x/", O1 );
              assert( "Able to rebind empty name", false );
          }
          catch( final NamingException ne ) {}
      }
  }
  
  
  
  1.1                  
jakarta-commons-sandbox/cadastre/src/test/org/apache/avalon/cadastre/rmi/RMIContextTestlet.java
  
  Index: RMIContextTestlet.java
  ===================================================================
  /*
   * Copyright (C) The Apache Software Foundation. All rights reserved.
   *
   * This software is published under the terms of the Apache Software License
   * version 1.1, a copy of which has been included with this distribution in
   * the LICENSE file.
   */
  package org.apache.avalon.cadastre.rmi;
  
  import java.util.Hashtable;
  import javax.naming.Context;
  import org.apache.testlet.*;
  import org.apache.avalon.cadastre.AbstractContextTestlet;
  import org.apache.avalon.cadastre.rmi.server.Main;
  
  /**
   * Unit testing for JNDI system
   *
   * @author <a href="mailto:[EMAIL PROTECTED]";>Peter Donald</a>
   * @version $Revision: 1.1 $
   */
  public class RMIContextTestlet
      extends AbstractContextTestlet
  {
      protected int                       m_id;
      protected Main                      m_server = new Main();
  
      public void initialize()
      {
          try
          {
              m_server.start();
  
              final Thread thread = new Thread( m_server );
              thread.start();
  
              final RMIInitialContextFactory factory = new RMIInitialContextFactory();
              final Context context = factory.getInitialContext( new Hashtable() );
              m_context = context.createSubcontext( "test" + m_id++ );
              context.close();
          }
          catch( final Exception e )
          {
              System.out.println( "Failed test initialisation " + e );
              e.printStackTrace();
          }
      }
  
      public void destroy()
      {
          try
          {
              m_context.close();
              m_context = null;
              m_server.stop();
          }
          catch( final Exception e )
          {
          }
      }
  }
  
  
  
  1.1                  
jakarta-commons-sandbox/cadastre/src/test/org/apache/avalon/cadastre/rmi/server/Main.java
  
  Index: Main.java
  ===================================================================
  /*
   * Copyright (C) The Apache Software Foundation. All rights reserved.
   *
   * This software is published under the terms of the Apache Software License
   * version 1.1, a copy of which has been included with this distribution in
   * the LICENSE file.
   */
  package org.apache.avalon.cadastre.rmi.server;
  
  import java.io.IOException;
  import java.io.ObjectOutputStream;
  import java.net.ServerSocket;
  import java.net.Socket;
  import java.rmi.MarshalledObject;
  import java.rmi.server.UnicastRemoteObject;
  import org.apache.avalon.cadastre.DefaultNameParser;
  import org.apache.avalon.cadastre.DefaultNamespace;
  import org.apache.avalon.cadastre.memory.MemoryContext;
  import org.apache.avalon.cadastre.memory.MemoryInitialContextFactory;
  
  public class Main
      implements Runnable
  {
      public static void main( final String[] args )
          throws Exception
      {
          final Main main = new Main();
          main.start();
          main.accept();
      }
  
      protected boolean                m_debug = true;
      protected RMINamingProviderImpl  m_server;
      protected ServerSocket           m_serverSocket;
      protected MarshalledObject       m_serverStub;
      protected boolean                m_running;
      protected boolean                m_initialized;
  
      public void init()
          throws Exception
      {
          if( m_initialized ) return;
  
          try
          {
              if( m_debug ) System.out.println( "Starting server on port " + 1977 );
              m_serverSocket = new ServerSocket( 1977 );
              m_initialized = true;
          }
          catch( final IOException ioe )
          {
              if( m_debug ) System.out.println( "Failed starting server" );
              throw ioe;
          }
      }
  
      public void start()
          throws Exception
      {
          init();
          export();
      }
  
      public void export()
          throws Exception
      {
          final DefaultNameParser parser = new DefaultNameParser();
          final DefaultNamespace namespace = new DefaultNamespace( parser );
          final MemoryContext context = new MemoryContext( namespace, null, null );
          m_server = new RMINamingProviderImpl( context );
  
          // Start listener
          try
          {
              // Export server
              if( m_debug ) System.out.println( "Exporting RMI object on port " + 1099 
);
              m_serverStub =
                  new MarshalledObject( UnicastRemoteObject.exportObject( m_server, 
1099 ) );
          }
          catch( final IOException ioe )
          {
              if( m_debug ) System.out.println( "Failed exporting object" );
              throw ioe;
          }
      }
  
      public void dispose()
          throws Exception
      {
          if( m_debug ) System.out.println( "Shutting down server" );
          m_running = false;
          final ServerSocket serverSocket = m_serverSocket;
          m_serverSocket = null;
          serverSocket.close();
          if( m_debug ) System.out.println( "Server shutdown" );
      }
  
      public void stop()
          throws Exception
      {
          if( m_debug ) System.out.println( "Stopping" );
          m_running = false;
          if( m_debug ) System.out.println( "Unexporting object" );
          UnicastRemoteObject.unexportObject( m_server, true );
          m_serverStub = null;
          if( m_debug ) System.out.println( "Server stopped" );
      }
  
      public void accept()
      {
          m_running = true;
          while( m_running )
          {
              // Accept a connection
              try
              {
                  final Socket socket = m_serverSocket.accept();
                  if( m_debug ) System.out.println( "Accepted Connection" );
                  final ObjectOutputStream output =
                      new ObjectOutputStream( socket.getOutputStream() );
  
                  output.writeObject( m_serverStub );
  
                  socket.close();
              }
              catch( final IOException ioe )
              {
                  if( false == m_running ) break;
                  ioe.printStackTrace();
              }
          }
      }
  
      public void run()
      {
          accept();
      }
  }
  
  
  

Reply via email to