/* * CDDL HEADER START * * The contents of this file are subject to the terms of the * Common Development and Distribution License, Version 1.0 only * (the "License"). You may not use this file except in compliance * with the License. * * You can obtain a copy of the license at legal-notices/CDDLv1_0.txt * or http://forgerock.org/license/CDDLv1.0.html. * See the License for the specific language governing permissions * and limitations under the License. * * When distributing Covered Code, include this CDDL HEADER in each * file and include the License file at legal-notices/CDDLv1_0.txt. * If applicable, add the following below this CDDL HEADER, with the * fields enclosed by brackets "[]" replaced with your own identifying * information: * Portions Copyright [yyyy] [name of copyright owner] * * CDDL HEADER END * * * Copyright 2008-2010 Sun Microsystems, Inc. * Portions copyright 2013-2014 ForgeRock AS. */ package org.opends.server.workflowelement; import java.util.List; import java.util.Observable; import java.util.Observer; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentMap; import java.util.concurrent.CopyOnWriteArrayList; import org.opends.server.admin.std.server.WorkflowElementCfg; import org.opends.server.types.CanceledOperationException; import org.opends.server.types.Operation; /** * This class defines the super class for all the workflow elements. A workflow * element is a task in a workflow. A workflow element can wrap a physical * repository such as a local backend, a remote LDAP server or a local LDIF * file. A workflow element can also be used to route operations. This is the * case for load balancing and distribution. And workflow element can be used * in a virtual environment to transform data (DN and attribute renaming, * attribute value renaming...). * * @param The type of configuration handled by this workflow element. */ public abstract class WorkflowElement implements Observer { /** 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> newWorkflowElementNotificationList = new ConcurrentHashMap>(); /** * 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 final 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. *

* If the workflow element we is not null * then the observer is registered with the list of objects * to notify when we has changed. *

* If the workflow element we is null then * the observer is registered with a static list of objects * to notify when a workflow element named weid is created. * * @param we the workflow element. If null then observer * is registered with a list of workflow element * identifiers. * @param weid the identifier of the workflow element. This parameter * is useless when we is not null * @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 observers = newWorkflowElementNotificationList.get(weid); if (observers == null) { // create the list of observers observers = new CopyOnWriteArrayList(); 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. *

* If the workflow element we is not null * then the observer is deregistered with the list of objects * to notify when we has changed. *

* If the workflow element we is null then * the observer is deregistered with a static list of objects * to notify when a workflow element named weid is created. * * @param we the workflow element. If null then observer * is deregistered with a list of workflow element * identifiers. * @param weid the identifier of the workflow element. This parameter * is useless when we is not null * @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); } if (weid != null) { List observers = newWorkflowElementNotificationList.get(weid); if (observers != null) { observers.remove(observer); } } } /** {@inheritDoc} */ @Override public final void update(Observable o, Object arg) { // By default, do nothing when notification hits the workflow element. } /** * Indicates whether the provided configuration is acceptable for * this workflow element. * * @param configuration The workflow element configuration for * which to make the determination. * @param unacceptableReasons A list that may be used to hold the * reasons that the provided * configuration is not acceptable. * * @return {@code true} if the provided configuration is acceptable * for this workflow element, or {@code false} if not. */ public final boolean isConfigurationAcceptable( T configuration, List unacceptableReasons) { // This default implementation does not perform any special // validation. It should be overridden by workflow element // implementations that wish to perform more detailed validation. return true; } /** * Performs any finalization that might be required when this * workflow element is unloaded. No action is taken in the default * implementation. */ public abstract void finalizeWorkflowElement(); /** * Executes the workflow element for an operation. * * @param operation the operation to execute * * @throws CanceledOperationException if this operation should be * canceled */ public abstract void execute(Operation operation) throws CanceledOperationException; /** * Indicates whether the workflow element encapsulates a private * local backend. * * @return true if the workflow element encapsulates a private * local backend, false otherwise */ public abstract boolean isPrivate(); /** * Provides the workflow element identifier. * * @return the workflow element identifier */ public abstract String getWorkflowElementID(); }