You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@directory.apache.org by ak...@apache.org on 2006/01/07 00:26:30 UTC

svn commit: r366597 - in /directory/trunk: apacheds-server-unit/src/test/java/org/apache/ldap/server/ apacheds/src/main/java/org/apache/ldap/server/enumeration/ ldap-common/src/main/java/org/apache/ldap/common/exception/ ldap-common/src/main/java/org/a...

Author: akarasulu
Date: Fri Jan  6 15:21:28 2006
New Revision: 366597

URL: http://svn.apache.org/viewcvs?rev=366597&view=rev
Log:
implemented abandon handling used only for search requests at this point in time

Added:
    directory/trunk/ldap-common/src/main/java/org/apache/ldap/common/exception/OperationAbandonedException.java   (with props)
    directory/trunk/ldap-common/src/main/java/org/apache/ldap/common/message/AbandonListener.java   (with props)
    directory/trunk/ldap-common/src/main/java/org/apache/ldap/common/message/AbandonableRequest.java   (with props)
    directory/trunk/ldap-common/src/main/java/org/apache/ldap/common/message/AbstractAbandonableRequest.java   (with props)
Modified:
    directory/trunk/apacheds-server-unit/src/test/java/org/apache/ldap/server/PersistentSearchTest.java
    directory/trunk/apacheds/src/main/java/org/apache/ldap/server/enumeration/SearchResultFilteringEnumeration.java
    directory/trunk/ldap-common/src/main/java/org/apache/ldap/common/message/AbandonRequestImpl.java
    directory/trunk/ldap-common/src/main/java/org/apache/ldap/common/message/AbstractMessage.java
    directory/trunk/ldap-common/src/main/java/org/apache/ldap/common/message/AbstractRequest.java
    directory/trunk/ldap-common/src/main/java/org/apache/ldap/common/message/AddRequest.java
    directory/trunk/ldap-common/src/main/java/org/apache/ldap/common/message/AddRequestImpl.java
    directory/trunk/ldap-common/src/main/java/org/apache/ldap/common/message/BindRequestImpl.java
    directory/trunk/ldap-common/src/main/java/org/apache/ldap/common/message/CompareRequest.java
    directory/trunk/ldap-common/src/main/java/org/apache/ldap/common/message/CompareRequestImpl.java
    directory/trunk/ldap-common/src/main/java/org/apache/ldap/common/message/DeleteRequest.java
    directory/trunk/ldap-common/src/main/java/org/apache/ldap/common/message/DeleteRequestImpl.java
    directory/trunk/ldap-common/src/main/java/org/apache/ldap/common/message/ModifyDnRequest.java
    directory/trunk/ldap-common/src/main/java/org/apache/ldap/common/message/ModifyDnRequestImpl.java
    directory/trunk/ldap-common/src/main/java/org/apache/ldap/common/message/ModifyRequest.java
    directory/trunk/ldap-common/src/main/java/org/apache/ldap/common/message/ModifyRequestImpl.java
    directory/trunk/ldap-common/src/main/java/org/apache/ldap/common/message/SearchRequest.java
    directory/trunk/ldap-common/src/main/java/org/apache/ldap/common/message/SearchRequestImpl.java
    directory/trunk/ldap-common/src/main/java/org/apache/ldap/common/message/UnbindRequestImpl.java
    directory/trunk/ldap-common/src/test/java/org/apache/ldap/common/message/AddRequestImplTest.java
    directory/trunk/ldap-common/src/test/java/org/apache/ldap/common/message/BindRequestImplTest.java
    directory/trunk/ldap-common/src/test/java/org/apache/ldap/common/message/CompareRequestImplTest.java
    directory/trunk/ldap-common/src/test/java/org/apache/ldap/common/message/DeleteRequestImplTest.java
    directory/trunk/ldap-common/src/test/java/org/apache/ldap/common/message/ExtendedRequestImplTest.java
    directory/trunk/ldap-common/src/test/java/org/apache/ldap/common/message/ModifyDnRequestImplTest.java
    directory/trunk/ldap-common/src/test/java/org/apache/ldap/common/message/ModifyRequestImplTest.java
    directory/trunk/ldap-protocol/src/main/java/org/apache/ldap/server/protocol/SessionRegistry.java
    directory/trunk/ldap-protocol/src/main/java/org/apache/ldap/server/protocol/support/AbandonHandler.java
    directory/trunk/ldap-protocol/src/main/java/org/apache/ldap/server/protocol/support/PersistentSearchListener.java
    directory/trunk/ldap-protocol/src/main/java/org/apache/ldap/server/protocol/support/SearchHandler.java

Modified: directory/trunk/apacheds-server-unit/src/test/java/org/apache/ldap/server/PersistentSearchTest.java
URL: http://svn.apache.org/viewcvs/directory/trunk/apacheds-server-unit/src/test/java/org/apache/ldap/server/PersistentSearchTest.java?rev=366597&r1=366596&r2=366597&view=diff
==============================================================================
--- directory/trunk/apacheds-server-unit/src/test/java/org/apache/ldap/server/PersistentSearchTest.java (original)
+++ directory/trunk/apacheds-server-unit/src/test/java/org/apache/ldap/server/PersistentSearchTest.java Fri Jan  6 15:21:28 2006
@@ -557,6 +557,81 @@
     }
 
     
