/*
* 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;
}
}