directory-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From akaras...@apache.org
Subject svn commit: rev 55540 - in incubator/directory/eve/trunk/backend/core: . src/aspects/org/apache/eve/jndi src/java/org/apache/eve src/java/org/apache/eve/db src/java/org/apache/eve/db/jdbm src/java/org/apache/eve/exception src/java/org/apache/eve/jndi src/java/org/apache/eve/jndi/ibs src/java/org/apache/eve/schema src/java/org/apache/eve/schema/bootstrap src/test/org/apache/eve/jndi src/test/org/apache/eve/jndi/ibs
Date Mon, 25 Oct 2004 23:59:05 GMT
Author: akarasulu
Date: Mon Oct 25 16:59:04 2004
New Revision: 55540

Added:
   incubator/directory/eve/trunk/backend/core/src/java/org/apache/eve/exception/
   incubator/directory/eve/trunk/backend/core/src/java/org/apache/eve/exception/EveAttributeInUseException.java
   incubator/directory/eve/trunk/backend/core/src/java/org/apache/eve/exception/EveException.java
   incubator/directory/eve/trunk/backend/core/src/java/org/apache/eve/exception/EveInterceptorException.java
   incubator/directory/eve/trunk/backend/core/src/java/org/apache/eve/exception/EveNamingException.java
   incubator/directory/eve/trunk/backend/core/src/java/org/apache/eve/jndi/AbstractJndiTest.java
   incubator/directory/eve/trunk/backend/core/src/java/org/apache/eve/jndi/BaseInterceptor.java
   incubator/directory/eve/trunk/backend/core/src/java/org/apache/eve/jndi/InvocationMethodEnum.java
   incubator/directory/eve/trunk/backend/core/src/java/org/apache/eve/jndi/OnErrorPipeline.java
   incubator/directory/eve/trunk/backend/core/src/java/org/apache/eve/jndi/ibs/
   incubator/directory/eve/trunk/backend/core/src/java/org/apache/eve/jndi/ibs/EveExceptionService.java
   incubator/directory/eve/trunk/backend/core/src/java/org/apache/eve/schema/ConcreteNameComponentNormalizer.java
      - copied, changed from rev 55390, incubator/directory/eve/trunk/backend/core/src/java/org/apache/eve/schema/bootstrap/RegistryNameComponentNormalizer.java
   incubator/directory/eve/trunk/backend/core/src/test/org/apache/eve/jndi/CreateContextTest.java
   incubator/directory/eve/trunk/backend/core/src/test/org/apache/eve/jndi/DestroyContextTest.java
   incubator/directory/eve/trunk/backend/core/src/test/org/apache/eve/jndi/SearchContextTest.java
   incubator/directory/eve/trunk/backend/core/src/test/org/apache/eve/jndi/ibs/
Removed:
   incubator/directory/eve/trunk/backend/core/src/java/org/apache/eve/jndi/AfterFailurePipeline.java
   incubator/directory/eve/trunk/backend/core/src/java/org/apache/eve/jndi/InterceptorException.java
   incubator/directory/eve/trunk/backend/core/src/java/org/apache/eve/schema/bootstrap/RegistryNameComponentNormalizer.java
Modified:
   incubator/directory/eve/trunk/backend/core/maven.xml
   incubator/directory/eve/trunk/backend/core/project.properties
   incubator/directory/eve/trunk/backend/core/project.xml
   incubator/directory/eve/trunk/backend/core/src/aspects/org/apache/eve/jndi/ProviderNexusAspect.java
   incubator/directory/eve/trunk/backend/core/src/java/org/apache/eve/RootNexus.java
   incubator/directory/eve/trunk/backend/core/src/java/org/apache/eve/db/IndexRecord.java
   incubator/directory/eve/trunk/backend/core/src/java/org/apache/eve/db/SearchResultEnumeration.java
   incubator/directory/eve/trunk/backend/core/src/java/org/apache/eve/db/jdbm/JdbmDatabase.java
   incubator/directory/eve/trunk/backend/core/src/java/org/apache/eve/jndi/EveContextFactory.java
   incubator/directory/eve/trunk/backend/core/src/java/org/apache/eve/jndi/EveJndiProvider.java
   incubator/directory/eve/trunk/backend/core/src/java/org/apache/eve/jndi/FailFastPipeline.java
   incubator/directory/eve/trunk/backend/core/src/java/org/apache/eve/jndi/Interceptor.java
   incubator/directory/eve/trunk/backend/core/src/java/org/apache/eve/jndi/InterceptorPipeline.java
   incubator/directory/eve/trunk/backend/core/src/java/org/apache/eve/jndi/Invocation.java
   incubator/directory/eve/trunk/backend/core/src/java/org/apache/eve/schema/bootstrap/SystemComparatorProducer.java
   incubator/directory/eve/trunk/backend/core/src/java/org/apache/eve/schema/bootstrap/SystemNormalizerProducer.java
   incubator/directory/eve/trunk/backend/core/src/test/org/apache/eve/jndi/EveContextFactoryTest.java
Log:


Modified: incubator/directory/eve/trunk/backend/core/maven.xml
==============================================================================
--- incubator/directory/eve/trunk/backend/core/maven.xml	(original)
+++ incubator/directory/eve/trunk/backend/core/maven.xml	Mon Oct 25 16:59:04 2004
@@ -11,10 +11,6 @@
     <attainGoal name="eve:schema"/>
   </preGoal> 
  
-  <preGoal name="aspectj:compile">
-    <attainGoal name="eve:schema"/>
-  </preGoal> 
- 
   <postGoal name="java:compile">
     <attainGoal name="aspectj:compile"/>
   </postGoal>

Modified: incubator/directory/eve/trunk/backend/core/project.properties
==============================================================================
--- incubator/directory/eve/trunk/backend/core/project.properties	(original)
+++ incubator/directory/eve/trunk/backend/core/project.properties	Mon Oct 25 16:59:04 2004
@@ -1,3 +1,5 @@
+maven.junit.fork=yes
+
 maven.javadoc.private=true
 maven.javadoc.overview=src/java/org/apache/eve/schema/overview.html
 maven.javadoc.customtags=tag1 tag2

Modified: incubator/directory/eve/trunk/backend/core/project.xml
==============================================================================
--- incubator/directory/eve/trunk/backend/core/project.xml	(original)
+++ incubator/directory/eve/trunk/backend/core/project.xml	Mon Oct 25 16:59:04 2004
@@ -10,12 +10,12 @@
   <currentVersion>SNAPSHOT</currentVersion>
   <inceptionYear>2002</inceptionYear>
   <shortDescription>Eve's Backend Subsystem</shortDescription>
-  <description>
-      Eve's backend subsystem, providing a LDAP namespace based backing store
-      using JNDI as the access API.  This deliverable is a JNDI LDAP namespace
-      provider but it does not use the LDAP protocol to access and store 
-      entries.  Instead entries are stored within a custom database 
-      implementation on disk designed for fast reads and hierarchical data.
+  <description>
+      Eve's backend subsystem, providing a LDAP namespace based backing store
+      using JNDI as the access API.  This deliverable is a JNDI LDAP namespace
+      provider but it does not use the LDAP protocol to access and store 
+      entries.  Instead entries are stored within a custom database 
+      implementation on disk designed for fast reads and hierarchical data.
     </description>
   <dependencies>
     <dependency>
@@ -29,6 +29,12 @@
       <artifactId>oro</artifactId>
       <version>2.0.7</version>
       <url>http://jakarta.apache.org/oro</url>
+    </dependency>
+    <dependency>
+      <groupId>commons-io</groupId>
+      <artifactId>commons-io</artifactId>
+      <version>1.0</version>
+      <url>http://jakarta.apache.org/commons/io</url>
     </dependency>
     <dependency>
       <groupId>regexp</groupId>

Modified: incubator/directory/eve/trunk/backend/core/src/aspects/org/apache/eve/jndi/ProviderNexusAspect.java
==============================================================================
--- incubator/directory/eve/trunk/backend/core/src/aspects/org/apache/eve/jndi/ProviderNexusAspect.java	(original)
+++ incubator/directory/eve/trunk/backend/core/src/aspects/org/apache/eve/jndi/ProviderNexusAspect.java	Mon Oct 25 16:59:04 2004
@@ -1,22 +1,22 @@
-package org.apache.eve.jndi ;
+package org.apache.eve.jndi;
 
 
-import java.util.Map ;
-import java.util.Stack ;
-import java.util.Iterator ;
-import java.util.EmptyStackException ;
-        
-import javax.naming.Name ;
-import javax.naming.Context ;
-import javax.naming.ldap.LdapContext ;
-import javax.naming.NamingEnumeration ;
-import javax.naming.directory.Attributes ;
-import javax.naming.directory.SearchControls ;
-import javax.naming.directory.ModificationItem ;
-
-import org.apache.ldap.common.filter.ExprNode ;
-import org.apache.eve.PartitionNexus ;
-import org.apache.eve.db.Database ;
+import java.util.Map;
+import java.util.Stack;
+import java.util.Iterator;
+import java.util.EmptyStackException;
+        
+import javax.naming.Name;
+import javax.naming.Context;
+import javax.naming.ldap.LdapContext;
+import javax.naming.NamingEnumeration;
+import javax.naming.directory.Attributes;
+import javax.naming.directory.SearchControls;
+import javax.naming.directory.ModificationItem;
+
+import org.apache.ldap.common.filter.ExprNode;
+import org.apache.eve.PartitionNexus;
+import org.apache.eve.db.Database;
 import org.apache.eve.ContextPartition;
 
 
@@ -40,7 +40,7 @@
      * backend nexus calls made by the JndiProvider's contexts within the same 
      * thread of execution.
      */
-    private static ThreadLocal EveJndiProvider.s_contextStacks = new ThreadLocal() ;
+    private static ThreadLocal EveJndiProvider.s_contextStacks = new ThreadLocal();
     
     
     // ------------------------------------------------------------------------
@@ -56,15 +56,15 @@
      */
     private static void EveJndiProvider.push( LdapContext context )
     {
-        Stack stack = ( Stack ) s_contextStacks.get() ;
+        Stack stack = ( Stack ) s_contextStacks.get();
         
         if ( null == stack )
         {
-            stack = new Stack() ;
-            s_contextStacks.set( stack ) ;
+            stack = new Stack();
+            s_contextStacks.set( stack );
         }
         
-        stack.push( context ) ;
+        stack.push( context );
     } 
 
 
@@ -76,14 +76,14 @@
      */
     private static LdapContext EveJndiProvider.pop()
     {
-        Stack stack = ( Stack ) s_contextStacks.get() ;
+        Stack stack = ( Stack ) s_contextStacks.get();
         
         if ( null == stack )
         {
-            throw new EmptyStackException() ;
+            throw new EmptyStackException();
         }
         
-        return ( LdapContext ) stack.pop() ;
+        return ( LdapContext ) stack.pop();
     }
     
     
@@ -94,14 +94,14 @@
      */
     static LdapContext EveJndiProvider.peek()
     {
-        Stack stack = ( Stack ) s_contextStacks.get() ;
+        Stack stack = ( Stack ) s_contextStacks.get();
         
         if ( null == stack )
         {
-            throw new EmptyStackException() ;
+            throw new EmptyStackException();
         }
         
-        return ( LdapContext ) stack.peek() ;
+        return ( LdapContext ) stack.peek();
     }
     
     
@@ -117,14 +117,14 @@
      */    
     private static Stack getContextStack()
     {
-        Stack stack = ( Stack ) EveJndiProvider.s_contextStacks.get() ;
+        Stack stack = ( Stack ) EveJndiProvider.s_contextStacks.get();
         
         if ( null == stack )
         {
-            throw new NullPointerException( "Thread had null stack" ) ;
+            throw new NullPointerException( "Thread had null stack" );
         }
         
-        return ( Stack ) stack.clone() ;
+        return ( Stack ) stack.clone();
     }
     
     
@@ -170,17 +170,17 @@
         call( public void move( Name, Name ) ) ||
         call( public void move( Name, Name, String, boolean ) ) ||
         call( public NamingEnumeration 
-           search( Name, Map, ExprNode, SearchControls ) ) ) ;
+           search( Name, Map, ExprNode, SearchControls ) ) );
         
 
     /**
      * Selects join points where the Invokation default constructor executes.
      * 
-     * @param a_invocation the Invocation instantiated
+     * @param invocation the Invocation instantiated
      */