+    /**
+     * Shows notifications functioning with the JNDI notification API of the SUN
+     * provider.
+     */
+    public void testPsearchAbandon() throws Exception
+    {
+        PersistentSearchControl control = new PersistentSearchControl();
+        control.setReturnECs( true );
+        PSearchListener listener = new PSearchListener( control );
+        Thread t = new Thread( listener );
+        t.start();
+        
+        while( ! listener.isReady )
+        {
+            Thread.sleep( 100 );
+        }
+        Thread.sleep( 250 );
+
+        ctx.createSubcontext( "cn=Jack Black", getPersonAttributes( "Black", "Jack Black" ) );
+        
+        long start = System.currentTimeMillis();
+        while ( t.isAlive() )
+        {
+            Thread.sleep( 100 );
+            if ( System.currentTimeMillis() - start > 3000 )
+            {
+                System.out.println( "PSearchListener thread not dead yet" );
+                break;
+            }
+        }
+        
+        assertNotNull( listener.result );
+        // darn it getting normalized name back
+        assertEquals( "cn=Jack Black".toLowerCase(), listener.result.getName().toLowerCase() );
+        assertEquals( listener.result.control.getChangeType(), ChangeType.ADD );
+        listener.result = null;
+        t = new Thread( listener );
+        t.start();
+        
+        ctx.destroySubcontext( "cn=Jack Black" );
+        
+        start = System.currentTimeMillis();
+        while ( t.isAlive() )
+        {
+            Thread.sleep( 100 );
+            if ( System.currentTimeMillis() - start > 3000 )
+            {
+                System.out.println( "PSearchListener thread not dead yet" );
+                break;
+            }
+        }
+
+        assertNull( listener.result );
+
+        // thread is still waiting for notifications try a modify
+        ctx.modifyAttributes( RDN, DirContext.REMOVE_ATTRIBUTE, 
+            new BasicAttributes( "description", PERSON_DESCRIPTION, true ) );
+        start = System.currentTimeMillis();
+        while ( t.isAlive() )
+        {
+            Thread.sleep( 200 );
+            if ( System.currentTimeMillis() - start > 3000 )
+            {
+                System.out.println( "PSearchListener thread not dead yet" );
+                break;
+            }
+        }
+        
+        assertNotNull( listener.result );
+        // darn it getting normalized name back
+        assertEquals( RDN.toLowerCase(), listener.result.getName().toLowerCase() );
+        assertEquals( listener.result.control.getChangeType(), ChangeType.MODIFY );
+    }
+
+    
     class JndiNotificationListener implements NamespaceChangeListener, ObjectChangeListener
     {
         ArrayList list = new ArrayList();
@@ -606,6 +681,7 @@
         
         public void run()
         {
+            NamingEnumeration list = null;
             control.setCritical( true );
             Control[] ctxCtls = new Control[] { control };
             
@@ -613,7 +689,7 @@
             {
                 ctx.setRequestControls( ctxCtls );
                 isReady = true;
-                NamingEnumeration list = ctx.search( "", "objectClass=*", null );
+                list = ctx.search( "", "objectClass=*", null );
                 EntryChangeControl ecControl = null;
                 
                 while( list.hasMore() )
@@ -645,6 +721,13 @@
             catch( Exception e ) 
             {
                 e.printStackTrace();
+            }
+            finally
+            {
+                if ( list != null )
+                {
+                    try { list.close(); } catch ( Exception e ) { e.printStackTrace(); };
+                }
             }
         }
     }

Modified: directory/trunk/apacheds/src/main/java/org/apache/ldap/server/enumeration/SearchResultFilteringEnumeration.java
URL: http://svn.apache.org/viewcvs/directory/trunk/apacheds/src/main/java/org/apache/ldap/server/enumeration/SearchResultFilteringEnumeration.java?rev=366597&r1=366596&r2=366597&view=diff
==============================================================================
--- directory/trunk/apacheds/src/main/java/org/apache/ldap/server/enumeration/SearchResultFilteringEnumeration.java (original)
+++ directory/trunk/apacheds/src/main/java/org/apache/ldap/server/enumeration/SearchResultFilteringEnumeration.java Fri Jan  6 15:21:28 2006
@@ -35,6 +35,9 @@
 //import org.slf4j.Logger;
 //import org.slf4j.LoggerFactory;
 import org.apache.ldap.server.invocation.Invocation;
+import org.apache.ldap.common.exception.OperationAbandonedException;
+import org.apache.ldap.common.message.AbandonListener;
+import org.apache.ldap.common.message.AbandonableRequest;
 import org.apache.ldap.common.name.LdapName;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -48,7 +51,7 @@
  * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
  * @version $Rev$
  */
-public class SearchResultFilteringEnumeration implements NamingEnumeration
+public class SearchResultFilteringEnumeration implements NamingEnumeration, AbandonListener
 {
     /** the logger used by this class */
     private static final Logger log = LoggerFactory.getLogger( SearchResultFilteringEnumeration.class );
@@ -68,6 +71,8 @@
     private final Invocation invocation;
     /** whether or not the caller context has object factories which need to be applied to the results */
     private final boolean applyObjectFactories;
+    /** whether or not this search has been abandoned */
+    private boolean abandoned = false;
 
 
     // ------------------------------------------------------------------------
@@ -282,6 +287,11 @@
     private void prefetch() throws NamingException
     {
         SearchResult tmp;
+        if ( abandoned )
+        {
+            this.close();
+            throw new OperationAbandonedException();
+        }
 
         outer:
         while( decorated.hasMore() )
@@ -337,5 +347,11 @@
          * filters before we exhausted the decorated enumeration so we close
          */
         close();
+    }
+
+
+    public void requestAbandoned( AbandonableRequest req )
+    {
+        this.abandoned = true;
     }
 }

Added: directory/trunk/ldap-common/src/main/java/org/apache/ldap/common/exception/OperationAbandonedException.java
URL: http://svn.apache.org/viewcvs/directory/trunk/ldap-common/src/main/java/org/apache/ldap/common/exception/OperationAbandonedException.java?rev=366597&view=auto
==============================================================================
--- directory/trunk/ldap-common/src/main/java/org/apache/ldap/common/exception/OperationAbandonedException.java (added)
+++ directory/trunk/ldap-common/src/main/java/org/apache/ldap/common/exception/OperationAbandonedException.java Fri Jan  6 15:21:28 2006
@@ -0,0 +1,32 @@
+/*
+ *   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.ldap.common.exception;
+
+
+import javax.naming.NamingException;
+
+
+/**
+ * Marker exception thrown when an operation is cancelled.
+ * 
+ * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
+ * @version $Rev$
+ */
+public class OperationAbandonedException extends NamingException
+{
+    private static final long serialVersionUID = -99548684403070989L;
+}

Propchange: directory/trunk/ldap-common/src/main/java/org/apache/ldap/common/exception/OperationAbandonedException.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: directory/trunk/ldap-common/src/main/java/org/apache/ldap/common/message/AbandonListener.java
URL: http://svn.apache.org/viewcvs/directory/trunk/ldap-common/src/main/java/org/apache/ldap/common/message/AbandonListener.java?rev=366597&view=auto
==============================================================================
--- directory/trunk/ldap-common/src/main/java/org/apache/ldap/common/message/AbandonListener.java (added)
+++ directory/trunk/ldap-common/src/main/java/org/apache/ldap/common/message/AbandonListener.java Fri Jan  6 15:21:28 2006
@@ -0,0 +1,33 @@
+/*
+ *
+ *   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.ldap.common.message;
+
+
+/**
+ * A listener interested in abandon operations performed on requests.
+ * 
+ * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
+ * @version $Rev$
+ */
+public interface AbandonListener
+{
+    /**
+     * Notifies that a request has been abandoned.
+     * 
+     * @param req the request which is abandoned.
+     */
+    void requestAbandoned( AbandonableRequest req );
+}

Propchange: directory/trunk/ldap-common/src/main/java/org/apache/ldap/common/message/AbandonListener.java
------------------------------------------------------------------------------
    svn:eol-style = native

Modified: directory/trunk/ldap-common/src/main/java/org/apache/ldap/common/message/AbandonRequestImpl.java
URL: http://svn.apache.org/viewcvs/directory/trunk/ldap-common/src/main/java/org/apache/ldap/common/message/AbandonRequestImpl.java?rev=366597&r1=366596&r2=366597&view=diff
==============================================================================
--- directory/trunk/ldap-common/src/main/java/org/apache/ldap/common/message/AbandonRequestImpl.java (original)
+++ directory/trunk/ldap-common/src/main/java/org/apache/ldap/common/message/AbandonRequestImpl.java Fri Jan  6 15:21:28 2006
@@ -24,8 +24,7 @@
  * Apache Directory Project</a>
  * @version $Rev$
  */
-public class AbandonRequestImpl
-    extends AbstractRequest implements AbandonRequest
+public class AbandonRequestImpl extends AbstractRequest implements AbandonRequest
 {
     static final long serialVersionUID = -4688193359792740969L;
     /** Sequence identifier of the outstanding request message to abandon */
@@ -93,5 +92,14 @@
         }
 
         return true;
+    }
+    
+    
+    /**
+     * RFC 2251 [Section 4.11]: Abandon, Bind, Unbind, and StartTLS operations cannot be abandoned. 
+     */
+    public void abandon()
+    {
+        throw new UnsupportedOperationException( "RFC 2251 [Section 4.11]: Abandon, Bind, Unbind, and StartTLS operations cannot be abandoned. " );
     }
 }

