From 6607300a6843009cd3ad72c3a7498d1766c34d5f Mon Sep 17 00:00:00 2001
From: boli <boli@localhost>
Date: Mon, 06 Apr 2009 20:34:48 +0000
Subject: [PATCH] Fix for issue 3609:

---
 opends/src/server/org/opends/server/admin/server/ServerManagedObject.java |  275 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 275 insertions(+), 0 deletions(-)

diff --git a/opends/src/server/org/opends/server/admin/server/ServerManagedObject.java b/opends/src/server/org/opends/server/admin/server/ServerManagedObject.java
index 991e19c..7100abf 100644
--- a/opends/src/server/org/opends/server/admin/server/ServerManagedObject.java
+++ b/opends/src/server/org/opends/server/admin/server/ServerManagedObject.java
@@ -1235,6 +1235,12 @@
           }
         }
       }
+      else
+      {
+        // The relation entry does not exist so check for and deregister
+        // delayed add listener.
+        deregisterDelayedAddListener(baseDN, listener);
+      }
     } catch (ConfigException e) {
       // Ignore the exception since this implies deregistration.
       if (debugEnabled()) {
@@ -1261,6 +1267,12 @@
           }
         }
       }
+      else
+      {
+        // The relation entry does not exist so check for and deregister
+        // delayed add listener.
+        deregisterDelayedAddListener(baseDN, listener);
+      }
     } catch (ConfigException e) {
       // Ignore the exception since this implies deregistration.
       if (debugEnabled()) {
@@ -1293,6 +1305,12 @@
           }
         }
       }
+      else
+      {
+        // The relation entry does not exist so check for and deregister
+        // delayed add listener.
+        deregisterDelayedDeleteListener(baseDN, listener);
+      }
     } catch (ConfigException e) {
       // Ignore the exception since this implies deregistration.
       if (debugEnabled()) {
@@ -1319,6 +1337,12 @@
           }
         }
       }