-    pointcut newInvocation( Invocation a_invocation ):
-        target( a_invocation ) &&
-        execution( public Invocation.new() ) ;
+    pointcut newInvocation( Invocation invocation ):
+        target( invocation ) &&
+        execution( public Invocation.new() );
       
         
     // ------------------------------------------------------------------------
@@ -188,31 +188,31 @@
     // ------------------------------------------------------------------------
 
 
-    before( Context a_caller ):
-        jndiNexusCalls( a_caller )
+    before( Context caller ):
+        jndiNexusCalls( caller )
         {
-    		EveJndiProvider.push( ( LdapContext ) a_caller ) ;
+    		EveJndiProvider.push( ( LdapContext ) caller );
             //System.out.println( "\npushed " + a_caller + " for join point "
-            //    + thisJoinPoint ) ;
+            //    + thisJoinPoint );
         }
         
 
-    after( Context a_caller ):
-        jndiNexusCalls( a_caller ) 
+    after( Context caller ):
+        jndiNexusCalls( caller ) 
         {
-            LdapContext l_head = EveJndiProvider.pop() ;
+            LdapContext head = EveJndiProvider.pop();
             //System.out.println( "\npopped " + a_caller + " for join point "
-            //    + thisJoinPoint ) ;
+            //    + thisJoinPoint );
         }
       
         
-    after( Invocation a_invocation ):
-        newInvocation( a_invocation )
+    after( Invocation invocation ):
+        newInvocation( invocation )
         {
-            a_invocation.setContextStack( getContextStack() ) ;
+            invocation.setContextStack( getContextStack() );
             //System.out.println( 
             //    "\nJust set the context stack on a new Invocation: " 
-            //    + thisJoinPoint ) ;
+            //    + thisJoinPoint );
         }
 }
 

Modified: incubator/directory/eve/trunk/backend/core/src/java/org/apache/eve/RootNexus.java
==============================================================================
--- incubator/directory/eve/trunk/backend/core/src/java/org/apache/eve/RootNexus.java	(original)
+++ incubator/directory/eve/trunk/backend/core/src/java/org/apache/eve/RootNexus.java	Mon Oct 25 16:59:04 2004
@@ -161,6 +161,12 @@
 
 
     /**
+     * Looks up the backend corresponding to the entry first, then checks to
+     * see if the entry already exists.  If so an exception is thrown.  If not
+     * the add operation against the backend proceeds.  This check is performed
+     * here so backend implementors do not have to worry about performing these
+     * kinds of checks.
+     *
      * @see BackingStore#add(String, Name, Attributes)
      */
     public void add( String updn, Name dn, Attributes an_entry ) throws NamingException

Modified: incubator/directory/eve/trunk/backend/core/src/java/org/apache/eve/db/IndexRecord.java
==============================================================================
--- incubator/directory/eve/trunk/backend/core/src/java/org/apache/eve/db/IndexRecord.java	(original)
+++ incubator/directory/eve/trunk/backend/core/src/java/org/apache/eve/db/IndexRecord.java	Mon Oct 25 16:59:04 2004
@@ -46,8 +46,8 @@
      */
     public void setTuple( Tuple tuple, Attributes entry )
     {
-        tuple.setKey( tuple.getKey() );
-        tuple.setValue( tuple.getValue() );
+        this.tuple.setKey( tuple.getKey() );
+        this.tuple.setValue( tuple.getValue() );
         this.entry = entry;
     }
 
@@ -61,8 +61,8 @@
      */
     public void setSwapped( Tuple tuple, Attributes entry )
     {
-        tuple.setKey( tuple.getValue() );
-        tuple.setValue( tuple.getKey() );
+        this.tuple.setKey( tuple.getValue() );
+        this.tuple.setValue( tuple.getKey() );
         this.entry = entry;
     }
 

Modified: incubator/directory/eve/trunk/backend/core/src/java/org/apache/eve/db/SearchResultEnumeration.java
==============================================================================
--- incubator/directory/eve/trunk/backend/core/src/java/org/apache/eve/db/SearchResultEnumeration.java	(original)
+++ incubator/directory/eve/trunk/backend/core/src/java/org/apache/eve/db/SearchResultEnumeration.java	Mon Oct 25 16:59:04 2004
@@ -88,27 +88,36 @@
     public Object next() throws NamingException
     {
         IndexRecord rec = ( IndexRecord ) underlying.next();
-        Attributes entry = new LockableAttributesImpl();
+        Attributes entry;
         String name = db.getEntryUpdn( rec.getEntryId() );
         
         if ( null == rec.getAttributes() )
         {
             rec.setAttributes( db.lookup( rec.getEntryId() ) );
         }
-        
-        for ( int ii = 0; ii < attrIds.length; ii++ )
+
+        if ( attrIds == null )
+        {
+            entry = ( Attributes ) rec.getAttributes().clone();
+        }
+        else
         {
-            // there is no attribute by that name in the entry so we continue
-            if ( null == entry.get( attrIds[ii] ) ) 
+            entry = new LockableAttributesImpl();
+
+            for ( int ii = 0; ii < attrIds.length; ii++ )
             {
-                continue;
+                // there is no attribute by that name in the entry so we continue
+                if ( null == rec.getAttributes().get( attrIds[ii] ) )
+                {
+                    continue;
+                }
+
+                // clone attribute to stuff into the new resultant entry
+                Attribute attr = ( Attribute ) rec.getAttributes().get( attrIds[ii] ).clone();
+                entry.put( attr );
             }
-            
-            // clone attribute to stuff into the new resultant entry
-            Attribute attr = ( Attribute ) entry.clone();
-            entry.put( attr );
         }
-        
+
         return new DbSearchResult( rec.getEntryId(), name, null, entry );
     }
 

