opends/src/server/org/opends/server/core/SearchOperationWrapper.java
@@ -41,12 +41,13 @@ import org.opends.server.types.SearchResultEntry; import org.opends.server.types.SearchResultReference; import org.opends.server.types.SearchScope; import org.opends.server.workflowelement.WorkflowElement; /** * This abstract class wraps/decorates a given search operation. * This class will be extended by sub-classes to enhance the * functionnality of the SearchOperationBasis. * functionality of the SearchOperationBasis. */ public abstract class SearchOperationWrapper extends OperationWrapper implements SearchOperation @@ -54,6 +55,24 @@ // The wrapped operation. private SearchOperation search; // The workflow element which has invoked the current operation. // The returned entries and returned references must be sent to that // workflow element. private WorkflowElement<?> callingWorkflowElement = null; /** * Set the calling workflow element. * * @param callingWorkflowElement the workflow element which has invoked * the current operation */ public void setCallingWorkflowElement( WorkflowElement<?> callingWorkflowElement ) { this.callingWorkflowElement = callingWorkflowElement; } /** * Creates a new search operation based on the provided search operation. * @@ -70,7 +89,24 @@ */ public boolean returnEntry(Entry entry, List<Control> controls) { return search.returnEntry(entry, controls); boolean result; // If the calling workflow element is defined then send the return // entry to the workflow element, otherwise send the entry to the // calling operation. // Sometimes, the calling workflow element might not be set for // an internal operation because the internal search is done using // a local backend operation instead of an operation basis. if (callingWorkflowElement != null) { result = callingWorkflowElement.returnEntry(entry, controls); } else { result = this.search.returnEntry(entry, controls); } return result; } /** @@ -78,7 +114,23 @@ */ public boolean returnReference(DN dn, SearchResultReference reference) { return search.returnReference(dn, reference); boolean result; // If the calling workflow element is not set then send the // reference to the calling operation, otherwise send the reference // to the calling workflow element. // an internal operation because the internal search is done using // a local backend operation instead of an operation basis. if (callingWorkflowElement != null) { result = callingWorkflowElement.returnReference(dn, reference); } else { result = this.search.returnReference(dn, reference); } return result; } /** opends/src/server/org/opends/server/workflowelement/WorkflowElement.java
@@ -35,7 +35,12 @@ import org.opends.messages.Message; import org.opends.server.admin.std.server.WorkflowElementCfg; import org.opends.server.config.ConfigException; import org.opends.server.core.SearchOperationBasis; import org.opends.server.types.Control; import org.opends.server.types.DN; import org.opends.server.types.Entry; import org.opends.server.types.Operation; import org.opends.server.types.SearchResultReference; /** @@ -71,6 +76,18 @@ private static Object registeredWorkflowElementsLock = new Object(); // The original operation basis which has invoked the workflow. // This original operation basis is only useful for the search // operation, for the returned entry and returned reference to be // processed before they are sent back to the client application. private Operation originalOperationBasis = null; // The parent of the workflow element (null if the workflow element is // the root of the processing tree). private WorkflowElement<?> parent = null; /** * Creates a new instance of the workflow element. */ @@ -80,7 +97,6 @@ } /** * Initializes the instance of the workflow element. * @@ -93,6 +109,27 @@ } /** * Set the original operation basis which has invoked the workflow. * * @param operation the operation basis which has invoked the workflow */ protected void setOriginalOperationBasis(Operation operation) { this.originalOperationBasis = operation; } /** * Set the parent of the current workflow element. * * @param parent the parent of the workflow element */ protected void setParent(WorkflowElement<?> parent) { this.parent = parent; } /** * Indicates whether the provided configuration is acceptable for @@ -137,7 +174,6 @@ public abstract void execute(Operation operation); /** * Indicates whether the workflow element encapsulates a private * local backend. @@ -151,7 +187,6 @@ } /** * Specifies whether the workflow element encapsulates a private local * backend. @@ -165,7 +200,6 @@ } /** * Provides the workflow element identifier. * @@ -248,5 +282,83 @@ } } /** * Used as a callback for workflow elements to indicate that the provided * entry matches the search criteria and that additional processing should * be performed to potentially send it back to the client. * * @param entry The entry that matches the search criteria and should be * sent to the client. * @param controls The set of controls to include with the entry (may be * <CODE>null</CODE> if none are needed). * * @return <CODE>true</CODE> if the caller should continue processing the * search request and sending additional entries and references, or * <CODE>false</CODE> if not for some reason (e.g., the size limit * has been reached or the search has been abandoned). */ public boolean returnEntry( Entry entry, List<Control> controls) { boolean result; // If the workflow element has a parent then send the entry // to the parent, otherwise send the entry to the operation // basis. The operation basis will be in charge of sending // the entry to the client application. if (parent == null) { SearchOperationBasis searchOperationBasis = (SearchOperationBasis) originalOperationBasis; result = searchOperationBasis.returnEntry(entry, controls); } else { result = parent.returnEntry(entry, controls); } return result; } /** * Used as a callback for workflow elements to indicate that the provided * search reference was encountered during processing and that additional * processing should be performed to potentially send it back to the client. * * @param reference The search reference to send to the client. * @param dn The DN related to the specified search reference. * * @return <CODE>true</CODE> if the caller should continue processing the * search request and sending additional entries and references , or * <CODE>false</CODE> if not for some reason (e.g., the size limit * has been reached or the search has been abandoned). */ public boolean returnReference( DN dn, SearchResultReference reference) { boolean result; // If the workflow element has a parent then send the reference // to the parent, otherwise send the reference to the operation // basis. The operation basis will be in charge of sending // the reference to the client application. if (parent == null) { SearchOperationBasis searchOperationBasis = (SearchOperationBasis) originalOperationBasis; result = searchOperationBasis.returnReference(dn, reference); } else { result = parent.returnReference(dn, reference); } return result; } } opends/src/server/org/opends/server/workflowelement/localbackend/LocalBackendWorkflowElement.java
@@ -46,9 +46,13 @@ import org.opends.server.core.ModifyOperation; import org.opends.server.core.SearchOperation; import org.opends.server.types.ConfigChangeResult; import org.opends.server.types.Control; import org.opends.server.types.DN; import org.opends.server.types.Entry; import org.opends.server.types.InitializationException; import org.opends.server.types.Operation; import org.opends.server.types.ResultCode; import org.opends.server.types.SearchResultReference; import org.opends.server.workflowelement.LeafWorkflowElement; @@ -348,8 +352,15 @@ break; case SEARCH: // First of all store the original operation basis so that returned // entries can be sent to it later on setOriginalOperationBasis(operation); LocalBackendSearchOperation searchOperation = new LocalBackendSearchOperation((SearchOperation) operation); // Set the calling workflow element so that returnEntry and // returnReference callbacks can be invoked later on. searchOperation.setCallingWorkflowElement(this); searchOperation.processLocalSearch(backend); break; @@ -427,5 +438,45 @@ globalOperation.setAttachment(Operation.LOCALBACKENDOPERATIONS, newAttachment); } /** * {@inheritDoc} */ public boolean returnEntry( Entry entry, List<Control> controls) { boolean result; // There is no specific processing to perform on the returned entry. // Just let the superclass execute the generic processing on the // returned entry. result = super.returnEntry(entry, controls); return result; } /** * {@inheritDoc} */ public boolean returnReference( DN dn, SearchResultReference reference) { boolean result; // There is no specific processing to perform on the returned reference. // Just let the superclass execute the generic processing on the // returned reference. result = super.returnReference(dn, reference); return result; } }