+      else
+      {
+        // The relation entry does not exist so check for and deregister
+        // delayed add listener.
+        deregisterDelayedDeleteListener(baseDN, listener);
+      }
     } catch (ConfigException e) {
       // Ignore the exception since this implies deregistration.
       if (debugEnabled()) {
@@ -1392,6 +1416,257 @@
     throw new ConfigException(message);
   }
 
+  // Deregister a delayed listener with the nearest existing parent
+  // entry to the provided base DN.
+  private <M extends Configuration> void deregisterDelayedAddListener(DN baseDN,
+      ConfigurationAddListener<M> listener) throws ConfigException {
+    DN parentDN = baseDN.getParent();
+    int delayWrappers = 0;
+    while (parentDN != null) {
+      ConfigEntry relationEntry = getListenerConfigEntry(parentDN);
+      if (relationEntry == null) {
+        parentDN = parentDN.getParent();
+        delayWrappers++;
+      } else {
+        for (ConfigAddListener l : relationEntry.getAddListeners()) {
+          if(l instanceof DelayedConfigAddListener)
+          {
+            DelayedConfigAddListener delayListener =
+                (DelayedConfigAddListener) l;
+            ConfigAddListener wrappedListener;
+
+            int i = delayWrappers;
+            for(; i > 0; i--)
+            {
+              wrappedListener = delayListener.getDelayedAddListener();
+              if(wrappedListener != null &&
+                  wrappedListener instanceof DelayedConfigAddListener)
+              {
+                delayListener = (DelayedConfigAddListener) l;
+              }
+              else
+              {
+                break;
+              }
+            }
+
+            if(i > 0)
+            {
+              // There are not enough level of wrapping so this can't be
+              // the listener we are looking for.
+              continue;
+            }
+
+            ConfigAddListener delayedListener =
+                delayListener.getDelayedAddListener();
+
+            if (delayedListener != null &&
+                 delayedListener instanceof ConfigAddListenerAdaptor) {
+              ConfigAddListenerAdaptor<?> adaptor =
+                  (ConfigAddListenerAdaptor<?>) delayedListener;
+              ServerManagedObjectAddListener<?> l2 = adaptor
+                  .getServerManagedObjectAddListener();
+              if (l2 instanceof ServerManagedObjectAddListenerAdaptor<?>) {
+                ServerManagedObjectAddListenerAdaptor<?> adaptor2 =
+                    (ServerManagedObjectAddListenerAdaptor<?>) l2;
+                if (adaptor2.getConfigurationAddListener() == listener) {
+                  relationEntry.deregisterAddListener(l);
+                }
+              }
+            }
+          }
+        }
+        return;
+      }
+    }
+  }
+
+
+  // Deregister a delayed listener with the nearest existing parent
+  // entry to the provided base DN.
+  private <M extends Configuration> void deregisterDelayedDeleteListener(
+      DN baseDN, ConfigurationDeleteListener<M> listener)
+      throws ConfigException {
+    DN parentDN = baseDN.getParent();
+    int delayWrappers = 0;
+    while (parentDN != null) {
+      ConfigEntry relationEntry = getListenerConfigEntry(parentDN);
+      if (relationEntry == null) {
+        parentDN = parentDN.getParent();
+        delayWrappers++;
+      } else {
+        for (ConfigAddListener l : relationEntry.getAddListeners()) {
+          if(l instanceof DelayedConfigAddListener)
+          {
+            DelayedConfigAddListener delayListener =
+                (DelayedConfigAddListener) l;
+            ConfigAddListener wrappedListener;
+
+            int i = delayWrappers;
+            for(; i > 0; i--)
+            {
+              wrappedListener = delayListener.getDelayedAddListener();
+              if(wrappedListener != null &&
+                  wrappedListener instanceof DelayedConfigAddListener)
+              {
+                delayListener = (DelayedConfigAddListener) l;
+              }
+              else
+              {
+                break;
+              }
+            }
+
+            if(i > 0)
+            {
+              // There are not enough level of wrapping so this can't be
+              // the listener we are looking for.
+              continue;
+            }
+
+            ConfigDeleteListener delayedListener =
+                delayListener.getDelayedDeleteListener();
+
+            if (delayedListener != null &&
+                delayedListener instanceof ConfigDeleteListenerAdaptor) {
+              ConfigDeleteListenerAdaptor<?> adaptor =
+                  (ConfigDeleteListenerAdaptor<?>) delayedListener;
+              ServerManagedObjectDeleteListener<?> l2 = adaptor
+                  .getServerManagedObjectDeleteListener();
+              if (l2 instanceof ServerManagedObjectDeleteListenerAdaptor<?>) {
+                ServerManagedObjectDeleteListenerAdaptor<?> adaptor2 =
+                    (ServerManagedObjectDeleteListenerAdaptor<?>) l2;
+                if (adaptor2.getConfigurationDeleteListener() == listener) {
+                  relationEntry.deregisterAddListener(l);
+                }
+              }
+            }
+          }
+        }
+        return;
+      }
+    }
+  }
+
+  // Deregister a delayed listener with the nearest existing parent
+  // entry to the provided base DN.
+  private <M extends Configuration> void deregisterDelayedAddListener(DN baseDN,
+      ServerManagedObjectAddListener<M> listener) throws ConfigException {
+    DN parentDN = baseDN.getParent();
+    int delayWrappers = 0;
+    while (parentDN != null) {
+      ConfigEntry relationEntry = getListenerConfigEntry(parentDN);
+      if (relationEntry == null) {
+        parentDN = parentDN.getParent();
+        delayWrappers++;
+      } else {
+        for (ConfigAddListener l : relationEntry.getAddListeners()) {
+          if(l instanceof DelayedConfigAddListener)
+          {
+            DelayedConfigAddListener delayListener =
+                (DelayedConfigAddListener) l;
+            ConfigAddListener wrappedListener;
+
+            int i = delayWrappers;
+            for(; i > 0; i--)
+            {
+              wrappedListener = delayListener.getDelayedAddListener();
+              if(wrappedListener != null &&
+                  wrappedListener instanceof DelayedConfigAddListener)
+              {
+                delayListener = (DelayedConfigAddListener) l;
+              }
+              else
+              {
+                break;
+              }
+            }
+
+            if(i > 0)
+            {
+              // There are not enough level of wrapping so this can't be
+              // the listener we are looking for.
+              continue;
+            }
+
+            ConfigAddListener delayedListener =
+                delayListener.getDelayedAddListener();
+
+            if (delayedListener != null &&
+                 delayedListener instanceof ConfigAddListenerAdaptor) {
+              ConfigAddListenerAdaptor<?> adaptor =
+                  (ConfigAddListenerAdaptor<?>) delayedListener;
+              if (adaptor.getServerManagedObjectAddListener() == listener) {
+                relationEntry.deregisterAddListener(l);
+              }
+            }
+          }
+        }
+        return;
+      }
+    }
+  }
+
+
+  // Deregister a delayed listener with the nearest existing parent
+  // entry to the provided base DN.
+  private <M extends Configuration> void deregisterDelayedDeleteListener(
+      DN baseDN, ServerManagedObjectDeleteListener<M> listener)
+      throws ConfigException {
+    DN parentDN = baseDN.getParent();
+    int delayWrappers = 0;
+    while (parentDN != null) {
+      ConfigEntry relationEntry = getListenerConfigEntry(parentDN);
+      if (relationEntry == null) {
+        parentDN = parentDN.getParent();
+        delayWrappers++;
+      } else {
+        for (ConfigAddListener l : relationEntry.getAddListeners()) {
+          if(l instanceof DelayedConfigAddListener)
+          {
+            DelayedConfigAddListener delayListener =
+                (DelayedConfigAddListener) l;
+            ConfigAddListener wrappedListener;
+
+            int i = delayWrappers;
+            for(; i > 0; i--)
+            {
+              wrappedListener = delayListener.getDelayedAddListener();
+              if(wrappedListener != null &&
+                  wrappedListener instanceof DelayedConfigAddListener)
+              {
+                delayListener = (DelayedConfigAddListener) l;
+              }
+              else
+              {
+                break;
+              }
+            }
+
+            if(i > 0)
+            {
+              // There are not enough level of wrapping so this can't be
+              // the listener we are looking for.
+              continue;
+            }
+
+            ConfigDeleteListener delayedListener =
+                delayListener.getDelayedDeleteListener();
+
+            if (delayedListener != null &&
+                 delayedListener instanceof ConfigDeleteListenerAdaptor) {
+              ConfigDeleteListenerAdaptor<?> adaptor =
+                  (ConfigDeleteListenerAdaptor<?>) delayedListener;
+              if (adaptor.getServerManagedObjectDeleteListener() == listener) {
+                relationEntry.deregisterAddListener(l);
+              }
+            }
+          }
+        }
+        return;
+      }
+    }
+  }
 
 
   // Register an instantiable or optional relation delete listener.

--
Gitblit v1.10.0