Modified: incubator/directory/eve/trunk/backend/core/src/java/org/apache/eve/db/jdbm/JdbmDatabase.java
==============================================================================
--- incubator/directory/eve/trunk/backend/core/src/java/org/apache/eve/db/jdbm/JdbmDatabase.java	(original)
+++ incubator/directory/eve/trunk/backend/core/src/java/org/apache/eve/db/jdbm/JdbmDatabase.java	Mon Oct 25 16:59:04 2004
@@ -660,9 +660,11 @@
      */
     public void add( String updn, Name dn, Attributes entry ) throws NamingException
     {
-        BigInteger id = master.getNextId();
+        BigInteger id;
         BigInteger parentId = null;
-        
+
+        id = master.getNextId();
+
         //
         // Suffix entry cannot have a parent since it is the root so it is 
         // capped off using the zero value which no entry can have since 

Added: incubator/directory/eve/trunk/backend/core/src/java/org/apache/eve/exception/EveAttributeInUseException.java
==============================================================================
--- (empty file)
+++ incubator/directory/eve/trunk/backend/core/src/java/org/apache/eve/exception/EveAttributeInUseException.java	Mon Oct 25 16:59:04 2004
@@ -0,0 +1,38 @@
+/*
+ *   Copyright 2004 The Apache Software Foundation
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+package org.apache.eve.exception;
+
+
+import javax.naming.directory.AttributeInUseException;
+
+import org.apache.ldap.common.message.ResultCodeEnum;
+
+
+/**
+ * A subclass of AttributeInUseException which holds the LDAP resultCode
+ * associated with the exception.
+ *
+ * @author <a href="mailto:directory-dev@incubator.apache.org">Apache Directory Project</a>
+ * @version $Rev$
+ */
+public class EveAttributeInUseException extends AttributeInUseException implements EveException
+{
+    public ResultCodeEnum getResultCode()
+    {
+        return ResultCodeEnum.ENTRYALREADYEXISTS;
+    }
+}

Added: incubator/directory/eve/trunk/backend/core/src/java/org/apache/eve/exception/EveException.java
==============================================================================
--- (empty file)
+++ incubator/directory/eve/trunk/backend/core/src/java/org/apache/eve/exception/EveException.java	Mon Oct 25 16:59:04 2004
@@ -0,0 +1,37 @@
+/*
+ *   Copyright 2004 The Apache Software Foundation
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+package org.apache.eve.exception;
+
+
+import org.apache.ldap.common.message.ResultCodeEnum;
+
+
+/**
+ * An Eve exception add LDAP specific information to NamingExceptions.
+ *
+ * @author <a href="mailto:directory-dev@incubator.apache.org">Apache Directory Project</a>
+ * @version $Rev$
+ */
+public interface EveException
+{
+    /**
+     * Gets the LDAP result code that would be associated with this exception.
+     *
+     * @return
+     */
+    public ResultCodeEnum getResultCode();
+}

Added: incubator/directory/eve/trunk/backend/core/src/java/org/apache/eve/exception/EveInterceptorException.java
==============================================================================
--- (empty file)
+++ incubator/directory/eve/trunk/backend/core/src/java/org/apache/eve/exception/EveInterceptorException.java	Mon Oct 25 16:59:04 2004
@@ -0,0 +1,124 @@
+/*
+ *   Copyright 2004 The Apache Software Foundation
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+package org.apache.eve.exception;
+
+
+import org.apache.ldap.common.message.ResultCodeEnum;
+
+import org.apache.eve.jndi.Invocation;
+import org.apache.eve.jndi.Interceptor;
+
+
+/**
+ * Exception thrown by an Interceptor while intercepting an Invocation.
+ * Interceptor failures caught from the method are bundled as
+ * InterceptorExceptions and rethrown.
+ *
+ * @author <a href="mailto:directory-dev@incubator.apache.org">Apache Directory Project</a>
+ * @version $Rev$
+ */
+public class EveInterceptorException extends EveNamingException
+{
+    /** The Invokation the Interceptor failed on */
+    private final Invocation invocation;
+    /** The Interceptor causing the failure */
+    private final Interceptor interceptor;
+
+
+    /**
+     * Creates an EveInterceptorException without a message.
+     *
+     * @param interceptor the Interceptor causing the failure
+     * @param invocation the Invocation the Interceptor failed on
+     */
+    public EveInterceptorException( Interceptor interceptor, Invocation invocation )
+    {
+        super( ResultCodeEnum.OTHER );
+        this.invocation = invocation;
+        this.interceptor = interceptor;
+    }
+
+
+    /**
+     * Creates an EveInterceptorException with a custom message.
+     *
+     * @param interceptor the Interceptor causing the failure
+     * @param invocation the Invocation the Interceptor failed on
+     * @param explanation String explanation of why the Interceptor failed
+     */
+    public EveInterceptorException( Interceptor interceptor,
+                                    Invocation invocation, String explanation )
+    {
+        super( explanation, ResultCodeEnum.OTHER );
+        this.invocation = invocation;
+        this.interceptor = interceptor;
+    }
+
+
+    /**
+     * Creates an EveInterceptorException without a message.
+     *
+     * @param interceptor the Interceptor causing the failure
+     * @param invocation the Invocation the Interceptor failed on
+     * @param rootCause the root cause of this exception
+     */
+    public EveInterceptorException( Interceptor interceptor,
+                                    Invocation invocation, Throwable rootCause )
+    {
+        this( interceptor, invocation );
+        super.setRootCause( rootCause );
+    }
+
+
+    /**
+     * Gets the invovation object this exception is associated with.
+     *
+     * @return the invovation object this exception is associated with
+     */
+    public Invocation getInvocation()
+    {
+        return invocation;
+    }
+
+
+    /**
+     * Gets the interceptor this exception is associated with.
+     *
+     * @return the interceptor this exception is associated with
+     */
+    public Interceptor getInterceptor()
+    {
+        return interceptor;
+    }
+
+
+    /**
+     * Will return the resultCode of the root cause if the root cause
+     * implements EveException.
+     *
+     * @see EveException#getResultCode() 
+     */
+    public ResultCodeEnum getResultCode()
+    {
+        if ( getRootCause() != null && ( getRootCause() instanceof EveException ) )
+        {
+            return ( ( EveException ) getRootCause() ).getResultCode();
+        }
+
+        return super.getResultCode();
+    }
+}

Added: incubator/directory/eve/trunk/backend/core/src/java/org/apache/eve/exception/EveNamingException.java
==============================================================================
--- (empty file)
+++ incubator/directory/eve/trunk/backend/core/src/java/org/apache/eve/exception/EveNamingException.java	Mon Oct 25 16:59:04 2004
@@ -0,0 +1,73 @@
+/*
+ *   Copyright 2004 The Apache Software Foundation
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+package org.apache.eve.exception;
+
+
+import javax.naming.NamingException;
+
+import org.apache.ldap.common.message.ResultCodeEnum;
+
+
+/**
+ * Extends the root NamingException by adding LDAP specific properties to it.
+ *
+ * @author <a href="mailto:directory-dev@incubator.apache.org">Apache Directory Project</a>
+ * @version $Rev$
+ */
+public class EveNamingException extends NamingException implements EveException
+{
+    /** the LDAP resultCode this exception is associated with */
+    private final ResultCodeEnum resultCode;
+
+
+    /**
+     * Creates an Eve NamingException.
+     *
+     * @param resultCode the LDAP resultCode this exception is associated with
+     */
+    public EveNamingException( ResultCodeEnum resultCode )
+    {
+        super();
+
+        this.resultCode = resultCode;
+    }
+
+
+    /**
+     * Creates an Eve NamingException.
+     * 
+     * @param explanation an explanation for the failure
+     * @param resultCode the LDAP resultCode this exception is associated with
+     */
+    public EveNamingException( String explanation, ResultCodeEnum resultCode )
+    {
+        super( explanation );
+
+        this.resultCode = resultCode;
+    }
+
+
+    /**
+     * Gets the LDAP resultCode this exception is associated with.
+     *
+     * @return the LDAP resultCode this exception is associated with
+     */
+    public ResultCodeEnum getResultCode()
+    {
+        return this.resultCode;
+    }
+}

Added: incubator/directory/eve/trunk/backend/core/src/java/org/apache/eve/jndi/AbstractJndiTest.java
==============================================================================
--- (empty file)
+++ incubator/directory/eve/trunk/backend/core/src/java/org/apache/eve/jndi/AbstractJndiTest.java	Mon Oct 25 16:59:04 2004
@@ -0,0 +1,73 @@
+/*
+ *   Copyright 2004 The Apache Software Foundation
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+package org.apache.eve.jndi;
+
+
+import java.util.Hashtable;
+import java.io.File;
+import javax.naming.ldap.LdapContext;
+import javax.naming.Context;
+import javax.naming.InitialContext;
+
+import junit.framework.TestCase;
+import org.apache.commons.io.FileUtils;
+
+
+/**
+ * A simple testcase for testing JNDI provider functionality.
+ *
+ * @author <a href="mailto:directory-dev@incubator.apache.org">Apache Directory Project</a>
+ * @version $Rev$
+ */
+public class AbstractJndiTest extends TestCase
+{
+    /** the context root for the system partition */
+    protected LdapContext sysRoot;
+
+
+    /**
+     * Get's the initial context factory for the provider's ou=system context
+     * root.
+     *
+     * @see junit.framework.TestCase#setUp()
+     */
+    protected void setUp() throws Exception
+    {
+        super.setUp();
+
+        Hashtable env = new Hashtable();
+        env.put( Context.PROVIDER_URL, "ou=system" );
+        env.put( Context.INITIAL_CONTEXT_FACTORY, "org.apache.eve.jndi.EveContextFactory" );
+        env.put( EveContextFactory.WKDIR_ENV, "target/eve" );
+        InitialContext initialContext = new InitialContext( env );
+        sysRoot = ( LdapContext ) initialContext.lookup( "" );
+    }
+
+
+    /**
+     * Sets the system context root to null.
+     *
+     * @see junit.framework.TestCase#tearDown()
+     */
+    protected void tearDown() throws Exception
+    {
+        super.tearDown();
+        sysRoot = null;
+        File file = new File( "target/eve" );
+        FileUtils.deleteDirectory( file );
+    }
+}

Added: incubator/directory/eve/trunk/backend/core/src/java/org/apache/eve/jndi/BaseInterceptor.java
==============================================================================
--- (empty file)
+++ incubator/directory/eve/trunk/backend/core/src/java/org/apache/eve/jndi/BaseInterceptor.java	Mon Oct 25 16:59:04 2004
@@ -0,0 +1,366 @@
+/*
+ *   Copyright 2004 The Apache Software Foundation
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+package org.apache.eve.jndi;
+
+
+import java.util.Map;
+import javax.naming.Name;
+import javax.naming.NamingException;
+import javax.naming.directory.Attributes;
+import javax.naming.directory.ModificationItem;
+import javax.naming.directory.SearchControls;
+
+import org.apache.ldap.common.filter.ExprNode;
+
+
+/**
+ * An interceptor base class which delegates handling of specific Invocations
+ * to member methods within this Interceptor.  These handler methods are
+ * analogous to the methods assocated with the Invocation.  They have the same
+ * name and arguments as do the method associated with the Invocation.  The
+ * analog member methods simply serve as a clean way to handle interception
+ * without having to cast parameter Objects or recode this huge switch statement
+ * for each concrete Interceptor implementation.
+ *
+ * A ThreadLocal is used by all BaseInterceptors to associate the current
+ * Thread of execution with an Invocation object.  This is done to optimize
+ * the use of a single thread local for all instances of the BaseInterceptor
+ * class.  It also removes the need for the invoke() method implementation to
+ * have to set and [un]set the thread local Invocation on each invoke call of
+ * every BaseInterceptor instance.
+ *
+ * The question then arrises, "Why do we need the ThreadLocal?"  Well why pass
+ * around the Invocation object to all analog methods.  Plus we use member
+ * methods rather than static methods to access thread locals and make the
+ * analogs appear cleaner matching their respective invocation methods.
+ *
+ * @author <a href="mailto:directory-dev@incubator.apache.org">Apache Directory Project</a>
+ * @version $Rev$
+ */
+public abstract class BaseInterceptor implements Interceptor
+{
+    /** stores invocation objects by thread so we don't pass em around */
+    private static ThreadLocal invocations = new ThreadLocal();
+
+
+    // ------------------------------------------------------------------------
+    // S T A T I C   M E T H O D S
+    // ------------------------------------------------------------------------
+
+
+    /**
+     * Sets the Invocation object for the current thread of execution.  This is
+     * automatically called twice by the interceptor framework for each new
+     * Invocation.  First right after creation to set the Invocation for the
+     * current thread, and after all Interceptors have been called to unset
+     * the Invocation for the current thread.
+     *
+     * @param invocation the invocation for the current thread of execution
+     */
+    static void setInvocation( Invocation invocation )
+    {
+        invocations.set( invocation );
+    }
+
+
+    // ------------------------------------------------------------------------
+    // Interceptor's Invoke Method
+    // ------------------------------------------------------------------------
+
+
+    /**
+     * Uses a switch on the invocation method type to call the respective member
+     * analog method that does the work of the Interceptor for that Invocation
+     * method.
+     *
+     * @see Interceptor#invoke(Invocation)
+     */
+    public final void invoke( Invocation invocation ) throws NamingException
+    {
+        InvocationMethodEnum enum = invocation.getInvocationMethodEnum();
+
+        switch ( enum.getValue() )
+        {
+            case( InvocationMethodEnum.ADD_VAL ):
+                add( ( String ) invocation.getParameters()[0],
+                     ( Name ) invocation.getParameters()[1],
+                     ( Attributes ) invocation.getParameters()[2] );
+                break;
+            case( InvocationMethodEnum.DELETE_VAL ):
+                delete( ( Name ) invocation.getParameters()[0] );
+                break;
+            case( InvocationMethodEnum.GETMATCHEDDN_VAL ):
+                getMatchchedDn( ( Name ) invocation.getParameters()[0],
+                        ( ( Boolean ) invocation.getParameters()[1] ).booleanValue() );
+                break;
+            case( InvocationMethodEnum.GETSUFFIX_VAL ):
+                getSuffix( ( Name ) invocation.getParameters()[0],
+                        ( ( Boolean ) invocation.getParameters()[1] ).booleanValue() );
+                break;
+            case( InvocationMethodEnum.HASENTRY_VAL ):
+                hasEntry( ( Name ) invocation.getParameters()[0] );
+                break;
+            case( InvocationMethodEnum.ISSUFFIX_VAL ):
+                isSuffix( ( Name ) invocation.getParameters()[0] );
+                break;
+            case( InvocationMethodEnum.LIST_VAL ):
+                list( ( Name ) invocation.getParameters()[0] );
+                break;
+            case( InvocationMethodEnum.LISTSUFFIXES_VAL ):
+                listSuffixes( ( ( Boolean ) invocation.getParameters()[1] )
+                        .booleanValue() );
+                break;
+            case( InvocationMethodEnum.LOOKUP_NAME_VAL ):
+                lookup( ( Name ) invocation.getParameters()[0] );
+                break;
+            case( InvocationMethodEnum.LOOKUP_NAME_STRINGARR_VAL ):
+                lookup( ( Name ) invocation.getParameters()[0],
+                        ( String[] ) invocation.getParameters()[1] );
+                break;
+            case( InvocationMethodEnum.MODIFY_NAME_INT_ATTRIBUTES_VAL ):
+                modify( ( Name ) invocation.getParameters()[0],
+                        ( ( Integer ) invocation.getParameters()[1]).intValue(),
+                        ( Attributes ) invocation.getParameters()[2] );
+                break;
+            case( InvocationMethodEnum.MODIFY_NAME_MODIFICATIONITEMARR_VAL ):
+                modify( ( Name ) invocation.getParameters()[0],
+                        ( ModificationItem[] ) invocation.getParameters()[1] );
+                break;
+            case( InvocationMethodEnum.MODIFYRDN_VAL ):
+                modifyRdn( ( Name ) invocation.getParameters()[0],
+                        ( String ) invocation.getParameters()[1],
+                        ( ( Boolean ) invocation.getParameters()[2] ).booleanValue() );
+                break;
+            case( InvocationMethodEnum.MOVE_NAME_NAME_VAL ):
+                move( ( Name ) invocation.getParameters()[0],
+                        ( Name ) invocation.getParameters()[1] );
+                break;
+            case( InvocationMethodEnum.MOVE_NAME_NAME_STRING_BOOL_VAL ):
+                move( ( Name ) invocation.getParameters()[0],
+                        ( Name ) invocation.getParameters()[1],
+                        ( String ) invocation.getParameters()[2],
+                        ( ( Boolean ) invocation.getParameters()[3] ).booleanValue() );
+                break;
+            case( InvocationMethodEnum.SEARCH_VAL ):
+                search( ( Name ) invocation.getParameters()[0],
+                        ( Map ) invocation.getParameters()[1],
+                        ( ExprNode ) invocation.getParameters()[2],
+                        ( SearchControls ) invocation.getParameters()[3] );
+                break;
+            default:
+                throw new IllegalStateException( "Unexpected invocation type "
+                    + enum );
+        }
+    }
+
+
+    /**
+     * Gets the Invocation associated with the current thread of execution.
+     *
+     * @return the Invocation associated with the current thread of execution
+     */
+    protected Invocation getInvocation()
+    {
+        return ( Invocation ) invocations.get();
+    }
+
+
+    // ------------------------------------------------------------------------
+    // Invocation Analogs
+    // ------------------------------------------------------------------------
+
+
+    /**
+     * Override to inject functionality before, after or on error to
+     * {@link org.apache.eve.BackingStore#add(String, Name, Attributes)}.
+     *
+     * @see org.apache.eve.BackingStore#add(String, Name, Attributes)
+     */
+    protected void add( String upName, Name normName, Attributes entry ) throws NamingException
+    {
+    }
+
+
+    /**
+     * Override to inject functionality before, after or on error to
+     * {@link org.apache.eve.BackingStore#delete(Name)}.
+     *
+     * @see org.apache.eve.BackingStore#delete(Name)}
+     */
+    protected void delete( Name name ) throws NamingException
+    {
+    }
+
+
+    /**
+     * Override to inject functionality before, after or on error to
+     * {@link org.apache.eve.PartitionNexus#getMatchedDn(Name, boolean)}.
+     *
+     * @see org.apache.eve.PartitionNexus#getMatchedDn(Name, boolean)
+     */
+    protected void getMatchchedDn( Name dn, boolean normalized ) throws NamingException
+    {
+    }
+
+
+    /**
+     * Override to inject functionality before, after or on error to
+     * {@link org.apache.eve.ContextPartition#getSuffix(boolean)}.
+     *
+     * @see org.apache.eve.ContextPartition#getSuffix(boolean)
+     */
+    protected void getSuffix( Name dn, boolean normalized ) throws NamingException
+    {
+    }
+
+
+    /**
+     * Override to inject functionality before, after or on error to
+     * {@link org.apache.eve.BackingStore#hasEntry(Name)}.
+     *
+     * @see org.apache.eve.BackingStore#hasEntry(Name)
+     */
+    protected void hasEntry( Name dn ) throws NamingException
+    {
+    }
+
+
+    /**
+     * Override to inject functionality before, after or on error to
+     * {@link org.apache.eve.BackingStore#isSuffix(Name)}.
+     *
+     * @see org.apache.eve.BackingStore#isSuffix(Name)}
+     */
+    protected void isSuffix( Name name ) throws NamingException
+    {
+    }
+
+
+    /**
+     * Override to inject functionality before, after or on error to
+     * {@link org.apache.eve.BackingStore#list(Name)}.
+     *
+     * @see org.apache.eve.BackingStore#list(Name)
+     */
+    protected void list( Name base ) throws NamingException
+    {
+    }
+
+
+    /**
+     * Override to inject functionality before, after or on error to
+     * {@link org.apache.eve.PartitionNexus#listSuffixes(boolean)}.
+     *
+     * @see org.apache.eve.PartitionNexus#listSuffixes(boolean)
+     */
+    protected void listSuffixes( boolean normalized ) throws NamingException
+    {
+    }
+
+
+    /**
+     * Override to inject functionality before, after or on error to
+     * {@link org.apache.eve.BackingStore#lookup(javax.naming.Name)}.
+     *
+     * @see org.apache.eve.BackingStore#lookup(javax.naming.Name)
+     */
+    protected void lookup( Name dn ) throws NamingException
+    {
+    }
+
+
+    /**
+     * Override to inject functionality before, after or on error to
+     * {@link org.apache.eve.PartitionNexus#lookup(javax.naming.Name, String[])}.
+     *
+     * @see org.apache.eve.PartitionNexus#lookup(javax.naming.Name, String[])
+     */
+    protected void lookup( Name dn, String[] attrIds ) throws NamingException
+    {
+    }
+
+
+    /**
+     * Override to inject functionality before, after or on error to
+     * {@link org.apache.eve.BackingStore#modify(Name, int, Attributes)}.
+     *
+     * @see org.apache.eve.BackingStore#modify(Name, int, Attributes)
+     */
+    protected void modify( Name dn, int modOp, Attributes mods ) throws NamingException
+    {
+    }
+
+
+    /**
+     * Override to inject functionality before, after or on error to
+     * {@link org.apache.eve.BackingStore#modify(Name, ModificationItem[])}.
+     *
+     * @see org.apache.eve.BackingStore#modify(Name, ModificationItem[])
+     */
+    protected void modify( Name dn, ModificationItem[] mods ) throws NamingException
+    {
+    }
+
+
+    /**
+     * Override to inject functionality before, after or on error to
+     * {@link org.apache.eve.BackingStore#modifyRn(Name, String, boolean)}.
+     *
+     * @see org.apache.eve.BackingStore#modifyRn(Name, String, boolean)
+     */
+    protected void modifyRdn( Name dn, String newRdn, boolean deleteOldRdn )
+        throws NamingException
+    {
+    }
+
+
+    /**
+     * Override to inject functionality before, after or on error to
+     * {@link org.apache.eve.BackingStore#move(Name, Name)}.
+     *
+     * @see org.apache.eve.BackingStore#move(Name, Name)
+     */
+    protected void move( Name oriChildName, Name newParentName ) throws NamingException
+    {
+    }
+
+
+    /**
+     * Override to inject functionality before, after or on error to
+     * {@link org.apache.eve.BackingStore#move(Name, Name, String, boolean)}.
+     *
+     * @see org.apache.eve.BackingStore#move(Name, Name, String, boolean)
+     */
+    protected void move( Name oriChildName, Name newParentName, String newRdn,
+                         boolean deleteOldRdn ) throws NamingException
+    {
+    }
+
+
+    /**
+     * Override to inject functionality before, after or on error to
+     * {@link org.apache.eve.BackingStore#search(Name, Map, ExprNode, SearchControls)}.
+     *
+     * @see org.apache.eve.BackingStore#search(Name, Map, ExprNode, SearchControls)
+     */
+    protected void search( Name base, Map env, ExprNode filter,
+                           SearchControls searchControls ) throws NamingException
+    {
+    }
+}
+
+

Modified: incubator/directory/eve/trunk/backend/core/src/java/org/apache/eve/jndi/EveContextFactory.java
==============================================================================
--- incubator/directory/eve/trunk/backend/core/src/java/org/apache/eve/jndi/EveContextFactory.java	(original)
+++ incubator/directory/eve/trunk/backend/core/src/java/org/apache/eve/jndi/EveContextFactory.java	Mon Oct 25 16:59:04 2004
@@ -14,6 +14,8 @@
 
 import org.apache.eve.RootNexus;
 import org.apache.eve.SystemPartition;
+import org.apache.eve.exception.EveInterceptorException;
+import org.apache.eve.jndi.ibs.EveExceptionService;
 import org.apache.eve.db.*;
 import org.apache.eve.db.jdbm.JdbmDatabase;
 import org.apache.eve.schema.bootstrap.BootstrapRegistries;
@@ -183,7 +185,14 @@
 
         SystemPartition system = new SystemPartition( db, eng, attributes );
         RootNexus root = new RootNexus( system );
-        this.provider = new EveJndiProvider( root );
+        provider = new EveJndiProvider( root );
+
+        InvocationStateEnum[] state = new InvocationStateEnum[]{
+            InvocationStateEnum.PREINVOCATION,
+            InvocationStateEnum.FAILUREHANDLING
+        };
+        EveExceptionService interceptor = new EveExceptionService( root );
+        provider.addInterceptor( interceptor, state );
     }
 
 