Added: directory/trunk/ldap-common/src/main/java/org/apache/ldap/common/message/AbandonableRequest.java
URL: http://svn.apache.org/viewcvs/directory/trunk/ldap-common/src/main/java/org/apache/ldap/common/message/AbandonableRequest.java?rev=366597&view=auto
==============================================================================
--- directory/trunk/ldap-common/src/main/java/org/apache/ldap/common/message/AbandonableRequest.java (added)
+++ directory/trunk/ldap-common/src/main/java/org/apache/ldap/common/message/AbandonableRequest.java Fri Jan  6 15:21:28 2006
@@ -0,0 +1,47 @@
+/*
+ *   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.ldap.common.message;
+
+
+/**
+ * A request which can be abandoned.
+ *  
+ * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
+ * @version $Rev$
+ */
+public interface AbandonableRequest extends Request
+{
+    /**
+     * Abandons this request.
+     */
+    void abandon();
+
+    /**
+     * Checks to see if this request has been abandoned.
+     * 
+     * @return true if the request has been abandoned.
+     */
+    boolean isAbandoned();
+    
+    /**
+     * Adds listener to be notified if this request gets abandoned.
+     * 
+     * @param listener to be notified if this request gets abandoned.
+     */
+    void addAbandonListener( AbandonListener listener );
+
+}

Propchange: directory/trunk/ldap-common/src/main/java/org/apache/ldap/common/message/AbandonableRequest.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: directory/trunk/ldap-common/src/main/java/org/apache/ldap/common/message/AbstractAbandonableRequest.java
URL: http://svn.apache.org/viewcvs/directory/trunk/ldap-common/src/main/java/org/apache/ldap/common/message/AbstractAbandonableRequest.java?rev=366597&view=auto
==============================================================================
--- directory/trunk/ldap-common/src/main/java/org/apache/ldap/common/message/AbstractAbandonableRequest.java (added)
+++ directory/trunk/ldap-common/src/main/java/org/apache/ldap/common/message/AbstractAbandonableRequest.java Fri Jan  6 15:21:28 2006
@@ -0,0 +1,85 @@
+/*
+ *   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.ldap.common.message ;
+
+
+import java.util.Observable;
+import java.util.Observer;
+
+
+/**
+ * The base abandonable request message class.  All such requests have a reponse type.
+ * 
+ * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
+ * @version $Rev: 359829 $
+ */
+public class AbstractAbandonableRequest extends AbstractRequest implements AbandonableRequest
+{
+    static final long serialVersionUID = -4511116249089399040L;
+    /** Flag indicating whether or not this request returns a response. */
+    private boolean abandoned = false;
+    private RequestObservable o;
+
+    
+    /**
+     * Subclasses must provide these parameters via a super constructor call.
+     *
+     * @param id the sequential message identifier
+     * @param type the request type enum
+     */
+    protected AbstractAbandonableRequest( final int id, final MessageTypeEnum type )
+    {
+        super( id, type, true ) ;
+    }
+
+
+    public void abandon()
+    {
+        if ( abandoned ) return;
+        abandoned = true;
+        o.setChanged();
+        o.notifyObservers();
+        o.deleteObservers();
+    }
+
+    
+    public boolean isAbandoned()
+    {
+        return abandoned;
+    }
+
+
+    public void addAbandonListener( final AbandonListener listener )
+    {
+        if ( o == null ) o = new RequestObservable();
+        o.addObserver( new Observer() {
+            public void update( Observable o, Object arg )
+            {
+                listener.requestAbandoned( AbstractAbandonableRequest.this );
+            }
+        });
+    }
+
+    
+    class RequestObservable extends Observable
+    {
+        public void setChanged()
+        {
+            super.setChanged();
+        }
+    }
+}

Propchange: directory/trunk/ldap-common/src/main/java/org/apache/ldap/common/message/AbstractAbandonableRequest.java
------------------------------------------------------------------------------
    svn:eol-style = native

Modified: directory/trunk/ldap-common/src/main/java/org/apache/ldap/common/message/AbstractMessage.java
URL: http://svn.apache.org/viewcvs/directory/trunk/ldap-common/src/main/java/org/apache/ldap/common/message/AbstractMessage.java?rev=366597&r1=366596&r2=366597&view=diff
==============================================================================
--- directory/trunk/ldap-common/src/main/java/org/apache/ldap/common/message/AbstractMessage.java (original)
+++ directory/trunk/ldap-common/src/main/java/org/apache/ldap/common/message/AbstractMessage.java Fri Jan  6 15:21:28 2006
@@ -49,8 +49,7 @@
      * @param id the seq id of the message
      * @param type the type of the message
      */
