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 2006-2008 Sun Microsystems, Inc.
026 */
027 package org.opends.server.protocols.ldap;
028 import org.opends.messages.Message;
029
030
031
032 import java.util.ArrayList;
033 import java.util.Iterator;
034 import java.util.List;
035
036 import org.opends.server.protocols.asn1.ASN1Element;
037 import org.opends.server.protocols.asn1.ASN1Enumerated;
038 import org.opends.server.protocols.asn1.ASN1OctetString;
039 import org.opends.server.protocols.asn1.ASN1Sequence;
040 import org.opends.server.types.DebugLogLevel;
041 import org.opends.server.types.DN;
042 import org.opends.server.types.LDAPException;
043
044 import static org.opends.server.loggers.debug.DebugLogger.*;
045 import org.opends.server.loggers.debug.DebugTracer;
046 import static org.opends.messages.ProtocolMessages.*;
047 import static org.opends.server.protocols.ldap.LDAPConstants.*;
048 import static org.opends.server.protocols.ldap.LDAPResultCode.*;
049 import static org.opends.server.util.ServerConstants.*;
050
051
052
053 /**
054 * This class defines the structures and methods for an LDAP add response
055 * protocol op, which is used to provide information about the result of
056 * processing an add request.
057 */
058 public class AddResponseProtocolOp
059 extends ProtocolOp
060 {
061 /**
062 * The tracer object for the debug logger.
063 */
064 private static final DebugTracer TRACER = getTracer();
065
066 // The matched DN for this response.
067 private DN matchedDN;
068
069 // The result code for this response.
070 private int resultCode;
071
072 // The set of referral URLs for this response.
073 private List<String> referralURLs;
074
075 // The error message for this response.
076 private Message errorMessage;
077
078
079
080 /**
081 * Creates a new add response protocol op with the provided result code.
082 *
083 * @param resultCode The result code for this response.
084 */
085 public AddResponseProtocolOp(int resultCode)
086 {
087 this.resultCode = resultCode;
088
089 errorMessage = null;
090 matchedDN = null;
091 referralURLs = null;
092 }
093
094
095
096 /**
097 * Creates a new add response protocol op with the provided result code and
098 * error message.
099 *
100 * @param resultCode The result code for this response.
101 * @param errorMessage The error message for this response.
102 */
103 public AddResponseProtocolOp(int resultCode, Message errorMessage)
104 {
105 this.resultCode = resultCode;
106 this.errorMessage = errorMessage;
107
108 matchedDN = null;
109 referralURLs = null;
110 }
111
112
113
114 /**
115 * Creates a new add response protocol op with the provided information.
116 *
117 * @param resultCode The result code for this response.
118 * @param errorMessage The error message for this response.
119 * @param matchedDN The matched DN for this response.
120 * @param referralURLs The referral URLs for this response.
121 */
122 public AddResponseProtocolOp(int resultCode, Message errorMessage,
123 DN matchedDN, List<String> referralURLs)
124 {
125 this.resultCode = resultCode;
126 this.errorMessage = errorMessage;
127 this.matchedDN = matchedDN;
128 this.referralURLs = referralURLs;
129 }
130
131
132
133 /**
134 * Retrieves the result code for this response.
135 *
136 * @return The result code for this response.
137 */
138 public int getResultCode()
139 {
140 return resultCode;
141 }
142
143
144
145 /**
146 * Specifies the result code for this response.
147 *
148 * @param resultCode The result code for this response.
149 */
150 public void setResultCode(int resultCode)
151 {
152 this.resultCode = resultCode;
153 }
154
155
156
157 /**
158 * Retrieves the error message for this response.
159 *
160 * @return The error message for this response, or <CODE>null</CODE> if none
161 * is available.
162 */
163 public Message getErrorMessage()
164 {
165 return errorMessage;
166 }
167
168
169
170 /**
171 * Specifies the error message for this response.
172 *
173 * @param errorMessage The error message for this response.
174 */
175 public void setErrorMessage(Message errorMessage)
176 {
177 this.errorMessage = errorMessage;
178 }
179
180
181
182 /**
183 * Retrieves the matched DN for this response.
184 *
185 * @return The matched DN for this response, or <CODE>null</CODE> if none is
186 * available.
187 */
188 public DN getMatchedDN()
189 {
190 return matchedDN;
191 }
192
193
194
195 /**
196 * Specifies the matched DN for this response.
197 *
198 * @param matchedDN The matched DN for this response.
199 */
200 public void setMatchedDN(DN matchedDN)
201 {
202 this.matchedDN = matchedDN;
203 }
204
205
206
207 /**
208 * Retrieves the set of referral URLs for this response.
209 *
210 * @return The set of referral URLs for this response, or <CODE>null</CODE>
211 * if none are available.
212 */
213 public List<String> getReferralURLs()
214 {
215 return referralURLs;
216 }
217
218
219
220 /**
221 * Specifies the set of referral URLs for this response.
222 *
223 * @param referralURLs The set of referral URLs for this response.
224 */
225 public void setReferralURLs(List<String> referralURLs)
226 {
227 this.referralURLs = referralURLs;
228 }
229
230
231
232 /**
233 * Retrieves the BER type for this protocol op.
234 *
235 * @return The BER type for this protocol op.
236 */
237 public byte getType()
238 {
239 return OP_TYPE_ADD_RESPONSE;
240 }
241
242
243
244 /**
245 * Retrieves the name for this protocol op type.
246 *
247 * @return The name for this protocol op type.
248 */
249 public String getProtocolOpName()
250 {
251 return "Add Response";
252 }
253
254
255
256 /**
257 * Encodes this protocol op to an ASN.1 element suitable for including in an
258 * LDAP message.
259 *
260 * @return The ASN.1 element containing the encoded protocol op.
261 */
262 public ASN1Element encode()
263 {
264 ArrayList<ASN1Element> elements = new ArrayList<ASN1Element>(4);
265 elements.add(new ASN1Enumerated(resultCode));
266
267 if (matchedDN == null)
268 {
269 elements.add(new ASN1OctetString());
270 }
271 else
272 {
273 elements.add(new ASN1OctetString(matchedDN.toString()));
274 }
275
276 elements.add(new ASN1OctetString(errorMessage));
277
278 if ((referralURLs != null) && (! referralURLs.isEmpty()))
279 {
280 ArrayList<ASN1Element> referralElements =
281 new ArrayList<ASN1Element>(referralURLs.size());
282
283 for (String s : referralURLs)
284 {
285 referralElements.add(new ASN1OctetString(s));
286 }
287
288 elements.add(new ASN1Sequence(TYPE_REFERRAL_SEQUENCE, referralElements));
289 }
290
291 return new ASN1Sequence(OP_TYPE_ADD_RESPONSE, elements);
292 }
293
294
295
296 /**
297 * Decodes the provided ASN.1 element as an add response protocol op.
298 *
299 * @param element The ASN.1 element to decode.
300 *
301 * @return The decoded add response protocol op.
302 *
303 * @throws LDAPException If a problem occurs while attempting to decode the
304 * ASN.1 element to a protocol op.
305 */
306 public static AddResponseProtocolOp decodeAddResponse(ASN1Element element)
307 throws LDAPException
308 {
309 ArrayList<ASN1Element> elements;
310 try
311 {
312 elements = element.decodeAsSequence().elements();
313 }
314 catch (Exception e)
315 {
316 if (debugEnabled())
317 {
318 TRACER.debugCaught(DebugLogLevel.ERROR, e);
319 }
320
321 Message message = ERR_LDAP_RESULT_DECODE_SEQUENCE.get(String.valueOf(e));
322 throw new LDAPException(PROTOCOL_ERROR, message, e);
323 }
324
325
326 int numElements = elements.size();
327 if ((numElements < 3) || (numElements > 4))
328 {
329 Message message =
330 ERR_LDAP_RESULT_DECODE_INVALID_ELEMENT_COUNT.get(numElements);
331 throw new LDAPException(PROTOCOL_ERROR, message);
332 }
333
334
335 int resultCode;
336 try
337 {
338 resultCode = elements.get(0).decodeAsInteger().intValue();
339 }
340 catch (Exception e)
341 {
342 if (debugEnabled())
343 {
344 TRACER.debugCaught(DebugLogLevel.ERROR, e);
345 }
346
347 Message message =
348 ERR_LDAP_RESULT_DECODE_RESULT_CODE.get(String.valueOf(e));
349 throw new LDAPException(PROTOCOL_ERROR, message, e);
350 }
351
352
353 DN matchedDN;
354 try
355 {
356 String dnString = elements.get(1).decodeAsOctetString().stringValue();
357 if (dnString.length() == 0)
358 {
359 matchedDN = null;
360 }
361 else
362 {
363 matchedDN = DN.decode(dnString);
364 }
365 }
366 catch (Exception e)
367 {
368 if (debugEnabled())
369 {
370 TRACER.debugCaught(DebugLogLevel.ERROR, e);
371 }
372
373 Message message =
374 ERR_LDAP_RESULT_DECODE_MATCHED_DN.get(String.valueOf(e));
375 throw new LDAPException(PROTOCOL_ERROR, message, e);
376 }
377
378
379 Message errorMessage;
380 try
381 {
382 errorMessage = Message.raw(
383 elements.get(2).decodeAsOctetString().stringValue());
384 if (errorMessage.length() == 0)
385 {
386 errorMessage = null;
387 }
388 }
389 catch (Exception e)
390 {
391 if (debugEnabled())
392 {
393 TRACER.debugCaught(DebugLogLevel.ERROR, e);
394 }
395
396 Message message =
397 ERR_LDAP_RESULT_DECODE_ERROR_MESSAGE.get(String.valueOf(e));
398 throw new LDAPException(PROTOCOL_ERROR, message, e);
399 }
400
401
402 ArrayList<String> referralURLs;
403 if (numElements == 3)
404 {
405 referralURLs = null;
406 }
407 else
408 {
409 try
410 {
411 ArrayList<ASN1Element> referralElements =
412 elements.get(3).decodeAsSequence().elements();
413 referralURLs = new ArrayList<String>(referralElements.size());
414
415 for (ASN1Element e : referralElements)
416 {
417 referralURLs.add(e.decodeAsOctetString().stringValue());
418 }
419 }
420 catch (Exception e)
421 {
422 if (debugEnabled())
423 {
424 TRACER.debugCaught(DebugLogLevel.ERROR, e);
425 }
426
427 Message message =
428 ERR_LDAP_RESULT_DECODE_REFERRALS.get(String.valueOf(e));
429 throw new LDAPException(PROTOCOL_ERROR, message, e);
430 }
431 }
432
433
434 return new AddResponseProtocolOp(resultCode, errorMessage, matchedDN,
435 referralURLs);
436 }
437
438
439
440 /**
441 * Appends a string representation of this LDAP protocol op to the provided
442 * buffer.
443 *
444 * @param buffer The buffer to which the string should be appended.
445 */
446 public void toString(StringBuilder buffer)
447 {
448 buffer.append("AddResponse(resultCode=");
449 buffer.append(resultCode);
450
451 if ((errorMessage != null) && (errorMessage.length() > 0))
452 {
453 buffer.append(", errorMessage=");
454 buffer.append(errorMessage);
455 }
456
457 if (matchedDN != null)
458 {
459 buffer.append(", matchedDN=");
460 buffer.append(matchedDN.toString());
461 }
462
463 if ((referralURLs != null) && (! referralURLs.isEmpty()))
464 {
465 buffer.append(", referralURLs={");
466
467 Iterator<String> iterator = referralURLs.iterator();
468 buffer.append(iterator.next());
469
470 while (iterator.hasNext())
471 {
472 buffer.append(", ");
473 buffer.append(iterator.next());
474 }
475
476 buffer.append("}");
477 }
478
479 buffer.append(")");
480 }
481
482
483
484 /**
485 * Appends a multi-line string representation of this LDAP protocol op to the
486 * provided buffer.
487 *
488 * @param buffer The buffer to which the information should be appended.
489 * @param indent The number of spaces from the margin that the lines should
490 * be indented.
491 */
492 public void toString(StringBuilder buffer, int indent)
493 {
494 StringBuilder indentBuf = new StringBuilder(indent);
495 for (int i=0 ; i < indent; i++)
496 {
497 indentBuf.append(' ');
498 }
499
500 buffer.append(indentBuf);
501 buffer.append("Add Response");
502 buffer.append(EOL);
503
504 buffer.append(indentBuf);
505 buffer.append(" Result Code: ");
506 buffer.append(resultCode);
507 buffer.append(EOL);
508
509 if (errorMessage != null)
510 {
511 buffer.append(indentBuf);
512 buffer.append(" Error Message: ");
513 buffer.append(errorMessage);
514 buffer.append(EOL);
515 }
516
517 if (matchedDN != null)
518 {
519 buffer.append(indentBuf);
520 buffer.append(" Matched DN: ");
521 matchedDN.toString(buffer);
522 buffer.append(EOL);
523 }
524
525 if ((referralURLs != null) && (! referralURLs.isEmpty()))
526 {
527 buffer.append(indentBuf);
528 buffer.append(" Referral URLs: ");
529 buffer.append(EOL);
530
531 for (String s : referralURLs)
532 {
533 buffer.append(indentBuf);
534 buffer.append(" ");
535 buffer.append(s);
536 buffer.append(EOL);
537 }
538 }
539 }
540 }
541