Modified: incubator/directory/eve/trunk/backend/core/src/java/org/apache/eve/jndi/EveJndiProvider.java
==============================================================================
--- incubator/directory/eve/trunk/backend/core/src/java/org/apache/eve/jndi/EveJndiProvider.java	(original)
+++ incubator/directory/eve/trunk/backend/core/src/java/org/apache/eve/jndi/EveJndiProvider.java	Mon Oct 25 16:59:04 2004
@@ -20,6 +20,8 @@
 import org.apache.eve.RootNexus;
 import org.apache.eve.PartitionNexus;
 import org.apache.eve.EveBackendSubsystem;
+import org.apache.eve.exception.EveNamingException;
+import org.apache.ldap.common.message.ResultCodeEnum;
 
 import java.util.Hashtable;
 
@@ -32,7 +34,7 @@
 
 
 /**
- * EveBackendSubsystem service implementing block.
+ * The EveBackendSubsystem service implementation.
  * 
  * @author <a href="mailto:directory-dev@incubator.apache.org">Apache Directory Project</a>
  * @version $Rev$
@@ -47,7 +49,7 @@
     /** Interceptor of interceptors in pre-invocation pipeline */
     private InterceptorPipeline before = new FailFastPipeline();
     /** Interceptor of interceptors in post-invocation pipeline failure */
-    private InterceptorPipeline afterFailure  = new AfterFailurePipeline();
+    private InterceptorPipeline afterFailure = new OnErrorPipeline();
     /** RootNexus as it was given to us by the ServiceManager */
     private RootNexus nexus = null;
     /** PartitionNexus proxy wrapping nexus to inject services */
@@ -122,15 +124,17 @@
     /**
      * @see java.lang.reflect.InvocationHandler#invoke(Object,Method,Object[])
      */
-    public Object invoke( Object proxy, Method method, Object[] args )
-        throws Throwable
+    public Object invoke( Object proxy, Method method, Object[] args ) throws Throwable
     {
         // Setup the invocation and populate: remember aspect sets context stack
         Invocation invocation = new Invocation();
         invocation.setMethod( method );
         invocation.setProxy( proxy );
         invocation.setParameters( args );
-        
+
+        // used for an optimization
+        BaseInterceptor.setInvocation( invocation );
+
         try
         {
             before.invoke( invocation );
@@ -141,19 +145,11 @@
              * On errors we need to continue into the failure handling state
              * of Invocation processing and not throw anything just record it.
              */
-            if ( throwable instanceof InterceptorException )
+            if ( invocation.getBeforeFailure() == null )
             {
-                invocation.setBeforeFailure( ( InterceptorException )
-                    throwable );
+                invocation.setBeforeFailure( throwable );
             }
-            else 
-            {
-                InterceptorException ie =
-                    new InterceptorException( before, invocation );
-                invocation.setBeforeFailure( ie );
-                ie.setRootCause( throwable );
-            }
-            
+
             invocation.setState( InvocationStateEnum.FAILUREHANDLING );
         }
 
@@ -166,12 +162,12 @@
          * If before pipeline failed then we invoke the after failure pipeline
          * and throw the before failure exception.
          */
-        if ( InvocationStateEnum.PREINVOCATION == invocation.getState() )
+        if ( invocation.getState() == InvocationStateEnum.PREINVOCATION )
         {
             try
             {
-                invocation.setReturnValue( method.invoke( nexus,
-                    invocation.getParameters() ) );
+                Object retVal = method.invoke( nexus, invocation.getParameters() );
+                invocation.setReturnValue( retVal );
                 invocation.setState( InvocationStateEnum.POSTINVOCATION );
             }
             catch ( Throwable throwable )
@@ -182,10 +178,10 @@
 
             invocation.setComplete( true );
         }
-        else if ( 
-            InvocationStateEnum.FAILUREHANDLING == invocation.getState() )
+        else if ( invocation.getState() == InvocationStateEnum.FAILUREHANDLING )
         {
             afterFailure.invoke( invocation );
+            BaseInterceptor.setInvocation( null );
             throw invocation.getBeforeFailure();
         }
 
@@ -199,55 +195,78 @@
          * pipeline since we will be in the FAILUREHANDLINE state and after 
          * doing so we throw the original throwable raised by the target.
          */
-        if ( InvocationStateEnum.POSTINVOCATION == invocation.getState() )
+        if ( invocation.getState() == InvocationStateEnum.POSTINVOCATION )
         {
             try
             {
                 after.invoke( invocation );
+                BaseInterceptor.setInvocation( null );
                 return invocation.getReturnValue();
             }
             catch ( Throwable throwable )
             {
                 invocation.setState( InvocationStateEnum.FAILUREHANDLING );
                 
-                if ( throwable instanceof InterceptorException )
+                if ( invocation.getAfterFailure() == null )
                 {
-                    invocation.setAfterFailure( ( InterceptorException )
-                        throwable );
+                    invocation.setAfterFailure( throwable );
                 }
-                else 
-                {
-                    InterceptorException ie =
-                        new InterceptorException( after, invocation );
-                    ie.setRootCause( throwable );
-                    invocation.setAfterFailure( ie );
-                }
-                
+
                 afterFailure.invoke( invocation );
+                BaseInterceptor.setInvocation( null );
                 throw invocation.getAfterFailure();
             }
         }
-        else if ( 
-            InvocationStateEnum.FAILUREHANDLING == invocation.getState()
-            )
+        else if ( invocation.getState() == InvocationStateEnum.FAILUREHANDLING )
         {
             afterFailure.invoke( invocation );
-            
-            if ( null != invocation.getThrowable() )
-            {
-                throw invocation.getThrowable();
-            }
-            else if ( null != invocation.getBeforeFailure() )
+
+            if ( invocation.getThrowable() == null )
             {
-                throw invocation.getBeforeFailure();
+                throw new EveNamingException( "Interceptor Framework Failure: "
+                        + "failures on the proxied call should have a non null "
+                        + "throwable associated with the Invocation object.",
+                        ResultCodeEnum.OTHER );
             }
-            else if ( null != invocation.getAfterFailure() )
+
+            BaseInterceptor.setInvocation( null );
+            throw invocation.getThrowable();
+        }
+
+        // used for an optimization
+        BaseInterceptor.setInvocation( null );
+        throw new EveNamingException( "Interceptor Framework Failure: "
+                + "invocation handling should never have reached this line",
+                ResultCodeEnum.OTHER );
+    }
+
+
+    /**
+     * Allows the addition of an interceptor to pipelines based on invocation
+     * processing states.
+     *
+     * @param interceptor the interceptor to add to pipelines
+     * @param states the states (pipelines) where the interceptor should be applied
+     */
+    public void addInterceptor( Interceptor interceptor, InvocationStateEnum states[] )
+    {
+        for ( int ii = 0; ii < states.length; ii++ )
+        {
+            switch( states[ii].getValue() )
             {
-                throw invocation.getAfterFailure();
+                case( InvocationStateEnum.PREINVOCATION_VAL ):
+                    before.add( interceptor );
+                    break;
+                case( InvocationStateEnum.POSTINVOCATION_VAL ):
+                    after.add( interceptor );
+                    break;
+                case( InvocationStateEnum.FAILUREHANDLING_VAL ):
+                    afterFailure.add( interceptor );
+                    break;
+                default:
+                    throw new IllegalStateException( "unexpected invocation state: "
+                            + states[ii].getName() );
             }
         }
-        
-        throw new IllegalStateException( "The EveJndiProvider's invocation "
-            + "handler method invoke should never have reached this line" );
     }
 }