-    protected AbstractMessage( final int id,
-        final MessageTypeEnum type )
+    protected AbstractMessage( final int id, final MessageTypeEnum type )
     {
         super( true );
 
@@ -94,8 +93,7 @@
      * @throws MessageException if controls cannot be added to this Message or
      * the control is not known etc.
      */
-    public void add( Control control )
-        throws MessageException
+    public void add( Control control ) throws MessageException
     {
         lockCheck( "Attempt to add control to locked message envelope!" );
         controls.put( control.getType(), control );
@@ -109,8 +107,7 @@
      * @throws MessageException if controls cannot be added to this Message or
      * the control is not known etc.
      */
-    public void remove( Control control )
-        throws MessageException
+    public void remove( Control control ) throws MessageException
     {
         lockCheck( "Attempt to remove control from locked message envelope!" );
         controls.remove( control.getType() );

Modified: directory/trunk/ldap-common/src/main/java/org/apache/ldap/common/message/AbstractRequest.java
URL: http://svn.apache.org/viewcvs/directory/trunk/ldap-common/src/main/java/org/apache/ldap/common/message/AbstractRequest.java?rev=366597&r1=366596&r2=366597&view=diff
==============================================================================
--- directory/trunk/ldap-common/src/main/java/org/apache/ldap/common/message/AbstractRequest.java (original)
+++ directory/trunk/ldap-common/src/main/java/org/apache/ldap/common/message/AbstractRequest.java Fri Jan  6 15:21:28 2006
@@ -15,36 +15,33 @@
  *
  */
 package org.apache.ldap.common.message ;
-
+
 
 /**
  * The base request message class.
  * 
- * @author <a href="mailto:dev@directory.apache.org">
- * Apache Directory Project</a>
+ * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
  * @version $Rev$
  */
-public class AbstractRequest
-    extends AbstractMessage implements Request
+public class AbstractRequest extends AbstractMessage implements Request
 {
     static final long serialVersionUID = -4511116249089399040L;
     /** Flag indicating whether or not this request returns a response. */
-    private final boolean m_hasResponse ;
-
-
+    private final boolean hasResponse ;
+ 
+    
     /**
      * Subclasses must provide these parameters via a super constructor call.
      *
-     * @param a_id the sequential message identifier
-     * @param a_type the request type enum
-     * @param a_hasResponse flag indicating if this request generates a response
+     * @param id the sequential message identifier
+     * @param type the request type enum
+     * @param hasResponse flag indicating if this request generates a response
      */
-    protected AbstractRequest( final int a_id,
-        final MessageTypeEnum a_type, boolean a_hasResponse )
+    protected AbstractRequest( final int id, final MessageTypeEnum type, boolean hasResponse )
     {
-        super( a_id, a_type ) ;
+        super( id, type ) ;
 
-        m_hasResponse = a_hasResponse ;
+        this.hasResponse = hasResponse ;
     }
 
 
@@ -56,6 +53,6 @@
      */
     public boolean hasResponse()
     {
-        return m_hasResponse ;
-    }
-}
+        return hasResponse ;
+    }
+ }

Modified: directory/trunk/ldap-common/src/main/java/org/apache/ldap/common/message/AddRequest.java
URL: http://svn.apache.org/viewcvs/directory/trunk/ldap-common/src/main/java/org/apache/ldap/common/message/AddRequest.java?rev=366597&r1=366596&r2=366597&view=diff
==============================================================================
--- directory/trunk/ldap-common/src/main/java/org/apache/ldap/common/message/AddRequest.java (original)
+++ directory/trunk/ldap-common/src/main/java/org/apache/ldap/common/message/AddRequest.java Fri Jan  6 15:21:28 2006
@@ -37,8 +37,7 @@
  * @author $Author: akarasulu $
  * @version $Revision$
  */
-public interface AddRequest
-    extends SingleReplyRequest
+public interface AddRequest extends SingleReplyRequest, AbandonableRequest
 {
     /** LDAPv3 add request type enum code */
     MessageTypeEnum TYPE = MessageTypeEnum.ADDREQUEST ;

Modified: directory/trunk/ldap-common/src/main/java/org/apache/ldap/common/message/AddRequestImpl.java
URL: http://svn.apache.org/viewcvs/directory/trunk/ldap-common/src/main/java/org/apache/ldap/common/message/AddRequestImpl.java?rev=366597&r1=366596&r2=366597&view=diff
==============================================================================
--- directory/trunk/ldap-common/src/main/java/org/apache/ldap/common/message/AddRequestImpl.java (original)
+++ directory/trunk/ldap-common/src/main/java/org/apache/ldap/common/message/AddRequestImpl.java Fri Jan  6 15:21:28 2006
@@ -29,8 +29,7 @@
  * Apache Directory Project</a>
  * @version $Rev$
  */
-public class AddRequestImpl
-    extends AbstractRequest implements AddRequest
+public class AddRequestImpl extends AbstractAbandonableRequest implements AddRequest
 {
     static final long serialVersionUID = 7534132448349520346L;
     /** Distinguished name of the new entry. */
@@ -52,7 +51,7 @@
      */
     public AddRequestImpl( final int id )
     {
-        super( id, TYPE, true );
+        super( id, TYPE );
     }
 
 

Modified: directory/trunk/ldap-common/src/main/java/org/apache/ldap/common/message/BindRequestImpl.java
URL: http://svn.apache.org/viewcvs/directory/trunk/ldap-common/src/main/java/org/apache/ldap/common/message/BindRequestImpl.java?rev=366597&r1=366596&r2=366597&view=diff
==============================================================================
--- directory/trunk/ldap-common/src/main/java/org/apache/ldap/common/message/BindRequestImpl.java (original)
+++ directory/trunk/ldap-common/src/main/java/org/apache/ldap/common/message/BindRequestImpl.java Fri Jan  6 15:21:28 2006
@@ -338,4 +338,13 @@
         
         return sb.toString();
     }
+
+    
+    /**
+     * RFC 2251 [Section 4.11]: Abandon, Bind, Unbind, and StartTLS operations cannot be abandoned. 
+     */
+    public void abandon()
+    {
+        throw new UnsupportedOperationException( "RFC 2251 [Section 4.11]: Abandon, Bind, Unbind, and StartTLS operations cannot be abandoned. " );
+    }
 }

Modified: directory/trunk/ldap-common/src/main/java/org/apache/ldap/common/message/CompareRequest.java
URL: http://svn.apache.org/viewcvs/directory/trunk/ldap-common/src/main/java/org/apache/ldap/common/message/CompareRequest.java?rev=366597&r1=366596&r2=366597&view=diff
==============================================================================
--- directory/trunk/ldap-common/src/main/java/org/apache/ldap/common/message/CompareRequest.java (original)
+++ directory/trunk/ldap-common/src/main/java/org/apache/ldap/common/message/CompareRequest.java Fri Jan  6 15:21:28 2006
@@ -35,8 +35,7 @@
  * @author $Author: akarasulu $
  * @version $Revision$
  */
-public interface CompareRequest
-    extends SingleReplyRequest
+public interface CompareRequest extends SingleReplyRequest, AbandonableRequest
 {
     /** Compare request message type enum code */
     MessageTypeEnum TYPE = MessageTypeEnum.COMPAREREQUEST ;

Modified: directory/trunk/ldap-common/src/main/java/org/apache/ldap/common/message/CompareRequestImpl.java
URL: http://svn.apache.org/viewcvs/directory/trunk/ldap-common/src/main/java/org/apache/ldap/common/message/CompareRequestImpl.java?rev=366597&r1=366596&r2=366597&view=diff
==============================================================================
--- directory/trunk/ldap-common/src/main/java/org/apache/ldap/common/message/CompareRequestImpl.java (original)
+++ directory/trunk/ldap-common/src/main/java/org/apache/ldap/common/message/CompareRequestImpl.java Fri Jan  6 15:21:28 2006
@@ -28,8 +28,7 @@
  * Apache Directory Project</a>
  * @version $Rev$
  */
-public class CompareRequestImpl
-    extends AbstractRequest implements CompareRequest
+public class CompareRequestImpl extends AbstractAbandonableRequest implements CompareRequest
 {
     static final long serialVersionUID = 1699731530016468977L;
     /** Distinguished name identifying the compared entry */
@@ -53,7 +52,7 @@
      */
     public CompareRequestImpl( final int id )
     {
-        super( id, TYPE, true );
+        super( id, TYPE );
     }
 
 

Modified: directory/trunk/ldap-common/src/main/java/org/apache/ldap/common/message/DeleteRequest.java
URL: http://svn.apache.org/viewcvs/directory/trunk/ldap-common/src/main/java/org/apache/ldap/common/message/DeleteRequest.java?rev=366597&r1=366596&r2=366597&view=diff
==============================================================================
--- directory/trunk/ldap-common/src/main/java/org/apache/ldap/common/message/DeleteRequest.java (original)
+++ directory/trunk/ldap-common/src/main/java/org/apache/ldap/common/message/DeleteRequest.java Fri Jan  6 15:21:28 2006
@@ -35,7 +35,7 @@
  * @author $Author: akarasulu $
  * @version $Revision$
  */
-public interface DeleteRequest extends SingleReplyRequest
+public interface DeleteRequest extends SingleReplyRequest, AbandonableRequest
 {
     /** Delete request message type enumeration value */
     MessageTypeEnum TYPE = MessageTypeEnum.DELREQUEST ;

Modified: directory/trunk/ldap-common/src/main/java/org/apache/ldap/common/message/DeleteRequestImpl.java
URL: http://svn.apache.org/viewcvs/directory/trunk/ldap-common/src/main/java/org/apache/ldap/common/message/DeleteRequestImpl.java?rev=366597&r1=366596&r2=366597&view=diff
==============================================================================
--- directory/trunk/ldap-common/src/main/java/org/apache/ldap/common/message/DeleteRequestImpl.java (original)
+++ directory/trunk/ldap-common/src/main/java/org/apache/ldap/common/message/DeleteRequestImpl.java Fri Jan  6 15:21:28 2006
@@ -24,8 +24,7 @@
  * Apache Directory Project</a>
  * @version $Rev$
  */
-public class DeleteRequestImpl
-    extends AbstractRequest implements DeleteRequest
+public class DeleteRequestImpl extends AbstractAbandonableRequest implements DeleteRequest
 {
     static final long serialVersionUID = 3187847454305567542L;
     /** The distinguished name of the entry to delete */
@@ -45,7 +44,7 @@
      */
     public DeleteRequestImpl( final int id )
     {
-        super( id, TYPE, true );
+        super( id, TYPE );
     }
 
 

Modified: directory/trunk/ldap-common/src/main/java/org/apache/ldap/common/message/ModifyDnRequest.java
URL: http://svn.apache.org/viewcvs/directory/trunk/ldap-common/src/main/java/org/apache/ldap/common/message/ModifyDnRequest.java?rev=366597&r1=366596&r2=366597&view=diff
==============================================================================
--- directory/trunk/ldap-common/src/main/java/org/apache/ldap/common/message/ModifyDnRequest.java (original)
+++ directory/trunk/ldap-common/src/main/java/org/apache/ldap/common/message/ModifyDnRequest.java Fri Jan  6 15:21:28 2006
@@ -69,7 +69,7 @@
  * @author $Author: akarasulu $
  * @version $Revision$
  */
-public interface ModifyDnRequest extends SingleReplyRequest
+public interface ModifyDnRequest extends SingleReplyRequest, AbandonableRequest
 {
     /** Modify DN request message type enumeration value */
     MessageTypeEnum TYPE = MessageTypeEnum.MODDNREQUEST ;

Modified: directory/trunk/ldap-common/src/main/java/org/apache/ldap/common/message/ModifyDnRequestImpl.java
URL: http://svn.apache.org/viewcvs/directory/trunk/ldap-common/src/main/java/org/apache/ldap/common/message/ModifyDnRequestImpl.java?rev=366597&r1=366596&r2=366597&view=diff
==============================================================================
--- directory/trunk/ldap-common/src/main/java/org/apache/ldap/common/message/ModifyDnRequestImpl.java (original)
+++ directory/trunk/ldap-common/src/main/java/org/apache/ldap/common/message/ModifyDnRequestImpl.java Fri Jan  6 15:21:28 2006
@@ -20,12 +20,10 @@
 /**
  * Lockable ModifyDNRequest implementation.
  * 
- * @author <a href="mailto:dev@directory.apache.org">
- * Apache Directory Project</a>
+ * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
  * @version $Rev$
  */
-public class ModifyDnRequestImpl
-    extends AbstractRequest implements ModifyDnRequest
+public class ModifyDnRequestImpl extends AbstractAbandonableRequest implements ModifyDnRequest
 {
     static final long serialVersionUID = 1233507339633051696L;
     
@@ -55,7 +53,7 @@
      */
     public ModifyDnRequestImpl( final int id )
     {
-        super( id, TYPE, true ) ;
+        super( id, TYPE ) ;
     }
 
 

Modified: directory/trunk/ldap-common/src/main/java/org/apache/ldap/common/message/ModifyRequest.java
URL: http://svn.apache.org/viewcvs/directory/trunk/ldap-common/src/main/java/org/apache/ldap/common/message/ModifyRequest.java?rev=366597&r1=366596&r2=366597&view=diff
==============================================================================
--- directory/trunk/ldap-common/src/main/java/org/apache/ldap/common/message/ModifyRequest.java (original)
+++ directory/trunk/ldap-common/src/main/java/org/apache/ldap/common/message/ModifyRequest.java Fri Jan  6 15:21:28 2006
@@ -100,7 +100,7 @@
  * @author $Author: akarasulu $
  * @version $Revision$
  */
-public interface ModifyRequest extends SingleReplyRequest
+public interface ModifyRequest extends SingleReplyRequest, AbandonableRequest
 {
     /** Modify request message type enumeration value */
     MessageTypeEnum TYPE = MessageTypeEnum.MODIFYREQUEST ;

Modified: directory/trunk/ldap-common/src/main/java/org/apache/ldap/common/message/ModifyRequestImpl.java
URL: http://svn.apache.org/viewcvs/directory/trunk/ldap-common/src/main/java/org/apache/ldap/common/message/ModifyRequestImpl.java?rev=366597&r1=366596&r2=366597&view=diff
==============================================================================
--- directory/trunk/ldap-common/src/main/java/org/apache/ldap/common/message/ModifyRequestImpl.java (original)
+++ directory/trunk/ldap-common/src/main/java/org/apache/ldap/common/message/ModifyRequestImpl.java Fri Jan  6 15:21:28 2006
@@ -38,13 +38,11 @@
 /**
  * Lockable ModifyRequest implementation.
  * 
- * @author <a href="mailto:dev@directory.apache.org">
- * Apache Directory Project</a>
+ * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
  * @version $Rev$
  */
-public class ModifyRequestImpl
-    extends AbstractRequest implements ModifyRequest
-{
+public class ModifyRequestImpl extends AbstractAbandonableRequest implements ModifyRequest
+{ 
     static final long serialVersionUID = -505803669028990304L;
     
     /** The logger */
@@ -69,7 +67,7 @@
      */
     public ModifyRequestImpl( final int id )
     {
-        super( id, TYPE, true ) ;
+        super( id, TYPE ) ;
     }
 
 

Modified: directory/trunk/ldap-common/src/main/java/org/apache/ldap/common/message/SearchRequest.java
URL: http://svn.apache.org/viewcvs/directory/trunk/ldap-common/src/main/java/org/apache/ldap/common/message/SearchRequest.java?rev=366597&r1=366596&r2=366597&view=diff
==============================================================================
--- directory/trunk/ldap-common/src/main/java/org/apache/ldap/common/message/SearchRequest.java (original)
+++ directory/trunk/ldap-common/src/main/java/org/apache/ldap/common/message/SearchRequest.java Fri Jan  6 15:21:28 2006
@@ -29,8 +29,7 @@
  * Apache Directory Project</a>
  * @version $Rev$
  */
-public interface SearchRequest
-    extends ManyReplyRequest
+public interface SearchRequest extends ManyReplyRequest, AbandonableRequest
 {
     /** Search request protocol message type */
     MessageTypeEnum TYPE = MessageTypeEnum.SEARCHREQUEST ;
@@ -214,7 +213,7 @@
      *
      * @param a_attribute the attribute description or identifier.
      */
-    void removeAttribute( String a_attribute ) ;
+    void removeAttribute( String a_attribute ) ;
 }
 
 

Modified: directory/trunk/ldap-common/src/main/java/org/apache/ldap/common/message/SearchRequestImpl.java
URL: http://svn.apache.org/viewcvs/directory/trunk/ldap-common/src/main/java/org/apache/ldap/common/message/SearchRequestImpl.java?rev=366597&r1=366596&r2=366597&view=diff
==============================================================================
--- directory/trunk/ldap-common/src/main/java/org/apache/ldap/common/message/SearchRequestImpl.java (original)
+++ directory/trunk/ldap-common/src/main/java/org/apache/ldap/common/message/SearchRequestImpl.java Fri Jan  6 15:21:28 2006
@@ -33,8 +33,7 @@
  * Apache Directory Project</a>
  * @version $Rev$
  */
-public class SearchRequestImpl
-    extends AbstractRequest implements SearchRequest
+public class SearchRequestImpl extends AbstractAbandonableRequest implements SearchRequest
 {
     static final long serialVersionUID = -5655881944020886218L;
     /** Search base distinguished name */
@@ -68,7 +67,7 @@
      */
     public SearchRequestImpl( final int id )
     {
-        super( id, TYPE, true ) ;
+        super( id, TYPE ) ;
     }
 
 

Modified: directory/trunk/ldap-common/src/main/java/org/apache/ldap/common/message/UnbindRequestImpl.java
URL: http://svn.apache.org/viewcvs/directory/trunk/ldap-common/src/main/java/org/apache/ldap/common/message/UnbindRequestImpl.java?rev=366597&r1=366596&r2=366597&view=diff
==============================================================================
--- directory/trunk/ldap-common/src/main/java/org/apache/ldap/common/message/UnbindRequestImpl.java (original)
+++ directory/trunk/ldap-common/src/main/java/org/apache/ldap/common/message/UnbindRequestImpl.java Fri Jan  6 15:21:28 2006
@@ -38,4 +38,13 @@
     {
         super( id, TYPE, false );
     }
+    
+    
+    /**
+     * RFC 2251 [Section 4.11]: Abandon, Bind, Unbind, and StartTLS operations cannot be abandoned. 
+     */
+    public void abandon()
+    {
+        throw new UnsupportedOperationException( "RFC 2251 [Section 4.11]: Abandon, Bind, Unbind, and StartTLS operations cannot be abandoned. " );
+    }
 }

Modified: directory/trunk/ldap-common/src/test/java/org/apache/ldap/common/message/AddRequestImplTest.java
URL: http://svn.apache.org/viewcvs/directory/trunk/ldap-common/src/test/java/org/apache/ldap/common/message/AddRequestImplTest.java?rev=366597&r1=366596&r2=366597&view=diff
==============================================================================
--- directory/trunk/ldap-common/src/test/java/org/apache/ldap/common/message/AddRequestImplTest.java (original)
+++ directory/trunk/ldap-common/src/test/java/org/apache/ldap/common/message/AddRequestImplTest.java Fri Jan  6 15:21:28 2006
@@ -248,6 +248,19 @@
             {
                 return false;
             }
+
+            public void abandon()
+            {
+            }
+
+            public boolean isAbandoned()
+            {
+                return false;
+            }
+
+            public void addAbandonListener(AbandonListener listener)
+            {
+            }
         };
 
         AddRequestImpl req1 = new AddRequestImpl( 5 );

Modified: directory/trunk/ldap-common/src/test/java/org/apache/ldap/common/message/BindRequestImplTest.java
URL: http://svn.apache.org/viewcvs/directory/trunk/ldap-common/src/test/java/org/apache/ldap/common/message/BindRequestImplTest.java?rev=366597&r1=366596&r2=366597&view=diff
==============================================================================
--- directory/trunk/ldap-common/src/test/java/org/apache/ldap/common/message/BindRequestImplTest.java (original)
+++ directory/trunk/ldap-common/src/test/java/org/apache/ldap/common/message/BindRequestImplTest.java Fri Jan  6 15:21:28 2006
@@ -300,6 +300,19 @@
             public void setSaslMechanism( String saslMechanism )
             {
             }
+
+            public void abandon()
+            {
+            }
+
+            public boolean isAbandoned()
+            {
+                return false;
+            }
+
+            public void addAbandonListener(AbandonListener listener)
+            {
+            }
         };
 
         BindRequestImpl req1 = new BindRequestImpl( 5 );

Modified: directory/trunk/ldap-common/src/test/java/org/apache/ldap/common/message/CompareRequestImplTest.java
URL: http://svn.apache.org/viewcvs/directory/trunk/ldap-common/src/test/java/org/apache/ldap/common/message/CompareRequestImplTest.java?rev=366597&r1=366596&r2=366597&view=diff
==============================================================================
--- directory/trunk/ldap-common/src/test/java/org/apache/ldap/common/message/CompareRequestImplTest.java (original)
+++ directory/trunk/ldap-common/src/test/java/org/apache/ldap/common/message/CompareRequestImplTest.java Fri Jan  6 15:21:28 2006
@@ -161,20 +161,6 @@
             {
             }
 
-//            public boolean isVersion3()
-//            {
-//                return true;
-//            }
-//
-//            public boolean getVersion3()
-//            {
-//                return true;
-//            }
-//
-//            public void setVersion3( boolean a_isVersion3 )
-//            {
-//            }
-
             public MessageTypeEnum getResponseType()
             {
                 return MessageTypeEnum.COMPARERESPONSE;
@@ -240,6 +226,19 @@
             public boolean isUnlockable()
             {
                 return false;
+            }
+
+            public void abandon()
+            {
+            }
+
+            public boolean isAbandoned()
+            {
+                return false;
+            }
+
+            public void addAbandonListener(AbandonListener listener)
+            {
             }
         };
 

Modified: directory/trunk/ldap-common/src/test/java/org/apache/ldap/common/message/DeleteRequestImplTest.java
URL: http://svn.apache.org/viewcvs/directory/trunk/ldap-common/src/test/java/org/apache/ldap/common/message/DeleteRequestImplTest.java?rev=366597&r1=366596&r2=366597&view=diff
==============================================================================
--- directory/trunk/ldap-common/src/test/java/org/apache/ldap/common/message/DeleteRequestImplTest.java (original)
+++ directory/trunk/ldap-common/src/test/java/org/apache/ldap/common/message/DeleteRequestImplTest.java Fri Jan  6 15:21:28 2006
@@ -172,6 +172,19 @@
             {
                 return false;
             }
+
+            public void abandon()
+            {
+            }
+
+            public boolean isAbandoned()
+            {
+                return false;
+            }
+
+            public void addAbandonListener(AbandonListener listener)
+            {
+            }
         };
 
         DeleteRequestImpl req1 = new DeleteRequestImpl( 5 );

Modified: directory/trunk/ldap-common/src/test/java/org/apache/ldap/common/message/ExtendedRequestImplTest.java
URL: http://svn.apache.org/viewcvs/directory/trunk/ldap-common/src/test/java/org/apache/ldap/common/message/ExtendedRequestImplTest.java?rev=366597&r1=366596&r2=366597&view=diff
==============================================================================
--- directory/trunk/ldap-common/src/test/java/org/apache/ldap/common/message/ExtendedRequestImplTest.java (original)
+++ directory/trunk/ldap-common/src/test/java/org/apache/ldap/common/message/ExtendedRequestImplTest.java Fri Jan  6 15:21:28 2006
@@ -203,6 +203,19 @@
             {
                 return false;
             }
+
+            public void abandon()
+            {
+            }
+
+            public boolean isAbandoned()
+            {
+                return false;
+            }
+
+            public void addAbandonListener(AbandonListener listener)
+            {
+            }
         };
 
         ExtendedRequestImpl req1 = new ExtendedRequestImpl( 5 );

Modified: directory/trunk/ldap-common/src/test/java/org/apache/ldap/common/message/ModifyDnRequestImplTest.java
URL: http://svn.apache.org/viewcvs/directory/trunk/ldap-common/src/test/java/org/apache/ldap/common/message/ModifyDnRequestImplTest.java?rev=366597&r1=366596&r2=366597&view=diff
==============================================================================
--- directory/trunk/ldap-common/src/test/java/org/apache/ldap/common/message/ModifyDnRequestImplTest.java (original)
+++ directory/trunk/ldap-common/src/test/java/org/apache/ldap/common/message/ModifyDnRequestImplTest.java Fri Jan  6 15:21:28 2006
@@ -275,6 +275,19 @@
             {
                 return false;
             }
+
+            public void abandon()
+            {
+            }
+
+            public boolean isAbandoned()
+            {
+                return false;
+            }
+
+            public void addAbandonListener(AbandonListener listener)
+            {
+            }
         };
 
         ModifyDnRequestImpl req1 = getRequest();

Modified: directory/trunk/ldap-common/src/test/java/org/apache/ldap/common/message/ModifyRequestImplTest.java
URL: http://svn.apache.org/viewcvs/directory/trunk/ldap-common/src/test/java/org/apache/ldap/common/message/ModifyRequestImplTest.java?rev=366597&r1=366596&r2=366597&view=diff
==============================================================================
--- directory/trunk/ldap-common/src/test/java/org/apache/ldap/common/message/ModifyRequestImplTest.java (original)
+++ directory/trunk/ldap-common/src/test/java/org/apache/ldap/common/message/ModifyRequestImplTest.java Fri Jan  6 15:21:28 2006
@@ -336,6 +336,19 @@
             {
                 return false;
             }
+
+            public void abandon()
+            {
+            }
+
+            public boolean isAbandoned()
+            {
+                return false;
+            }
+
+            public void addAbandonListener(AbandonListener listener)
+            {
+            }
         };
 
         ModifyRequestImpl req1 = getRequest();

Modified: directory/trunk/ldap-protocol/src/main/java/org/apache/ldap/server/protocol/SessionRegistry.java
URL: http://svn.apache.org/viewcvs/directory/trunk/ldap-protocol/src/main/java/org/apache/ldap/server/protocol/SessionRegistry.java?rev=366597&r1=366596&r2=366597&view=diff
==============================================================================
--- directory/trunk/ldap-protocol/src/main/java/org/apache/ldap/server/protocol/SessionRegistry.java (original)
+++ directory/trunk/ldap-protocol/src/main/java/org/apache/ldap/server/protocol/SessionRegistry.java Fri Jan  6 15:21:28 2006
@@ -137,6 +137,19 @@
             reqmap.put( new Integer( req.getMessageId() ), req );
         }
     }
+
+
+    /**
+     * Overload that does not require boxing of primitive messageId.
+     * 
+     * @param session the session associated with the request
+     * @param messageId the id of the request
+     * @return the Request if it is removed or null if no such request was mapped as outstanding
+     */
+    public Request removeOutstandingRequest( IoSession session, int messageId )
+    {
+        return removeOutstandingRequest( session, new Integer( messageId ) );
+    }
     
 
     /**
@@ -174,7 +187,19 @@
         return new HashMap( reqmap );
     }
     
-    
+
+    /**
+     * Overload that does not require boxing of primitive messageId.
+     * 
+     * @param session the session associated with the request
+     * @param messageId the id of the request
+     * @return the request in session for id or null if request has completed
+     */
+    public Request getOutstandingRequest( IoSession session, int abandonedId )
+    {
+        return getOutstandingRequest( session, new Integer( abandonedId ) );
+    }
+
     /**
      * Gets an outstanding request by messageId for a session.
      * 

Modified: directory/trunk/ldap-protocol/src/main/java/org/apache/ldap/server/protocol/support/AbandonHandler.java
URL: http://svn.apache.org/viewcvs/directory/trunk/ldap-protocol/src/main/java/org/apache/ldap/server/protocol/support/AbandonHandler.java?rev=366597&r1=366596&r2=366597&view=diff
==============================================================================
--- directory/trunk/ldap-protocol/src/main/java/org/apache/ldap/server/protocol/support/AbandonHandler.java (original)
+++ directory/trunk/ldap-protocol/src/main/java/org/apache/ldap/server/protocol/support/AbandonHandler.java Fri Jan  6 15:21:28 2006
@@ -18,6 +18,9 @@
 
 
 import org.apache.ldap.common.message.AbandonRequest;
+import org.apache.ldap.common.message.AbandonableRequest;
+import org.apache.ldap.common.message.Request;
+import org.apache.ldap.server.protocol.SessionRegistry;
 import org.apache.mina.common.IoSession;
 import org.apache.mina.handler.demux.MessageHandler;
 import org.slf4j.Logger;
@@ -43,7 +46,39 @@
         {
             return;
         }
+
+        Request abandonedRequest = SessionRegistry.getSingleton().getOutstandingRequest( session, abandonedId );
+        
+        if ( abandonedRequest == null )
+        {
+            if ( log.isWarnEnabled() )
+            {
+                log.warn( "Got abandon request from client " + session + " but request must have already " +
+                        "terminated.  Abandon request "+req+" had no effect." );
+            }
+            return;
+        }
+        
+        if ( abandonedRequest instanceof AbandonableRequest )
+        {
+            log.warn( "Abandon, Bind, Unbind, and StartTLS operations cannot be abandoned.  Abandon request will be ignored." );
+        }
         
-        log.warn( "Got abandon request from client but I don't know how to do this just yet" );
+        ( ( AbandonableRequest ) abandonedRequest ).abandon();
+        if ( SessionRegistry.getSingleton().removeOutstandingRequest( session, abandonedId ) == null )
+        {
+            if ( log.isWarnEnabled() )
+            {
+                log.warn( "Got abandon request from client " + session + " but request must have already " +
+                        "terminated." );
+            }
+        }
+        else
+        {
+            if ( log.isDebugEnabled() )
+            {
+                log.debug( "Abandoned request: " + req );
+            }
+        }
     }
 }

Modified: directory/trunk/ldap-protocol/src/main/java/org/apache/ldap/server/protocol/support/PersistentSearchListener.java
URL: http://svn.apache.org/viewcvs/directory/trunk/ldap-protocol/src/main/java/org/apache/ldap/server/protocol/support/PersistentSearchListener.java?rev=366597&r1=366596&r2=366597&view=diff
==============================================================================
--- directory/trunk/ldap-protocol/src/main/java/org/apache/ldap/server/protocol/support/PersistentSearchListener.java (original)
+++ directory/trunk/ldap-protocol/src/main/java/org/apache/ldap/server/protocol/support/PersistentSearchListener.java Fri Jan  6 15:21:28 2006
@@ -27,6 +27,9 @@
 
 import org.apache.ldap.common.codec.search.controls.ChangeType;
 import org.apache.ldap.common.exception.LdapException;
+import org.apache.ldap.common.exception.OperationAbandonedException;
+import org.apache.ldap.common.message.AbandonListener;
+import org.apache.ldap.common.message.AbandonableRequest;
 import org.apache.ldap.common.message.Control;
 import org.apache.ldap.common.message.EntryChangeControl;
 import org.apache.ldap.common.message.LdapResultImpl;
@@ -58,7 +61,7 @@
  * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
  * @version $Rev$
  */
-class PersistentSearchListener implements ObjectChangeListener, NamespaceChangeListener
+class PersistentSearchListener implements ObjectChangeListener, NamespaceChangeListener, AbandonListener
 {
     private static final Logger log = LoggerFactory.getLogger( SearchHandler.class );
     final ServerLdapContext ctx;
@@ -71,26 +74,29 @@
     {
         this.session = session;
         this.req = req;
+        req.addAbandonListener( this );
         this.ctx = ctx;
-        this.req.put( "PersistentSearchHandler", this );
         this.control = getPersistentSearchControl( req );
     }
     
     
     public void abandon() throws NamingException
     {
-        // must abandon the operation and send response done with success
+        // must abandon the operation 
         ctx.removeNamingListener( this );
 
-        // remove from outstanding map
-        SessionRegistry.getSingleton().removeOutstandingRequest( session, new Integer( req.getMessageId() ) );
-        
-        // send successful response back to client
-        SearchResponseDone resp = new SearchResponseDoneImpl( req.getMessageId() );
-        resp.setLdapResult( new LdapResultImpl( resp ) );
-        resp.getLdapResult().setResultCode( ResultCodeEnum.SUCCESS );
-        resp.getLdapResult().setMatchedDn( req.getBase() );
-        session.write( resp );
+        /*
+         * From RFC 2251 Section 4.11:
+         * 
+         * In the event that a server receives an Abandon Request on a Search  
+         * operation in the midst of transmitting responses to the Search, that
+         * server MUST cease transmitting entry responses to the abandoned
+         * request immediately, and MUST NOT send the SearchResultDone. Of
+         * course, the server MUST ensure that only properly encoded LDAPMessage
+         * PDUs are transmitted. 
+         * 
+         * SO DON'T SEND BACK ANYTHING!!!!!
+         */
     }
     
     
@@ -107,6 +113,23 @@
         {
             log.error( "Attempt to remove listener from context failed", e );
         }
+        
+        /*
+         * From RFC 2251 Section 4.11:
+         * 
+         * In the event that a server receives an Abandon Request on a Search  
+         * operation in the midst of transmitting responses to the Search, that
+         * server MUST cease transmitting entry responses to the abandoned
+         * request immediately, and MUST NOT send the SearchResultDone. Of
+         * course, the server MUST ensure that only properly encoded LDAPMessage
+         * PDUs are transmitted. 
+         * 
+         * SO DON'T SEND BACK ANYTHING!!!!!
+         */
+        if ( evt.getException() instanceof OperationAbandonedException )
+        {
+            return;
+        }
 
         SessionRegistry.getSingleton().removeOutstandingRequest( session, new Integer( req.getMessageId() ) );
         String msg = "failed on persistent search operation";
@@ -250,5 +273,18 @@
         }
         
         return null;
+    }
+
+
+    public void requestAbandoned( AbandonableRequest req )
+    {
+        try
+        {
+            abandon();
+        }
+        catch ( NamingException e )
+        {
+            log.error( "failed to properly abandon this persistent search", e );
+        }
     }
 }

