001 /*
002 * CDDL HEADER START
003 *
004 * The contents of this file are subject to the terms of the
005 * Common Development and Distribution License, Version 1.0 only
006 * (the "License"). You may not use this file except in compliance
007 * with the License.
008 *
009 * You can obtain a copy of the license at
010 * trunk/opends/resource/legal-notices/OpenDS.LICENSE
011 * or https://OpenDS.dev.java.net/OpenDS.LICENSE.
012 * See the License for the specific language governing permissions
013 * and limitations under the License.
014 *
015 * When distributing Covered Code, include this CDDL HEADER in each
016 * file and include the License file at
017 * trunk/opends/resource/legal-notices/OpenDS.LICENSE. If applicable,
018 * add the following below this CDDL HEADER, with the fields enclosed
019 * by brackets "[]" replaced with your own identifying information:
020 * Portions Copyright [yyyy] [name of copyright owner]
021 *
022 * CDDL HEADER END
023 *
024 *
025 * Copyright 2008 Sun Microsystems, Inc.
026 */
027 package org.opends.server.core;
028 import org.opends.messages.Message;
029 import org.opends.messages.MessageBuilder;
030
031
032 import org.opends.server.types.ResultCode;
033
034
035 /**
036 * This class implements the workflow result code. The workflow result code
037 * contains an LDAP result code along with an LDAP error message.
038 */
039 public class WorkflowResultCode
040 {
041 // The global result code.
042 private ResultCode resultCode = ResultCode.UNDEFINED;
043
044 // The global error message.
045 private MessageBuilder errorMessage = new MessageBuilder(Message.EMPTY);
046
047
048 /**
049 * Creates a new instance of a workflow result. By default the result code
050 * is set to UNDEFINED and there is no error message.
051 */
052 public WorkflowResultCode()
053 {
054 // Nothing to implement.
055 }
056
057
058 /**
059 * Creates a new instance of a workflow result code and initializes it
060 * with a result code and an error message.
061 *
062 * @param resultCode the initial value for the result code
063 * @param errorMessage the initial value for the error message
064 */
065 public WorkflowResultCode(
066 ResultCode resultCode,
067 MessageBuilder errorMessage
068 )
069 {
070 this.resultCode = resultCode;
071 this.errorMessage = errorMessage;
072 }
073
074
075 /**
076 * Elaborates a global result code. A workflow may execute an operation
077 * on several subordinate workflows. In such case, the parent workflow
078 * has to take into account all the subordinate result codes to elaborate
079 * a global result code.
080 *
081 * Sometimes, a referral result code has to be turned into a reference
082 * entry. When such case is occurring the elaborateGlobalResultCode method
083 * will return true.
084 *
085 * The global result code is elaborated as follows:
086 *
087 * <PRE>
088 * -----------+------------+------------+-------------------------------
089 * new | current | resulting |
090 * resultCode | resultCode | resultCode | action
091 * -----------+------------+------------+-------------------------------
092 * SUCCESS NO_SUCH_OBJ SUCCESS -
093 * REFERRAL SUCCESS send reference entry to client
094 * other [unchanged] -
095 * ---------------------------------------------------------------------
096 * NO_SUCH_OBJ SUCCESS [unchanged] -
097 * REFERRAL [unchanged] -
098 * other [unchanged] -
099 * ---------------------------------------------------------------------
100 * REFERRAL SUCCESS [unchanged] send reference entry to client
101 * REFERRAL SUCCESS send reference entry to client
102 * NO_SUCH_OBJ REFERRAL -
103 * other [unchanged] send reference entry to client
104 * ---------------------------------------------------------------------
105 * others SUCCESS other -
106 * REFERRAL other send reference entry to client
107 * NO_SUCH_OBJ other -
108 * other2 [unchanged] -
109 * ---------------------------------------------------------------------
110 * </PRE>
111 *
112 * @param newResultCode the new result code to take into account
113 * @param newErrorMessage the new error message associated to the new
114 * error code
115 * @return <code>true</code> if a referral result code must be turned
116 * into a reference entry
117 */
118 public boolean elaborateGlobalResultCode(
119 ResultCode newResultCode,
120 MessageBuilder newErrorMessage
121 )
122 {
123 // Returned value
124 boolean sendReferenceEntry = false;
125
126 // if global result code has not been set yet then just take the new
127 // result code as is
128 if (resultCode == ResultCode.UNDEFINED)
129 {
130 resultCode = newResultCode;
131 errorMessage = new MessageBuilder (newErrorMessage);
132 }
133 else
134 {
135 // Elaborate the new result code (see table in the description header).
136
137 switch (newResultCode)
138 {
139 case SUCCESS:
140 //
141 // Received SUCCESS
142 // ----------------
143 //
144 switch (resultCode)
145 {
146 case NO_SUCH_OBJECT:
147 resultCode = ResultCode.SUCCESS;
148 errorMessage = new MessageBuilder(Message.EMPTY);
149 break;
150 case REFERRAL:
151 resultCode = ResultCode.SUCCESS;
152 errorMessage = new MessageBuilder(Message.EMPTY);
153 sendReferenceEntry = true;
154 break;
155 default:
156 // global resultCode remains the same
157 break;
158 }
159 break;
160 case NO_SUCH_OBJECT:
161 //
162 // Received NO SUCH OBJECT
163 // -----------------------
164 //
165 // global resultCode remains the same
166 break;
167 case REFERRAL:
168 //
169 // Received REFERRAL
170 // -----------------
171 //
172 switch (resultCode)
173 {
174 case REFERRAL:
175 resultCode = ResultCode.SUCCESS;
176 errorMessage = new MessageBuilder(Message.EMPTY);
177 sendReferenceEntry = true;
178 break;
179 case NO_SUCH_OBJECT:
180 resultCode = ResultCode.REFERRAL;
181 errorMessage = new MessageBuilder (Message.EMPTY);
182 break;
183 default:
184 // global resultCode remains the same
185 sendReferenceEntry = true;
186 break;
187 }
188 break;
189 default:
190 //
191 // Received other result codes
192 // ---------------------------
193 //
194 switch (resultCode)
195 {
196 case REFERRAL:
197 resultCode = newResultCode;
198 errorMessage = new MessageBuilder (newErrorMessage);
199 sendReferenceEntry = true;
200 break;
201 case SUCCESS:
202 resultCode = newResultCode;
203 errorMessage = new MessageBuilder (newErrorMessage);
204 break;
205 case NO_SUCH_OBJECT:
206 resultCode = newResultCode;
207 errorMessage = new MessageBuilder (newErrorMessage);
208 break;
209 default:
210 // global resultCode remains the same but append the new
211 // error message into the current error message
212 if (errorMessage == null)
213 {
214 errorMessage = new MessageBuilder (newErrorMessage);
215 }
216 else
217 {
218 errorMessage.append(newErrorMessage);
219 }
220 break;
221 }
222 break;
223 }
224 }
225
226 return sendReferenceEntry;
227 }
228
229
230 /**
231 * Returns the global result code.
232 *
233 * @return the global result code.
234 */
235 public ResultCode resultCode()
236 {
237 return resultCode;
238 }
239
240
241 /**
242 * Returns the global error message.
243 *
244 * @return the global error message.
245 */
246 public MessageBuilder errorMessage()
247 {
248 return errorMessage;
249 }
250
251 }