/* * 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 * trunk/opends/resource/legal-notices/OpenDS.LICENSE * or https://OpenDS.dev.java.net/OpenDS.LICENSE. * 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 * trunk/opends/resource/legal-notices/OpenDS.LICENSE. 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 Sun Microsystems, Inc. */ package org.opends.server.core; import org.opends.messages.Message; import org.opends.messages.MessageBuilder; import org.opends.server.types.ResultCode; /** * This class implements the workflow result code. The workflow result code * contains an LDAP result code along with an LDAP error message. */ public class WorkflowResultCode { // The global result code. private ResultCode resultCode = ResultCode.UNDEFINED; // The global error message. private MessageBuilder errorMessage = new MessageBuilder(Message.EMPTY); /** * Creates a new instance of a workflow result. By default the result code * is set to UNDEFINED and there is no error message. */ public WorkflowResultCode() { // Nothing to implement. } /** * Creates a new instance of a workflow result code and initializes it * with a result code and an error message. * * @param resultCode the initial value for the result code * @param errorMessage the initial value for the error message */ public WorkflowResultCode( ResultCode resultCode, MessageBuilder errorMessage ) { this.resultCode = resultCode; this.errorMessage = errorMessage; } /** * Elaborates a global result code. A workflow may execute an operation * on several subordinate workflows. In such case, the parent workflow * has to take into account all the subordinate result codes to elaborate * a global result code. * * Sometimes, a referral result code has to be turned into a reference * entry. When such case is occurring the elaborateGlobalResultCode method * will return true. * * The global result code is elaborated as follows: * * <PRE> * -----------+------------+------------+------------------------------- * new | current | resulting | * resultCode | resultCode | resultCode | action * -----------+------------+------------+------------------------------- * SUCCESS NO_SUCH_OBJ SUCCESS - * REFERRAL SUCCESS send reference entry to client * other [unchanged] - * --------------------------------------------------------------------- * NO_SUCH_OBJ SUCCESS [unchanged] - * REFERRAL [unchanged] - * other [unchanged] - * --------------------------------------------------------------------- * REFERRAL SUCCESS [unchanged] send reference entry to client * REFERRAL SUCCESS send reference entry to client * NO_SUCH_OBJ REFERRAL - * other [unchanged] send reference entry to client * --------------------------------------------------------------------- * others SUCCESS other - * REFERRAL other send reference entry to client * NO_SUCH_OBJ other - * other2 [unchanged] - * --------------------------------------------------------------------- * </PRE> * * @param newResultCode the new result code to take into account * @param newErrorMessage the new error message associated to the new * error code * @return <code>true</code> if a referral result code must be turned * into a reference entry */ public boolean elaborateGlobalResultCode( ResultCode newResultCode, MessageBuilder newErrorMessage ) { // Returned value boolean sendReferenceEntry = false; // if global result code has not been set yet then just take the new // result code as is if (resultCode == ResultCode.UNDEFINED) { resultCode = newResultCode; errorMessage = new MessageBuilder (newErrorMessage); } else { // Elaborate the new result code (see table in the description header). switch (newResultCode) { case SUCCESS: // // Received SUCCESS // ---------------- // switch (resultCode) { case NO_SUCH_OBJECT: resultCode = ResultCode.SUCCESS; errorMessage = new MessageBuilder(Message.EMPTY); break; case REFERRAL: resultCode = ResultCode.SUCCESS; errorMessage = new MessageBuilder(Message.EMPTY); sendReferenceEntry = true; break; default: // global resultCode remains the same break; } break; case NO_SUCH_OBJECT: // // Received NO SUCH OBJECT // ----------------------- // // global resultCode remains the same break; case REFERRAL: // // Received REFERRAL // ----------------- // switch (resultCode) { case REFERRAL: resultCode = ResultCode.SUCCESS; errorMessage = new MessageBuilder(Message.EMPTY); sendReferenceEntry = true; break; case NO_SUCH_OBJECT: resultCode = ResultCode.REFERRAL; errorMessage = new MessageBuilder (Message.EMPTY); break; default: // global resultCode remains the same sendReferenceEntry = true; break; } break; default: // // Received other result codes // --------------------------- // switch (resultCode) { case REFERRAL: resultCode = newResultCode; errorMessage = new MessageBuilder (newErrorMessage); sendReferenceEntry = true; break; case SUCCESS: resultCode = newResultCode; errorMessage = new MessageBuilder (newErrorMessage); break; case NO_SUCH_OBJECT: resultCode = newResultCode; errorMessage = new MessageBuilder (newErrorMessage); break; default: // Do nothing (we don't want to override the first error) break; } break; } } return sendReferenceEntry; } /** * Returns the global result code. * * @return the global result code. */ public ResultCode resultCode() { return resultCode; } /** * Returns the global error message. * * @return the global error message. */ public MessageBuilder errorMessage() { return errorMessage; } }