Modified: directory/trunk/ldap-protocol/src/main/java/org/apache/ldap/server/protocol/support/SearchHandler.java
URL: http://svn.apache.org/viewcvs/directory/trunk/ldap-protocol/src/main/java/org/apache/ldap/server/protocol/support/SearchHandler.java?rev=366597&r1=366596&r2=366597&view=diff
==============================================================================
--- directory/trunk/ldap-protocol/src/main/java/org/apache/ldap/server/protocol/support/SearchHandler.java (original)
+++ directory/trunk/ldap-protocol/src/main/java/org/apache/ldap/server/protocol/support/SearchHandler.java Fri Jan  6 15:21:28 2006
@@ -28,7 +28,9 @@
 
 import org.apache.ldap.common.codec.util.LdapResultEnum;
 import org.apache.ldap.common.exception.LdapException;
+import org.apache.ldap.common.exception.OperationAbandonedException;
 import org.apache.ldap.common.filter.PresenceNode;
+import org.apache.ldap.common.message.AbandonListener;
 import org.apache.ldap.common.message.LdapResultImpl;
 import org.apache.ldap.common.message.PersistentSearchControl;
 import org.apache.ldap.common.message.Response;
@@ -113,6 +115,9 @@
         String[] ids = null;
         Collection retAttrs = new HashSet();
         retAttrs.addAll( req.getAttributes() );