Modified: incubator/directory/eve/trunk/backend/core/src/java/org/apache/eve/jndi/FailFastPipeline.java
==============================================================================
--- incubator/directory/eve/trunk/backend/core/src/java/org/apache/eve/jndi/FailFastPipeline.java	(original)
+++ incubator/directory/eve/trunk/backend/core/src/java/org/apache/eve/jndi/FailFastPipeline.java	Mon Oct 25 16:59:04 2004
@@ -17,6 +17,11 @@
 package org.apache.eve.jndi;
 
 
+import javax.naming.NamingException;
+
+import org.apache.eve.exception.EveInterceptorException;
+
+
 /**
  * A fast failing InterceptorPipeline implementation where the first Interceptor
  * to fail within the invocation chain of the pipeline shorts the invocation of
@@ -40,13 +45,13 @@
 
     /**
      * This invoke method fails and throws at the first failure within the 
-     * pipeline.  If an unexpected Throwable other than an InterceptorException
+     * pipeline.  If an unexpected Throwable other than an EveInterceptorException
      * results this method catches it and wraps it within an 
-     * InterceptorException and rethrows the new exception.
+     * EveInterceptorException and rethrows the new exception.
      *
      * @see Interceptor#invoke(Invocation)
      */
-    public void invoke( Invocation invocation ) throws InterceptorException
+    public void invoke( Invocation invocation ) throws NamingException
     {
         for ( int ii = 0; ii < getList().size(); ii++ )
         {
@@ -58,12 +63,13 @@
             }
             catch ( Throwable throwable )
             {
-                if ( throwable instanceof InterceptorException )
+                if ( throwable instanceof EveInterceptorException )
                 {
-                    throw ( InterceptorException ) throwable;
+                    throw ( EveInterceptorException ) throwable;
                 }
                 
-                InterceptorException ie = new InterceptorException( service, invocation );
+                EveInterceptorException ie;
+                ie = new EveInterceptorException( service, invocation );
                 ie.setRootCause( throwable );
                 throw ie;
             }

Modified: incubator/directory/eve/trunk/backend/core/src/java/org/apache/eve/jndi/Interceptor.java
==============================================================================
--- incubator/directory/eve/trunk/backend/core/src/java/org/apache/eve/jndi/Interceptor.java	(original)
+++ incubator/directory/eve/trunk/backend/core/src/java/org/apache/eve/jndi/Interceptor.java	Mon Oct 25 16:59:04 2004
@@ -17,6 +17,11 @@
 package org.apache.eve.jndi;
 
 
+import javax.naming.NamingException;
+
+import org.apache.eve.exception.EveInterceptorException;
+
+
 /**
  * The Interceptor is a component through which invocations pass thru.  In 
  * most cases the invocations pass thru a series of Interceptor objects 
@@ -31,16 +36,16 @@
 public interface Interceptor
 {
     /**
-     * Process a particular invocation.
-     * The method must NEVER throw an exception and any exceptions should be 
-     * caught and placed into the invocation via {@link Invocation#setThrowable}
-     * or {@link Invocation#addFailure(InterceptorException)}.
+     * Process a particular invocation.  The method must try to catch and
+     * rethrow exceptions as EveInterceptorExceptions and any other exceptions
+     * will be caught and placed into the invocation via
+     * {@link Invocation#setThrowable} or {@link Invocation#addFailure(Throwable)}.
      *
      * <p>Note: most Interceptors pass control to the next Interceptor in the
      * series.</p>
      *
      * @param invocation the invocation to process
-     * @throws InterceptorException on failures while handling the invokation
+     * @throws NamingException on failures while handling the invokation
      */
-    void invoke( Invocation invocation ) throws InterceptorException;
+    void invoke( Invocation invocation ) throws NamingException;
 }

Modified: incubator/directory/eve/trunk/backend/core/src/java/org/apache/eve/jndi/InterceptorPipeline.java
==============================================================================
--- incubator/directory/eve/trunk/backend/core/src/java/org/apache/eve/jndi/InterceptorPipeline.java	(original)
+++ incubator/directory/eve/trunk/backend/core/src/java/org/apache/eve/jndi/InterceptorPipeline.java	Mon Oct 25 16:59:04 2004
@@ -20,6 +20,8 @@
 import java.util.List;
 import java.util.ArrayList;
 
+import javax.naming.NamingException;
+
 
 /**
  * An Interceptor composed of a pipeline of interceptors that can be called 
@@ -44,8 +46,19 @@
     {
         list.add( posn, service );
     }
-    
-    
+
+
+    /**
+     * Adds a Interceptor to the end of this InterceptorPipeline.
+     *
+     * @param service the Interceptor to add.
+     */
+    public void add( Interceptor service )
+    {
+        list.add( service );
+    }
+
+
     /**
      * Removes an Interceptor from this InterceptorPipeline.
      *
@@ -92,7 +105,7 @@
      *
      * @see Interceptor#invoke(Invocation)
      */
-    public abstract void invoke( Invocation invocation ) throws InterceptorException;
+    public abstract void invoke( Invocation invocation ) throws NamingException;
 
     /**
      * Get whether this pipeline is fail fast or not.

Modified: incubator/directory/eve/trunk/backend/core/src/java/org/apache/eve/jndi/Invocation.java
==============================================================================
--- incubator/directory/eve/trunk/backend/core/src/java/org/apache/eve/jndi/Invocation.java	(original)
+++ incubator/directory/eve/trunk/backend/core/src/java/org/apache/eve/jndi/Invocation.java	Mon Oct 25 16:59:04 2004
@@ -43,23 +43,28 @@
      * The interceptor processing state of this Invocation.
      */
     private InvocationStateEnum state = InvocationStateEnum.PREINVOCATION;
-    
+
+    /**
+     * The interceptor processing state of this Invocation.
+     */
+    private InvocationMethodEnum methodEnum;
+
     /**
      * The invokation state: when call has completed isCompleted will be true
      */
     private boolean isComplete = false;
     
     /**
-     * InterceptorException thrown by the first interceptor to fail within the 
-     * after invocation InterceptorPipeline which is fail fast.
+     * Thrown by the first interceptor to fail within the before invocation
+     * InterceptorPipeline which is fail fast.
      */
-    private InterceptorException before;
+    private Throwable before;
     
     /**
-     * InterceptorException thrown by the first interceptor to fail within the 
-     * after invocation InterceptorPipeline which is fail fast.
+     * Thrown by the first interceptor to fail within the after invocation
+     * InterceptorPipeline which is fail fast.
      */
-    private InterceptorException after;
+    private Throwable after;
     
     /**
      * Exceptions thrown by interceptors within the failure pipeline which is 
@@ -151,9 +156,9 @@
     
 
     /**
-     * Lists  the InterceptorExceptions thrown by interceptors within the 
-     * failure pipeline which is NOT fail fast - hence the use of a list for 
-     * potentially many exceptions.
+     * Lists the Throwables thrown by interceptors within the failure pipeline
+     * which is NOT fail fast - hence the use of a list for potentially many
+     * exceptions.
      *
      * @return an Iterator over the exceptions produced by Interceptors
      */
@@ -174,7 +179,7 @@
      *
      * @param throwable Throwable resulting from an Interceptor invoke call
      */
