1689N/A/*
1689N/A * CDDL HEADER START
1689N/A *
1689N/A * The contents of this file are subject to the terms of the
1689N/A * Common Development and Distribution License, Version 1.0 only
1689N/A * (the "License"). You may not use this file except in compliance
1689N/A * with the License.
1689N/A *
6983N/A * You can obtain a copy of the license at legal-notices/CDDLv1_0.txt
6983N/A * or http://forgerock.org/license/CDDLv1.0.html.
1689N/A * See the License for the specific language governing permissions
1689N/A * and limitations under the License.
1689N/A *
1689N/A * When distributing Covered Code, include this CDDL HEADER in each
6983N/A * file and include the License file at legal-notices/CDDLv1_0.txt.
6983N/A * If applicable, add the following below this CDDL HEADER, with the
6983N/A * fields enclosed by brackets "[]" replaced with your own identifying
6983N/A * information:
1689N/A * Portions Copyright [yyyy] [name of copyright owner]
1689N/A *
1689N/A * CDDL HEADER END
1689N/A *
1689N/A *
5107N/A * Copyright 2008-2010 Sun Microsystems, Inc.
1689N/A */
1689N/Apackage org.opends.server.core;
1689N/A
1689N/A
4172N/Aimport org.opends.messages.Message;
4172N/Aimport org.opends.messages.MessageBuilder;
3853N/Aimport org.opends.server.core.networkgroups.NetworkGroupNamingContexts;
3352N/Aimport org.opends.server.types.*;
1689N/A
1689N/A
1689N/A/**
1689N/A * This class implements the workflow node that handles the root DSE entry.
1689N/A * As opposed to the WorkflowTopologyNode class, the root DSE node has no
1689N/A * parent node nor subordinate nodes. Instead, the root DSE node has a set
1689N/A * of naming contexts, each of which is a WorkflowTopologyNode object with
1689N/A * no parent.
1689N/A */
1689N/Apublic class RootDseWorkflowTopology extends WorkflowTopology
1689N/A{
1689N/A
1689N/A // The naming contexts known by the root DSE. These naming contexts
1689N/A // are defined in the scope of a network group.
1689N/A private NetworkGroupNamingContexts namingContexts = null;
1689N/A
1689N/A
1689N/A /**
1689N/A * Creates a workflow node to handle the root DSE entry.
1689N/A *
1689N/A * @param workflowImpl the workflow which contains the processing for
1689N/A * the root DSE backend
1689N/A * @param namingContexts the list of naming contexts being registered
1689N/A * with the network group the root DSE belongs to
1689N/A */
1689N/A public RootDseWorkflowTopology(
1689N/A WorkflowImpl workflowImpl,
1689N/A NetworkGroupNamingContexts namingContexts
1689N/A )
1689N/A {
1689N/A super(workflowImpl);
1689N/A this.namingContexts = namingContexts;
1689N/A }
1689N/A
1689N/A
1689N/A /**
1689N/A * Executes an operation on the root DSE entry.
1689N/A *
1689N/A * @param operation the operation to execute
3352N/A *
3352N/A * @throws CanceledOperationException if this operation should
3352N/A * be cancelled.
1689N/A */
3352N/A public void execute(Operation operation)
3352N/A throws CanceledOperationException {
1689N/A // Execute the operation.
1689N/A OperationType operationType = operation.getOperationType();
1689N/A if (operationType != OperationType.SEARCH)
1689N/A {
1689N/A // Execute the operation
1689N/A getWorkflowImpl().execute(operation);
1689N/A }
1689N/A else
1689N/A {
1689N/A // Execute the SEARCH operation
1689N/A executeSearch((SearchOperation) operation);
1689N/A }
1689N/A }
1689N/A
1689N/A
1689N/A /**
1689N/A * Executes a search operation on the the root DSE entry.
1689N/A *
1689N/A * @param searchOp the operation to execute
3352N/A *
3352N/A * @throws CanceledOperationException if this operation should
3352N/A * be cancelled.
1689N/A */
3352N/A private void executeSearch(SearchOperation searchOp)
3352N/A throws CanceledOperationException {
1689N/A // Keep a the original search scope because we will alter it in the
1689N/A // operation.
1689N/A SearchScope originalScope = searchOp.getScope();
1689N/A
1689N/A // Search base?
1689N/A // The root DSE entry itself is never returned unless the operation
1689N/A // is a search base on the null suffix.
1689N/A if (originalScope == SearchScope.BASE_OBJECT)
1689N/A {
1689N/A getWorkflowImpl().execute(searchOp);
1689N/A return;
1689N/A }
1689N/A
1689N/A // Create a workflow result code in case we need to perform search in
1689N/A // subordinate workflows.
1689N/A WorkflowResultCode workflowResultCode = new WorkflowResultCode(
1689N/A searchOp.getResultCode(), searchOp.getErrorMessage());
1689N/A
1689N/A // The search scope is not 'base', so let's do a search on all the public
1689N/A // naming contexts with appropriate new search scope and new base DN.
1689N/A SearchScope newScope = elaborateScopeForSearchInSubordinates(originalScope);
1689N/A searchOp.setScope(newScope);
1689N/A DN originalBaseDN = searchOp.getBaseDN();
1689N/A
5107N/A Iterable<WorkflowTopologyNode> ncToSearch =
5107N/A DirectoryServer.getRootDSEBackend().getSubordinateNamingContexts(
5107N/A namingContexts.getPublicNamingContexts());
5107N/A
5107N/A for (WorkflowTopologyNode namingContext: ncToSearch)
1689N/A {
1689N/A // We have to change the operation request base DN to match the
1689N/A // subordinate workflow base DN. Otherwise the workflow will
1689N/A // return a no such entry result code as the operation request
1689N/A // base DN is a superior of the workflow base DN!
1689N/A DN ncDN = namingContext.getBaseDN();
1689N/A
1689N/A // Set the new request base DN then do execute the operation
1689N/A // in the naming context workflow.
1689N/A searchOp.setBaseDN(ncDN);
1689N/A namingContext.execute(searchOp);
1689N/A boolean sendReferenceEntry =
1689N/A workflowResultCode.elaborateGlobalResultCode(
1689N/A searchOp.getResultCode(), searchOp.getErrorMessage());
1689N/A if (sendReferenceEntry)
1689N/A {
1689N/A // TODO jdemendi - turn a referral result code into a reference entry
1689N/A // and send the reference entry to the client application
1689N/A }
1689N/A }
1689N/A
1689N/A // Now restore the original request base DN and original search scope
1689N/A searchOp.setBaseDN(originalBaseDN);
1689N/A searchOp.setScope(originalScope);
1689N/A
4172N/A // If the result code is still uninitialized (ie no naming context),
4172N/A // we should return NO_SUCH_OBJECT
4172N/A workflowResultCode.elaborateGlobalResultCode(
4172N/A ResultCode.NO_SUCH_OBJECT, new MessageBuilder(Message.EMPTY));
4172N/A
1689N/A // Set the operation result code and error message
1689N/A searchOp.setResultCode(workflowResultCode.resultCode());
1689N/A searchOp.setErrorMessage(workflowResultCode.errorMessage());
1689N/A }
1689N/A
1689N/A
1689N/A /**
1689N/A * Dumps info from the current workflow for debug purpose.
1689N/A *
1689N/A * @param leftMargin white spaces used to indent the traces
1689N/A * @return a string buffer that contains trace information
1689N/A */
2446N/A public StringBuilder toString(String leftMargin)
1689N/A {
2446N/A StringBuilder sb = new StringBuilder();
1689N/A
2800N/A // display the identifier and baseDN
2800N/A String workflowID = this.getWorkflowImpl().getWorkflowId();
2800N/A sb.append(leftMargin + "Workflow ID = " + workflowID + "\n");
2800N/A sb.append(leftMargin + " baseDN:[ \"\" ]\n");
1689N/A
1689N/A return sb;
1689N/A }
1689N/A
1689N/A}