From 0e47fcf59332b96c43f4737143025e07f8202638 Mon Sep 17 00:00:00 2001
From: jdemendi <jdemendi@localhost>
Date: Fri, 31 Oct 2008 11:12:52 +0000
Subject: [PATCH] fix 35353, Workflows are not notified when their root workflow elements are disabled
---
opends/src/server/org/opends/server/workflowelement/WorkflowElement.java | 184 +++++++++++++++++++++++++++++++++++++++++++++
1 files changed, 182 insertions(+), 2 deletions(-)
diff --git a/opends/src/server/org/opends/server/workflowelement/WorkflowElement.java b/opends/src/server/org/opends/server/workflowelement/WorkflowElement.java
index 7b8a29b..80eaff5 100644
--- a/opends/src/server/org/opends/server/workflowelement/WorkflowElement.java
+++ b/opends/src/server/org/opends/server/workflowelement/WorkflowElement.java
@@ -27,7 +27,13 @@
package org.opends.server.workflowelement;
+import java.util.ArrayList;
import java.util.List;
+import java.util.Observable;
+import java.util.Observer;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentMap;
+
import org.opends.server.admin.std.server.WorkflowElementCfg;
import org.opends.server.types.Operation;
import org.opends.server.types.CanceledOperationException;
@@ -44,8 +50,8 @@
*
* @param <T> The type of configuration handled by this workflow element.
*/
-public abstract class WorkflowElement
- <T extends WorkflowElementCfg>
+public abstract class WorkflowElement <T extends WorkflowElementCfg>
+ implements Observer
{
// Indicates whether the workflow element encapsulates a private local
// backend.
@@ -61,6 +67,170 @@
private String workflowElementID = null;
+ // The observable state of the workflow element.
+ private ObservableWorkflowElementState observableState =
+ new ObservableWorkflowElementState(this);
+
+
+ // The list of observers who want to be notified when a workflow element
+ // required by the observer is created. The key of the map is a string
+ // that identifies the newly created workflow element.
+ private static ConcurrentMap<String, List<Observer>>
+ newWorkflowElementNotificationList =
+ new ConcurrentHashMap<String, List<Observer>>();
+
+
+ /**
+ * Provides the observable state of the workflow element.
+ * This method is intended to be called by the WorkflowElementConfigManager
+ * that wants to notify observers that the workflow element state has
+ * changed (in particular when a workflow element has been disabled).
+ *
+ * @return the observable state of the workflow element
+ */
+ protected ObservableWorkflowElementState getObservableState()
+ {
+ return observableState;
+ }
+
+
+ /**
+ * Registers with a specific workflow element to be notified when the
+ * workflow element state has changed. This notification system is
+ * mainly used to be warned when a workflow element is enabled or
+ * disabled.
+ * <p>
+ * If the workflow element <code>we</code> is not <code>null</code>
+ * then the <code>observer</code> is registered with the list of objects
+ * to notify when <code>we</code> has changed.
+ * <p>
+ * If the workflow element <code>we</code> is <code>null</code> then
+ * the <code>observer</code> is registered with a static list of objects
+ * to notify when a workflow element named <code>weid</code> is created.
+ *
+ * @param we the workflow element. If <code>null</code> then observer
+ * is registered with a list of workflow element
+ * identifiers.
+ * @param weid the identifier of the workflow element. This parameter
+ * is useless when <code>we</code> is not <code>null</code>
+ * @param observer the observer to notify when the workflow element state
+ * has been modified
+ */
+ public static void registereForStateUpdate(
+ WorkflowElement<?> we,
+ String weid,
+ Observer observer
+ )
+ {
+ // If the workflow element "we" exists then register the observer with "we"
+ // else register the observer with a static list of workflow element
+ // identifiers
+ if (we != null)
+ {
+ ObservableWorkflowElementState westate = we.getObservableState();
+ westate.addObserver(observer);
+ }
+ else
+ {
+ if (weid == null)
+ {
+ return;
+ }
+
+ List<Observer> observers = newWorkflowElementNotificationList.get(weid);
+ if (observers == null)
+ {
+ // create the list of observers
+ observers = new ArrayList<Observer>();
+ observers.add(observer);
+ newWorkflowElementNotificationList.put(weid, observers);
+ }
+ else
+ {
+ // update the observer list
+ observers.add(observer);
+ }
+ }
+ }
+
+
+ /**
+ * Deregisters an observer that was registered with a specific workflow
+ * element.
+ * <p>
+ * If the workflow element <code>we</code> is not <code>null</code>
+ * then the <code>observer</code> is deregistered with the list of objects
+ * to notify when <code>we</code> has changed.
+ * <p>
+ * If the workflow element <code>we</code> is <code>null</code> then
+ * the <code>observer</code> is deregistered with a static list of objects
+ * to notify when a workflow element named <code>weid</code> is created.
+ *
+ * @param we the workflow element. If <code>null</code> then observer
+ * is deregistered with a list of workflow element
+ * identifiers.
+ * @param weid the identifier of the workflow element. This parameter
+ * is useless when <code>we</code> is not <code>null</code>
+ * @param observer the observer to deregister
+ */
+ public static void deregistereForStateUpdate(
+ WorkflowElement<?> we,
+ String weid,
+ Observer observer
+ )
+ {
+ // If the workflow element "we" exists then deregister the observer
+ // with "we" else deregister the observer with a static list of
+ // workflow element identifiers
+ if (we != null)
+ {
+ ObservableWorkflowElementState westate = we.getObservableState();
+ westate.deleteObserver(observer);
+ }
+ else
+ {
+ List<Observer> observers = newWorkflowElementNotificationList.get(weid);
+ if (observers != null)
+ {
+ observers.remove(observer);
+ }
+ }
+ }
+
+
+ /**
+ * Notifies all the observers who want to be warn when a workflow element
+ * is created.
+ *
+ * @param workflowElement the newly created workflow element
+ */
+ public static void notifyStateUpdate(
+ WorkflowElement<?> workflowElement)
+ {
+ // Go through the list of observers and notify them all
+ String weID = workflowElement.getWorkflowElementID();
+
+ List<Observer> observers = newWorkflowElementNotificationList.get(weID);
+ if (observers != null)
+ {
+ for (Observer observer: observers)
+ {
+ // The update might fail because an observer could have been
+ // terminated. In this case, just ignore the failure and remove
+ // the observer from the list of objects to notify.
+ try
+ {
+ observer.update(workflowElement.getObservableState(), null);
+ }
+ catch(Exception e)
+ {
+ observers.remove(observer);
+ }
+ }
+ }
+ }
+
+
/**
* Creates a new instance of the workflow element.
*/
@@ -69,6 +239,7 @@
// There is nothing to do in the constructor.
}
+
/**
* Initializes the instance of the workflow element.
*
@@ -89,6 +260,15 @@
/**
+ * {@inheritDoc}
+ */
+ public void update(Observable o, Object arg)
+ {
+ // By default, do nothing when notification hits the workflow element.
+ }
+
+
+ /**
* Get the type of the workflow element. The type is a string information
* indicating which type is the current workflow element. This information
* is intended to be used by tools for trace and debug purpose.
--
Gitblit v1.10.0