-    public void addFailure( InterceptorException throwable )
+    public void addFailure( Throwable throwable )
     {
         if ( null == failures )
         {
@@ -186,52 +191,44 @@
     
     
     /**
-     * Gets the InterceptorException thrown if at all within the before
-     * InterceptorPipeline.
+     * Gets the Throwable thrown if at all within the before InterceptorPipeline.
      *
-     * @return the InterceptorException thrown if at all within the before 
-     * InterceptorPipeline 
+     * @return the Throwable thrown if at all within the before InterceptorPipeline
      */
-    public InterceptorException getBeforeFailure()
+    public Throwable getBeforeFailure()
     {
         return before;
     }
     
     
     /**
-     * Sets the InterceptorException thrown if at all within the before
-     * InterceptorPipeline.
+     * Sets the Throwable thrown if at all within the before InterceptorPipeline.
      *
-     * @param before the InterceptorException thrown if at all within the
-     * before InterceptorPipeline 
+     * @param before the Throwable thrown if at all within the before InterceptorPipeline
      */
-    public void setBeforeFailure( InterceptorException before )
+    public void setBeforeFailure( Throwable before )
     {
         this.before = before;
     }
     
     
     /**
-     * Gets the InterceptorException thrown if at all within the after
-     * InterceptorPipeline.
+     * Gets the Throwable thrown if at all within the after InterceptorPipeline.
      *
-     * @return the InterceptorException thrown if at all within the after 
-     * InterceptorPipeline 
+     * @return the Throwable thrown if at all within the after InterceptorPipeline
      */
-    public InterceptorException getAfterFailure()
+    public Throwable getAfterFailure()
     {
         return after;
     }
     
     
     /**
-     * Sets the InterceptorException thrown if at all within the after
-     * InterceptorPipeline.
+     * Sets the Throwable thrown if at all within the after InterceptorPipeline.
      *
-     * @param after the InterceptorException thrown if at all within the
-     * after InterceptorPipeline 
+     * @param after the Throwable thrown if at all within the after InterceptorPipeline
      */
-    public void setAfterFailure( InterceptorException after )
+    public void setAfterFailure( Throwable after )
     {
         this.after = after;
     }
@@ -264,6 +261,17 @@
      *
      * @return the method that was invoked.
      */
+    public InvocationMethodEnum getInvocationMethodEnum()
+    {
+        return methodEnum;
+    }
+
+
+    /**
+     * Return the method that was invoked.
+     *
+     * @return the method that was invoked.
+     */
     public Method getMethod()
     {
         return method;
@@ -278,6 +286,7 @@
     public void setMethod( final Method method )
     {
         this.method = method;
+        this.methodEnum = InvocationMethodEnum.getInvocationMethodEnum( method );
     }
 
 

Added: incubator/directory/eve/trunk/backend/core/src/java/org/apache/eve/jndi/InvocationMethodEnum.java
==============================================================================
--- (empty file)
+++ incubator/directory/eve/trunk/backend/core/src/java/org/apache/eve/jndi/InvocationMethodEnum.java	Mon Oct 25 16:59:04 2004
@@ -0,0 +1,324 @@
+/*
+ *   Copyright 2004 The Apache Software Foundation
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+package org.apache.eve.jndi;
+
+
+import java.util.Map;
+import java.util.HashMap;
+import java.util.Collections;
+import java.lang.reflect.Method;
+
+import org.apache.ldap.common.util.ValuedEnum;
+
+
+/**
+ * A valued enumeration used by interceptor services for fast switching on
+ * invocation method names.
+ *
+ * @author <a href="mailto:directory-dev@incubator.apache.org">Apache Directory Project</a>
+ * @version $Rev$
+ */
+public class InvocationMethodEnum extends ValuedEnum
+{
+    /** name/signature for the getMatchedDn() method */
+    public static final String GETMATCHEDDN_STR = "getMatchedDn()";
+    /** name/signature for the getSuffix() method */
+    public static final String GETSUFFIX_STR = "getSuffix()";
+    /** name/signature for the listSuffixes() method */
+    public static final String LISTSUFFIXES_STR = "listSuffixes()";
+    /** name/signature for the lookup(Name, String[]) method */
+    public static final String LOOKUP_NAME_STRINGARR_STR =
+            "lookup(Name, String[])";
+    /** name/signature for the add() method */
+    public static final String ADD_STR = "add()";
+    /** name/signature for the delete() method */
+    public static final String DELETE_STR = "delete()";
+    /** name/signature for the hasEntry() method */
+    public static final String HASENTRY_STR = "hasEntry()";
+    /** name/signature for the isSuffix() method */
+    public static final String ISSUFFIX_STR = "isSuffix()";
+    /** name/signature for the list() method */
+    public static final String LIST_STR = "list()";
+    /** name/signature for the lookup(Name) method */
+    public static final String LOOKUP_NAME_STR = "lookup(Name)";
+    /** name/signature for the modify(Name, int, Attributes) method */
+    public static final String MODIFY_NAME_INT_ATTRIBUTES_STR =
+            "modify(Name, int, Attributes)";
+    /** name/signature for the modify(Name, ModificationItem[]) method */
+    public static final String MODIFY_NAME_MODIFICATIONITEMARR_STR =
+            "modify(Name, ModificationItem[])";
+    /** name/signature for the modifyRdn() method */
+    public static final String MODIFYRDN_STR = "modifyRdn()";
+    /** name/signature for the move(Name, Name) method */
+    public static final String MOVE_NAME_NAME_STR = "move(Name, Name)";
+    /** name/signature for the move(Name, Name, String, boolean) method */
+    public static final String MOVE_NAME_NAME_STRING_BOOL_STR =
+            "move(Name, Name, String, boolean)";
+    /** name/signature for the search() method */
+    public static final String SEARCH_STR = "search()";
+
+    /** the names in an array where the int value indexes the associated name */
+    public static final String[] NAMES = {
+        GETMATCHEDDN_STR, GETSUFFIX_STR, LISTSUFFIXES_STR,
+        LOOKUP_NAME_STRINGARR_STR,
+        ADD_STR, DELETE_STR, HASENTRY_STR, ISSUFFIX_STR, LIST_STR,
+        LOOKUP_NAME_STR, MODIFY_NAME_INT_ATTRIBUTES_STR,
+        MODIFY_NAME_MODIFICATIONITEMARR_STR, MODIFYRDN_STR,
+        MOVE_NAME_NAME_STR, MOVE_NAME_NAME_STRING_BOOL_STR, SEARCH_STR
+    };
+
+    /** the int value for the getMatchedDn() method */
+    public static final int GETMATCHEDDN_VAL = 0;
+    /** the int value for the getSuffix() method */
+    public static final int GETSUFFIX_VAL = 1;
+    /** the int value for the listSuffixes() method */
+    public static final int LISTSUFFIXES_VAL = 2;
+    /** the int value for the lookup(Name, String[]) method */
+    public static final int LOOKUP_NAME_STRINGARR_VAL = 3;
+    /** the int value for the add() method */
+    public static final int ADD_VAL = 4;
+    /** the int value for the delete() method */
+    public static final int DELETE_VAL = 5;
+    /** the int value for the hasEntry() method */
+    public static final int HASENTRY_VAL = 6;
+    /** the int value for the isSuffix() method */
+    public static final int ISSUFFIX_VAL = 7;
+    /** the int value for the list() method */
+    public static final int LIST_VAL = 8;
+    /** the int value for the lookup() method */
+    public static final int LOOKUP_NAME_VAL = 9;
+    /** the int value for the modify(Name, int, Attributes) method */
+    public static final int MODIFY_NAME_INT_ATTRIBUTES_VAL = 10;
+    /** the int value for the modify(Name, ModificationItem[]) method */
+    public static final int MODIFY_NAME_MODIFICATIONITEMARR_VAL = 11;
+    /** the int value for the modifyRdn() method */
+    public static final int MODIFYRDN_VAL = 12;
+    /** the int value for the move(Name, Name) method */
+    public static final int MOVE_NAME_NAME_VAL = 13;
+    /** the int value for the move(Name, Name, String, boolean) method */
+    public static final int MOVE_NAME_NAME_STRING_BOOL_VAL = 14;
+    /** the int value for the search() method */
+    public static final int SEARCH_VAL = 15;
+
+    /** the type safe enumeration for the getMatchedDn() method */
+    public static final InvocationMethodEnum GETMATCHEDDN =
+		new InvocationMethodEnum( NAMES[0], 0 );
+    /** the type safe enumeration for the getSuffix() method */
+    public static final InvocationMethodEnum GETSUFFIX =
+		new InvocationMethodEnum( NAMES[1], 1 );
+    /** the type safe enumeration for the listSuffixes() method */
+    public static final InvocationMethodEnum LISTSUFFIXES =
+		new InvocationMethodEnum( NAMES[2], 2 );
+    /** the type safe enumeration for the lookup(Name, String[]) method */
+    public static final InvocationMethodEnum LOOKUP_NAME_STRINGARR =
+		new InvocationMethodEnum( NAMES[3], 3 );
+    /** the type safe enumeration for the add() method */
+    public static final InvocationMethodEnum ADD =
+		new InvocationMethodEnum( NAMES[4], 4 );
+    /** the type safe enumeration for the delete() method */
+    public static final InvocationMethodEnum DELETE =
+		new InvocationMethodEnum( NAMES[5], 5 );
+    /** the type safe enumeration for the hasEntry() method */
+    public static final InvocationMethodEnum HASENTRY =
+		new InvocationMethodEnum( NAMES[6], 6 );
+    /** the type safe enumeration for the isSuffix() method */
+    public static final InvocationMethodEnum ISSUFFIX =
+		new InvocationMethodEnum( NAMES[7], 7 );
+    /** the type safe enumeration for the list() method */
+    public static final InvocationMethodEnum LIST =
+		new InvocationMethodEnum( NAMES[8], 8 );
+    /** the type safe enumeration for the lookup(Name) method */
+    public static final InvocationMethodEnum LOOKUP_NAME =
+		new InvocationMethodEnum( NAMES[9], 9 );
+    /** the type safe enumeration for the modify(Name, int, Attributes) method */
+    public static final InvocationMethodEnum MODIFY_NAME_INT_ATTRIBUTES =
+		new InvocationMethodEnum( NAMES[10], 10 );
+    /** the type safe enumeration for the modify(Name, ModificationItem[]) method */
+    public static final InvocationMethodEnum MODIFY_NAME_MODIFICATIONITEMARR =
+		new InvocationMethodEnum( NAMES[11], 11 );
+    /** the type safe enumeration for the modifyRdn() method */
+    public static final InvocationMethodEnum MODIFYRDN =
+		new InvocationMethodEnum( NAMES[12], 12 );
+    /** the type safe enumeration for the move(Name, Name) method */
+    public static final InvocationMethodEnum MOVE_NAME_NAME =
+		new InvocationMethodEnum( NAMES[13], 13 );
+    /** the type safe enumeration for the move(Name,Name,String,boolean) method */
+    public static final InvocationMethodEnum MOVE_NAME_NAME_STRING_BOOL =
+		new InvocationMethodEnum( NAMES[14], 14 );
+    /** the type safe enumeration for the search() method */
+    public static final InvocationMethodEnum SEARCH =
+		new InvocationMethodEnum( NAMES[15], 15 );
+
+    /** the type enums in an array where the int value indexes the enum */
+    public static final InvocationMethodEnum[] ENUMS = {
+        GETMATCHEDDN, GETSUFFIX, LISTSUFFIXES, LOOKUP_NAME_STRINGARR,
+        ADD, DELETE, HASENTRY, ISSUFFIX, LIST,LOOKUP_NAME,
+        MODIFY_NAME_INT_ATTRIBUTES, MODIFY_NAME_MODIFICATIONITEMARR, MODIFYRDN,
+        MOVE_NAME_NAME, MOVE_NAME_NAME_STRING_BOOL, SEARCH
+    };
+
+    /** a hash that uses the method name to lookup the enumeration type */
+    public static final Map MAP;
+
+
+    static
+    {
+        HashMap map = new HashMap();
+
+        map.put( "add", new InvocationMethodEnum[]{ ADD } );
+        map.put( "list", new InvocationMethodEnum[]{ LIST } );
+        map.put( "delete", new InvocationMethodEnum[]{ DELETE } );
+        map.put( "search", new InvocationMethodEnum[]{ SEARCH } );
+        map.put( "hasEntry", new InvocationMethodEnum[]{ HASENTRY } );
+        map.put( "isSuffix", new InvocationMethodEnum[]{ ISSUFFIX } );
+        map.put( "listSuffixes", new InvocationMethodEnum[]{ LISTSUFFIXES } );
+        map.put( "modifyRdn", new InvocationMethodEnum[]{ MODIFYRDN } );
+        map.put( "getSuffix", new InvocationMethodEnum[]{ GETSUFFIX } );
+        map.put( "getMatchedDn", new InvocationMethodEnum[]{ GETMATCHEDDN } );
+
+        map.put( "lookup", new InvocationMethodEnum[]{
+            LOOKUP_NAME, LOOKUP_NAME_STRINGARR } );
+        map.put( "modify", new InvocationMethodEnum[]{
+            MODIFY_NAME_INT_ATTRIBUTES, MODIFY_NAME_MODIFICATIONITEMARR
+        } );
+        map.put( "move", new InvocationMethodEnum[]{
+            MOVE_NAME_NAME, MOVE_NAME_NAME_STRING_BOOL
+        } );
+
+        MAP = Collections.unmodifiableMap( map );
+    }
+
+
+    /**
+     * Creates a type safe enumeration for a invocation method.
+     *
+     * @param name the name/signature of the invokation method
+     * @param value the int value for the method
+     */
+    private InvocationMethodEnum( String name, int value )
+    {
+        super( name, value );
+    }
+
+
+    /**
+     * Quickly gets the invocation method enumeration for a Method.
+     *
+     * @param method the method to get an InvocationMethodEnum for
+     * @return the InvocationMethodEnum for the Method
+     * @throws IllegalStateException if the method is not recognized to signify
+     * that some invocation method has not been accounted for
+     */
+    public static InvocationMethodEnum getInvocationMethodEnum( Method method )
+    {
+        InvocationMethodEnum[] enums;
+        String methodName = method.getName();
+
+        if ( ! MAP.containsKey( methodName ) )
+        {
+            throw new IllegalStateException( "Looks like there's a new method "
+                    + "point cut '" + methodName
+                    + "()' that has not yet been properly setup." );
+        }
+
+        enums = ( InvocationMethodEnum[] ) MAP.get( methodName );
+
+        if ( enums.length == 1 )
+        {
+            return enums[0];
+        }
+
+        if ( methodName.equals( "move" ) )
+        {
+            switch( method.getParameterTypes().length )
+            {
+                case(2):
+                    return MOVE_NAME_NAME;
+                case(4):
+                    return MOVE_NAME_NAME_STRING_BOOL;
+                default:
+                    throw new IllegalStateException( "Looks like there's a new "
+                            + "move overloaded method point cut '"
+                            + getSignature( method )
+                            + "()' that has not yet been properly setup." );
+            }
+        }
+        else if ( methodName.equals( "modify" ) )
+        {
+            switch( method.getParameterTypes().length )
+            {
+                case(2):
+                    return MODIFY_NAME_MODIFICATIONITEMARR;
+                case(3):
+                    return MODIFY_NAME_INT_ATTRIBUTES;
+                default:
+                    throw new IllegalStateException( "Looks like there's a new "
+                            + "modify overloaded method point cut '"
+                            + getSignature( method )
+                            + "()' that has not yet been properly setup." );
+            }
+        }
+        else if ( methodName.equals( "lookup" ) )
+        {
+            switch( method.getParameterTypes().length )
+            {
+                case(1):
+                    return LOOKUP_NAME;
+                case(2):
+                    return LOOKUP_NAME_STRINGARR;
+                default:
+                    throw new IllegalStateException( "Looks like there's a new "
+                            + "lookup overloaded method point cut '"
+                            + getSignature( method )
+                            + "()' that has not yet been properly setup." );
+            }
+        }
+
+
+        throw new IllegalStateException( "Looks like there's a new method "
+                + "point cut '" + getSignature( method )
+                + "()' that has not yet been properly setup." );
+    }
+
+
+    /**
+     * Gets the method signature with all parameter type class in the signature.
+     *
+     * @param method the method to generate a signature string for
+     * @return the signature String for the Method
+     */
+    private static String getSignature( Method method )
+    {
+        StringBuffer buf = new StringBuffer();
+        buf.append( method.getName() );
+        buf.append( '(' );
+
+        Class[] params = method.getParameterTypes();
+        for ( int ii = 0; ii < params.length; ii++ )
+        {
+            buf.append( params[ii].getName() );
+
+            if ( ii < params.length - 1 )
+            {
+                buf.append( ',' );
+            }
+        }
+
+        buf.append( ')' );
+        return buf.toString();
+    }
+}

Added: incubator/directory/eve/trunk/backend/core/src/java/org/apache/eve/jndi/OnErrorPipeline.java
==============================================================================
--- (empty file)
+++ incubator/directory/eve/trunk/backend/core/src/java/org/apache/eve/jndi/OnErrorPipeline.java	Mon Oct 25 16:59:04 2004
@@ -0,0 +1,98 @@
+/*
+ *   Copyright 2004 The Apache Software Foundation
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+package org.apache.eve.jndi;
+
+
+import javax.naming.NamingException;
+
+import org.apache.eve.exception.EveInterceptorException;
+
+
+/**
+ * A slow failing InterceptorPipeline implementation where all Interceptors 
+ * within the invocation chain are invoked regardless of errors upstream - 
+ * exceptions are added to the list of exceptions on the Invocation.
+ *
+ * @author <a href="mailto:directory-dev@incubator.apache.org">Apache Directory Project</a>
+ * @version $Rev$
+ */
+public class OnErrorPipeline extends InterceptorPipeline
+{
+    /**
+     * Returns false all the time! 
+     *
+     * @see InterceptorPipeline#isFailFast()
+     */
+    public final boolean isFailFast() 
+    {
+        return false;
+    }
+
+
+    /**
+     * This invoke method does not fail and throw exceptions until all 
+     * Interceptors within the pipeline have been invoked.  If an unexpected 
+     * Throwable other than an EveInterceptorException results this method
+     * catches it and wraps it within an EveInterceptorException and adds it to
+     * the Invocation's list of afterFailure exceptions.  The last error if any
+     * to result after all Interceptors have run is thrown.
+     *
+     * @see Interceptor#invoke(Invocation)
+     */
+    public void invoke( Invocation invocation ) throws NamingException
+    {
+        NamingException last = null;
+        
+        for ( int ii = 0; ii < getList().size(); ii++ )
+        {
+            Interceptor service = ( Interceptor ) getList().get( ii );
+            
+            try
+            {
+                service.invoke( invocation );
+            }
+            catch ( Throwable throwable )
+            {
+                /*
+                 * If exception is EveInterceptorException we add it to the list
+                 * of afterFailure exceptions on the Invocation.  Otherwise we
+                 * wrap the unexpected exception as an EveInterceptorException and
+                 * add it to the list of afterFailure exceptions on the 
+                 * Invocation
+                 */
+
+                if ( throwable instanceof EveInterceptorException )
+                {
+                    last = ( EveInterceptorException ) throwable;
+                    invocation.addFailure( last );
+                }
+                else
+                {
+                    last = new EveInterceptorException( service, invocation );
+                    last.setRootCause( throwable );
+                    invocation.addFailure( last );
+                }
+            }
+        }
+        
+        // Throw the last exception if any after all Interceptors are invoked
+        if ( null != last )
+        {
+            throw last;
+        }
+    }
+}

Added: incubator/directory/eve/trunk/backend/core/src/java/org/apache/eve/jndi/ibs/EveExceptionService.java
==============================================================================
--- (empty file)
+++ incubator/directory/eve/trunk/backend/core/src/java/org/apache/eve/jndi/ibs/EveExceptionService.java	Mon Oct 25 16:59:04 2004
@@ -0,0 +1,88 @@
+/*
+ *   Copyright 2004 The Apache Software Foundation
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+package org.apache.eve.jndi.ibs;
+
+
+import javax.naming.Name;
+import javax.naming.NamingException;
+import javax.naming.directory.Attributes;
+
+import org.apache.eve.jndi.*;
+import org.apache.eve.RootNexus;
+import org.apache.eve.exception.EveAttributeInUseException;
+import org.apache.eve.exception.EveInterceptorException;
+
+
+/**
+ * An interceptor based service used to detect, raise and handle eve exceptions
+ * in one place.  This interceptor has two modes of operation.  The first mode
+ * is as a before chain interceptor where it raises exceptions.  An example
+ * where this interceptor raises an exception is when an entry already exists
+ * at a DN and is added once again to the same DN.  The other mode is as an on
+ * error chain interceptor.  In this mode the service may wrap exceptions and
+ * add extra information to an exception which is to be thrown back at the
+ * caller.
+ *
+ * @author <a href="mailto:directory-dev@incubator.apache.org">Apache Directory Project</a>
+ * @version $Rev$
+ */
+public class EveExceptionService extends BaseInterceptor
+{
+    /** */
+    private RootNexus nexus = null;
+
+
+    /**
+     * Creates an interceptor that is also the exception handling service.
+     *
+     * @param nexus the root partition nexus
+     */
+    public EveExceptionService( RootNexus nexus )
+    {
+        this.nexus = nexus;
+    }
+
+
+    /**
+     * In the pre-invocation state this interceptor method checks to see if
+     * the entry to be added already exists.  If it does an exception is
+     * raised.
+     *
+     * @see BaseInterceptor#add(String, Name, Attributes)
+     */
+    protected void add( String upName, Name normName, Attributes entry ) throws NamingException
+    {
+        Invocation invocation = getInvocation();
+
+        if ( invocation.getState() == InvocationStateEnum.PREINVOCATION )
+        {
+            try
+            {
+                if ( nexus.hasEntry( normName ) )
+                {
+                    NamingException ne = new EveAttributeInUseException();
+                    invocation.setBeforeFailure( new EveAttributeInUseException() );
+                    throw ne;
+                }
+            }
+            catch ( NamingException e )
+            {
+                throw new EveInterceptorException( this, invocation, e );
+            }
+        }
+    }
+}

Copied: incubator/directory/eve/trunk/backend/core/src/java/org/apache/eve/schema/ConcreteNameComponentNormalizer.java (from rev 55390, incubator/directory/eve/trunk/backend/core/src/java/org/apache/eve/schema/bootstrap/RegistryNameComponentNormalizer.java)
==============================================================================
--- incubator/directory/eve/trunk/backend/core/src/java/org/apache/eve/schema/bootstrap/RegistryNameComponentNormalizer.java	(original)
+++ incubator/directory/eve/trunk/backend/core/src/java/org/apache/eve/schema/ConcreteNameComponentNormalizer.java	Mon Oct 25 16:59:04 2004
@@ -14,7 +14,7 @@
  *   limitations under the License.
  *
  */
-package org.apache.eve.schema.bootstrap;
+package org.apache.eve.schema;
 
 
 import javax.naming.NamingException;
@@ -23,8 +23,6 @@
 import org.apache.ldap.common.schema.AttributeType;
 import org.apache.ldap.common.name.NameComponentNormalizer;
 
-import org.apache.eve.schema.AttributeTypeRegistry;
-
 
 /**
  * A DN Name component Normalizer which uses the bootstrap registries to find
@@ -34,10 +32,10 @@
  * @author <a href="mailto:directory-dev@incubator.apache.org">Apache Directory Project</a>
  * @version $Rev$
  */
-public class RegistryNameComponentNormalizer implements NameComponentNormalizer
+public class ConcreteNameComponentNormalizer implements NameComponentNormalizer
 {
-    /** the bootstrap registries used to dynamically resolve Normalizers */
-    private final BootstrapRegistries registries;
+    /** the at registry used to dynamically resolve Normalizers */
+    private final AttributeTypeRegistry registry;
 
 
     /**
@@ -45,11 +43,11 @@
      * registries to find the appropriate normalizer for the attribute of the
      * name component with which to normalize the name component value.
      *
-     * @param registries the bootstrap registries to use for resolution
+     * @param registry the at registry used to dynamically resolve Normalizers
      */
-    public RegistryNameComponentNormalizer( BootstrapRegistries registries )
+    public ConcreteNameComponentNormalizer( AttributeTypeRegistry registry )
     {
-        this.registries = registries;
+        this.registry = registry;
     }
 
 
@@ -84,7 +82,6 @@
      */
     private Normalizer lookup( String id ) throws NamingException
     {
-        AttributeTypeRegistry registry = registries.getAttributeTypeRegistry();
         AttributeType type = registry.lookup( id );
         return type.getEquality().getNormalizer();
     }

Modified: incubator/directory/eve/trunk/backend/core/src/java/org/apache/eve/schema/bootstrap/SystemComparatorProducer.java
==============================================================================
--- incubator/directory/eve/trunk/backend/core/src/java/org/apache/eve/schema/bootstrap/SystemComparatorProducer.java	(original)
+++ incubator/directory/eve/trunk/backend/core/src/java/org/apache/eve/schema/bootstrap/SystemComparatorProducer.java	Mon Oct 25 16:59:04 2004
@@ -21,6 +21,7 @@
 import javax.naming.NamingException;
 
 import org.apache.ldap.common.schema.*;
+import org.apache.eve.schema.ConcreteNameComponentNormalizer;
 
 
 /**
@@ -55,8 +56,8 @@
         ( 2.5.13.1 NAME 'distinguishedNameMatch'
           SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 )
           */
-         comparator = new DnComparator(
-                 new RegistryNameComponentNormalizer( registries ) );
+         comparator = new DnComparator( new ConcreteNameComponentNormalizer(
+                 registries.getAttributeTypeRegistry() ) );
          cb.schemaObjectProduced( this, "2.5.13.1", comparator );
 
          /*

Modified: incubator/directory/eve/trunk/backend/core/src/java/org/apache/eve/schema/bootstrap/SystemNormalizerProducer.java
==============================================================================
--- incubator/directory/eve/trunk/backend/core/src/java/org/apache/eve/schema/bootstrap/SystemNormalizerProducer.java	(original)
+++ incubator/directory/eve/trunk/backend/core/src/java/org/apache/eve/schema/bootstrap/SystemNormalizerProducer.java	Mon Oct 25 16:59:04 2004
@@ -20,6 +20,7 @@
 import javax.naming.NamingException;
 
 import org.apache.ldap.common.schema.*;
+import org.apache.eve.schema.ConcreteNameComponentNormalizer;
 
 
 /**
@@ -50,7 +51,8 @@
           SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 )
          */
         normalizer = new CachingNormalizer( new DnNormalizer(
-                new RegistryNameComponentNormalizer( registries) ) ) ;
+                new ConcreteNameComponentNormalizer(
+                        registries.getAttributeTypeRegistry() ) ) ) ;
         cb.schemaObjectProduced( this, "2.5.13.1", normalizer );
 
         /*

Added: incubator/directory/eve/trunk/backend/core/src/test/org/apache/eve/jndi/CreateContextTest.java
==============================================================================
--- (empty file)
+++ incubator/directory/eve/trunk/backend/core/src/test/org/apache/eve/jndi/CreateContextTest.java	Mon Oct 25 16:59:04 2004
@@ -0,0 +1,164 @@
+/*
+ *   Copyright 2004 The Apache Software Foundation
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+package org.apache.eve.jndi;
+
+
+import javax.naming.NamingException;
+import javax.naming.directory.*;
+
+
+/**
+ * Tests the creation of contexts in various ways.
+ *
+ * @author <a href="mailto:directory-dev@incubator.apache.org">Apache Directory Project</a>
+ * @version $Rev$
+ */
+public class CreateContextTest extends AbstractJndiTest
+{
+    /**
+     * Tests the creation and subsequent read of a new JNDI context under the
+     * system context root.
+     *
+     * @throws javax.naming.NamingException if there are failures
+     */
+    public void testCreateContexts() throws NamingException
+    {
+        /*
+         * create ou=testing00,ou=system
+         */
+        Attributes attributes = new BasicAttributes();
+        Attribute attribute = new BasicAttribute( "objectClass" );
+        attribute.add( "top" );
+        attribute.add( "organizationalUnit" );
+        attributes.put( attribute );
+        attributes.put( "ou", "testing00" );
+        DirContext ctx = sysRoot.createSubcontext( "ou=testing00", attributes );
+        assertNotNull( ctx );
+
+        ctx = ( DirContext ) sysRoot.lookup( "ou=testing00" );
+        assertNotNull( ctx );
+
+        attributes = ctx.getAttributes( "" );
+        assertNotNull( attributes );
+        assertEquals( "testing00", attributes.get( "ou" ).get() );
+        attribute = attributes.get( "objectClass" );
+        assertNotNull( attribute );
+        assertTrue( attribute.contains( "top" ) );
+        assertTrue( attribute.contains( "organizationalUnit" ) );
+
+        /*
+         * create ou=testing01,ou=system
+         */
+        attributes = new BasicAttributes();
+        attribute = new BasicAttribute( "objectClass" );
+        attribute.add( "top" );
+        attribute.add( "organizationalUnit" );
+        attributes.put( attribute );
+        attributes.put( "ou", "testing01" );
+        ctx = sysRoot.createSubcontext( "ou=testing01", attributes );
+        assertNotNull( ctx );
+
+        ctx = ( DirContext ) sysRoot.lookup( "ou=testing01" );
+        assertNotNull( ctx );
+
+        attributes = ctx.getAttributes( "" );
+        assertNotNull( attributes );
+        assertEquals( "testing01", attributes.get( "ou" ).get() );
+        attribute = attributes.get( "objectClass" );
+        assertNotNull( attribute );
+        assertTrue( attribute.contains( "top" ) );
+        assertTrue( attribute.contains( "organizationalUnit" ) );
+
+        /*
+         * create ou=testing02,ou=system
+         */
+        attributes = new BasicAttributes();
+        attribute = new BasicAttribute( "objectClass" );
+        attribute.add( "top" );
+        attribute.add( "organizationalUnit" );
+        attributes.put( attribute );
+        attributes.put( "ou", "testing02" );
+        ctx = sysRoot.createSubcontext( "ou=testing02", attributes );
+        assertNotNull( ctx );
+
+        ctx = ( DirContext ) sysRoot.lookup( "ou=testing02" );
+        assertNotNull( ctx );
+
+        attributes = ctx.getAttributes( "" );
+        assertNotNull( attributes );
+        assertEquals( "testing02", attributes.get( "ou" ).get() );
+        attribute = attributes.get( "objectClass" );
+        assertNotNull( attribute );
+        assertTrue( attribute.contains( "top" ) );
+        assertTrue( attribute.contains( "organizationalUnit" ) );
+
+        /*
+         * create ou=subtest,ou=testing01,ou=system
+         */
+        ctx = ( DirContext ) sysRoot.lookup( "ou=testing01" );
+
+        attributes = new BasicAttributes();
+        attribute = new BasicAttribute( "objectClass" );
+        attribute.add( "top" );
+        attribute.add( "organizationalUnit" );
+        attributes.put( attribute );
+        attributes.put( "ou", "subtest" );
+        ctx = ctx.createSubcontext( "ou=subtest", attributes );
+        assertNotNull( ctx );
+
+        ctx = ( DirContext ) sysRoot.lookup( "ou=subtest,ou=testing01" );
+        assertNotNull( ctx );
+
+        attributes = ctx.getAttributes( "" );
+        assertNotNull( attributes );
+        assertEquals( "subtest", attributes.get( "ou" ).get() );
+        attribute = attributes.get( "objectClass" );
+        assertNotNull( attribute );
+        assertTrue( attribute.contains( "top" ) );
+        assertTrue( attribute.contains( "organizationalUnit" ) );
+    }
+
+
+    public void testFailCreateExisting() throws NamingException
+    {
+        Attribute attribute;
+        Attributes attributes;
+        DirContext ctx = null;
+
+        /*
+         * fail on ou=testing01,ou=system
+         */
+        attributes = new BasicAttributes();
+        attribute = new BasicAttribute( "objectClass" );
+        attribute.add( "top" );
+        attribute.add( "organizationalUnit" );
+        attributes.put( attribute );
+        attributes.put( "ou", "testing01" );
+
+        try
+        {
+            ctx = sysRoot.createSubcontext( "ou=testing01", attributes );
+            fail( "Attept to create exiting context should fail!" );
+        }
+        catch ( NamingException e )
+        {
+            assertNotNull( e );
+        }
+
+        assertNull( ctx );
+    }
+}

Added: incubator/directory/eve/trunk/backend/core/src/test/org/apache/eve/jndi/DestroyContextTest.java
==============================================================================
--- (empty file)
+++ incubator/directory/eve/trunk/backend/core/src/test/org/apache/eve/jndi/DestroyContextTest.java	Mon Oct 25 16:59:04 2004
@@ -0,0 +1,108 @@
+/*
+ *   Copyright 2004 The Apache Software Foundation
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+package org.apache.eve.jndi;
+
+
+import javax.naming.NamingException;
+
+
+/**
+ * Tests the destroyContext methods of the provider.
+ *
+ * @author <a href="mailto:directory-dev@incubator.apache.org">Apache Directory Project</a>
+ * @version $Rev$
+ */
+public class DestroyContextTest extends AbstractJndiTest
+{
+    protected void setUp() throws Exception
+    {
+        super.setUp();
+
+        CreateContextTest createTest = new CreateContextTest();
+        createTest.setUp();
+        createTest.testCreateContexts();
+    }
+
+
+    /**
+     * Tests the creation and subsequent read of a new JNDI context under the
+     * system context root.
+     *
+     * @throws NamingException if there are failures
+     */
+    public void testDestroyContext() throws NamingException
+    {
+        /*
+         * delete ou=testing00,ou=system
+         */
+        sysRoot.destroySubcontext( "ou=testing00");
+
+        try
+        {
+            sysRoot.lookup( "ou=testing00" );
+            fail( "ou=testing00, ou=system should not exist" );
+        }
+        catch( NamingException e )
+        {
+        }
+
+        /*
+         * delete ou=subtest,ou=testing01,ou=system
+         */
+        sysRoot.destroySubcontext( "ou=subtest,ou=testing01");
+
+        try
+        {
+            sysRoot.lookup( "ou=subtest,ou=testing01" );
+            fail( "ou=subtest,ou=testing01,ou=system should not exist" );
+        }
+        catch( NamingException e )
+        {
+        }
+
+        /*
+         * delete ou=testing01,ou=system
+         */
+        sysRoot.destroySubcontext( "ou=testing01");
+
+        try
+        {
+            sysRoot.lookup( "ou=testing01" );
+            fail( "ou=testing01, ou=system should not exist" );
+        }
+        catch( NamingException e )
+        {
+        }
+
+
+        /*
+         * delete ou=testing01,ou=system
+         */
+        sysRoot.destroySubcontext( "ou=testing02");
+
+        try
+        {
+            sysRoot.lookup( "ou=testing02" );
+            fail( "ou=testing02, ou=system should not exist" );
+        }
+        catch( NamingException e )
+        {
+        }
+    }
+
+
+}

Modified: incubator/directory/eve/trunk/backend/core/src/test/org/apache/eve/jndi/EveContextFactoryTest.java
==============================================================================
--- incubator/directory/eve/trunk/backend/core/src/test/org/apache/eve/jndi/EveContextFactoryTest.java	(original)
+++ incubator/directory/eve/trunk/backend/core/src/test/org/apache/eve/jndi/EveContextFactoryTest.java	Mon Oct 25 16:59:04 2004
@@ -17,14 +17,12 @@
 package org.apache.eve.jndi;
 
 
-import java.util.Hashtable;
-import javax.naming.NamingException;
-import javax.naming.InitialContext;
-import javax.naming.Context;
+import java.util.HashMap;
 import javax.naming.directory.*;
-import javax.naming.ldap.LdapContext;
+import javax.naming.NamingException;
+import javax.naming.NamingEnumeration;
 
-import junit.framework.TestCase;
+import org.apache.ldap.common.message.DerefAliasesEnum;
 
 
 /**
@@ -33,30 +31,13 @@
  * @author <a href="mailto:directory-dev@incubator.apache.org">Apache Directory Project</a>
  * @version $Rev$
  */
-public class EveContextFactoryTest extends TestCase
+public class EveContextFactoryTest extends AbstractJndiTest
 {
-    private LdapContext sysRoot;
-
-
-    protected void setUp() throws Exception
-    {
-        super.setUp();
-
-        Hashtable env = new Hashtable();
-        env.put( Context.PROVIDER_URL, "ou=system" );
-        env.put( Context.INITIAL_CONTEXT_FACTORY, "org.apache.eve.jndi.EveContextFactory" );
-        env.put( EveContextFactory.WKDIR_ENV, "target/eve" );
-        InitialContext initialContext = new InitialContext( env );
-        sysRoot = ( LdapContext ) initialContext.lookup( "" );
-    }
-
-
-    protected void tearDown() throws Exception
-    {
-        super.tearDown();
-    }
-
-
+    /**
+     * Makes sure the system context has the right attributes and values.
+     *
+     * @throws NamingException if there are failures
+     */
     public void testSystemContext() throws NamingException
     {
         assertNotNull( sysRoot );
@@ -69,29 +50,4 @@
         assertTrue( attribute.contains( "top" ) );
         assertTrue( attribute.contains( "organizationalUnit" ) );
     }
-
-
-    public void testCreateContext() throws NamingException
-    {
-        Attributes attributes = new BasicAttributes();
-        Attribute attribute = new BasicAttribute( "objectClass" );
-        attribute.add( "top" );
-        attribute.add( "organizationalUnit" );
-        attributes.put( attribute );
-        attributes.put( "ou", "testing" );
-        DirContext ctx = sysRoot.createSubcontext( "ou=testing", attributes );
-        assertNotNull( ctx );
-
-        ctx = ( DirContext ) sysRoot.lookup( "ou=testing" );
-        assertNotNull( ctx );
-
-        attributes = ctx.getAttributes( "" );
-        assertNotNull( attributes );
-        assertEquals( "testing", attributes.get( "ou" ).get() );
-        attribute = attributes.get( "objectClass" );
-        assertNotNull( attribute );
-        assertTrue( attribute.contains( "top" ) );
-        assertTrue( attribute.contains( "organizationalUnit" ) );
-    }
-
 }

Added: incubator/directory/eve/trunk/backend/core/src/test/org/apache/eve/jndi/SearchContextTest.java
==============================================================================
--- (empty file)
+++ incubator/directory/eve/trunk/backend/core/src/test/org/apache/eve/jndi/SearchContextTest.java	Mon Oct 25 16:59:04 2004
@@ -0,0 +1,93 @@
+/*
+ *   Copyright 2004 The Apache Software Foundation
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+package org.apache.eve.jndi;
+
+
+import java.util.HashMap;
+import javax.naming.NamingException;
+import javax.naming.NamingEnumeration;
+import javax.naming.directory.SearchControls;
+import javax.naming.directory.SearchResult;
+
+import org.apache.ldap.common.message.DerefAliasesEnum;
+
+
+/**
+ * Tests the search() methods of the provider.
+ *
+ * @author <a href="mailto:directory-dev@incubator.apache.org">Apache Directory Project</a>
+ * @version $Rev$
+ */
+public class SearchContextTest extends AbstractJndiTest
+{
+    protected void setUp() throws Exception
+    {
+        super.setUp();
+
+        CreateContextTest createContextTest = new CreateContextTest();
+        createContextTest.setUp();
+        createContextTest.testCreateContexts();
+    }
+
+
+    public void testSearchOneLeve() throws NamingException
+    {
+        SearchControls controls = new SearchControls();
+        controls.setSearchScope( SearchControls.ONELEVEL_SCOPE );
+        controls.setDerefLinkFlag( false );
+        sysRoot.addToEnvironment( DerefAliasesEnum.JNDI_PROP,
+                DerefAliasesEnum.NEVERDEREFALIASES.getName() );
+
+        HashMap map = new HashMap();
+        NamingEnumeration list = sysRoot.search( "", "(ou = *)", new SearchControls() );
+        while ( list.hasMore() )
+        {
+            SearchResult result = ( SearchResult ) list.next();
+            map.put( result.getName(), result.getAttributes() );
+        }
+
+        assertEquals( "Expected number of results returned was incorrect!", 3, map.size() );
+        assertTrue( map.containsKey( "ou=testing00,ou=system" ) );
+        assertTrue( map.containsKey( "ou=testing01,ou=system" ) );
+        assertTrue( map.containsKey( "ou=testing02,ou=system" ) );
+    }
+
+
+    public void testSearchSubTreeLeve() throws NamingException
+    {
+        SearchControls controls = new SearchControls();
+        controls.setSearchScope( SearchControls.SUBTREE_SCOPE );
+        controls.setDerefLinkFlag( false );
+        sysRoot.addToEnvironment( DerefAliasesEnum.JNDI_PROP,
+                DerefAliasesEnum.NEVERDEREFALIASES.getName() );
+
+        HashMap map = new HashMap();
+        NamingEnumeration list = sysRoot.search( "", "(ou = *)", new SearchControls() );
+        while ( list.hasMore() )
+        {
+            SearchResult result = ( SearchResult ) list.next();
+            map.put( result.getName(), result.getAttributes() );
+        }
+
+        assertEquals( "Expected number of results returned was incorrect", 5, map.size() );
+        assertTrue( map.containsKey( "ou=system" ) );
+        assertTrue( map.containsKey( "ou=testing00,ou=system" ) );
+        assertTrue( map.containsKey( "ou=testing01,ou=system" ) );
+        assertTrue( map.containsKey( "ou=testing02,ou=system" ) );
+        assertTrue( map.containsKey( "ou=subtest,ou=testing01,ou=system" ) );
+    }
+}

Mime
View raw message