+        
+        // add the search request to the registry of outstanding requests for this session
+        SessionRegistry.getSingleton().addOutstandingRequest( session, req );
 
         // check the attributes to see if a referral's ref attribute is included
         if( retAttrs.size() > 0 && !retAttrs.contains( "ref" ) )
@@ -195,6 +200,10 @@
                 if ( ! psearchControl.isChangesOnly() )
                 {
                     list = ( ( ServerLdapContext ) ctx ).search( new LdapName( req.getBase() ), req.getFilter(), controls );
+                    if ( list instanceof AbandonListener )
+                    {
+                        req.addAbandonListener( ( AbandonListener ) list );
+                    }
                     if( list.hasMore() )
                     {
                         Iterator it = new SearchResponseIterator( req, list );
@@ -241,6 +250,11 @@
              * for each search result returned.  
              */
             list = ( ( ServerLdapContext ) ctx ).search( new LdapName( req.getBase() ), req.getFilter(), controls );
+            if ( list instanceof AbandonListener )
+            {
+                req.addAbandonListener( ( AbandonListener ) list );
+            }
+            
             if( list.hasMore() )
             {
                 Iterator it = new SearchResponseIterator( req, list );
@@ -269,8 +283,24 @@
         }
         catch( NamingException e )
         {
+            /*
+             * From RFC 2251 Section 4.11:
+             * 
+             * In the event that a server receives an Abandon Request on a Search  
+             * operation in the midst of transmitting responses to the Search, that
+             * server MUST cease transmitting entry responses to the abandoned
+             * request immediately, and MUST NOT send the SearchResultDone. Of
+             * course, the server MUST ensure that only properly encoded LDAPMessage
+             * PDUs are transmitted. 
+             * 
+             * SO DON'T SEND BACK ANYTHING!!!!!
+             */
+            if ( e instanceof OperationAbandonedException )
+            {
+                return;
+            }
+            
             String msg = "failed on search operation";
-
             if ( log.isDebugEnabled() )
             {
                 msg += ":\n" + req + ":\n" + ExceptionUtils.getStackTrace( e );
@@ -302,10 +332,17 @@
             }
 
             Iterator it = Collections.singleton( resp ).iterator();
-
             while( it.hasNext() )
             {
                 session.write( it.next() );
+            }
+        }
+        finally
+        {
+            SessionRegistry.getSingleton().removeOutstandingRequest( session, req.getMessageId() );
+            if ( list != null )
+            {
+                try { list.close(); } catch( NamingException e ){ log.error("failed on list.close()", e ); } 
             }
         }
     }