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 search result done
055 * protocol op, which is used to provide information about the result of
056 * processing a search request.
057 */
058 public class SearchResultDoneProtocolOp
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 search result done protocol op with the provided result code.
082 *
083 * @param resultCode The result code for this response.
084 */
085 public SearchResultDoneProtocolOp(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 search result done protocol op with the provided result code
098 * and error message.
099 *
100 * @param resultCode The result code for this response.
101 * @param errorMessage The error message for this response.
102 */
103 public SearchResultDoneProtocolOp(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 search result done 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 SearchResultDoneProtocolOp(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_SEARCH_RESULT_DONE;
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 "Search Result Done";
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 if (errorMessage == null)
277 {
278 elements.add(new ASN1OctetString());
279 }
280 else
281 {
282 elements.add(new ASN1OctetString(errorMessage));
283 }
284
285 if ((referralURLs != null) && (! referralURLs.isEmpty()))
286 {
287 ArrayList<ASN1Element> referralElements =
288 new ArrayList<ASN1Element>(referralURLs.size());
289
290 for (String s : referralURLs)
291 {
292 referralElements.add(new ASN1OctetString(s));
293 }
294
295 elements.add(new ASN1Sequence(TYPE_REFERRAL_SEQUENCE, referralElements));
296 }
297
298 return new ASN1Sequence(OP_TYPE_SEARCH_RESULT_DONE, elements);
299 }
300
301
302
303 /**
304 * Decodes the provided ASN.1 element as a search result done protocol op.
305 *
306 * @param element The ASN.1 element to decode.
307 *
308 * @return The decoded search result done protocol op.
309 *
310 * @throws LDAPException If a problem occurs while attempting to decode the
311 * ASN.1 element to a protocol op.
312 */
313 public static SearchResultDoneProtocolOp decodeSearchDone(ASN1Element
314 element)
315 throws LDAPException
316 {
317 ArrayList<ASN1Element> elements;
318 try
319 {
320 elements = element.decodeAsSequence().elements();
321 }
322 catch (Exception e)
323 {
324 if (debugEnabled())
325 {
326 TRACER.debugCaught(DebugLogLevel.ERROR, e);
327 }
328
329 Message message = ERR_LDAP_RESULT_DECODE_SEQUENCE.get(String.valueOf(e));
330 throw new LDAPException(PROTOCOL_ERROR, message, e);
331 }
332
333
334 int numElements = elements.size();
335 if ((numElements < 3) || (numElements > 4))
336 {
337 Message message =
338 ERR_LDAP_RESULT_DECODE_INVALID_ELEMENT_COUNT.get(numElements);
339 throw new LDAPException(PROTOCOL_ERROR, message);
340 }
341
342
343 int resultCode;
344 try
345 {
346 resultCode = elements.get(0).decodeAsInteger().intValue();
347 }
348 catch (Exception e)
349 {
350 if (debugEnabled())
351 {
352 TRACER.debugCaught(DebugLogLevel.ERROR, e);
353 }
354
355 Message message =
356 ERR_LDAP_RESULT_DECODE_RESULT_CODE.get(String.valueOf(e));
357 throw new LDAPException(PROTOCOL_ERROR, message, e);
358 }
359
360
361 DN matchedDN;
362 try
363 {
364 String dnString = elements.get(1).decodeAsOctetString().stringValue();
365 if (dnString.length() == 0)
366 {
367 matchedDN = null;
368 }
369 else
370 {
371 matchedDN = DN.decode(dnString);
372 }
373 }
374 catch (Exception e)
375 {
376 if (debugEnabled())
377 {
378 TRACER.debugCaught(DebugLogLevel.ERROR, e);
379 }
380
381 Message message =
382 ERR_LDAP_RESULT_DECODE_MATCHED_DN.get(String.valueOf(e));
383 throw new LDAPException(PROTOCOL_ERROR, message, e);
384 }
385
386
387 Message errorMessage;
388 try
389 {
390 errorMessage =
391 Message.raw(elements.get(2).decodeAsOctetString().stringValue());
392 if (errorMessage.length() == 0)
393 {
394 errorMessage = null;
395 }
396 }
397 catch (Exception e)
398 {
399 if (debugEnabled())
400 {
401 TRACER.debugCaught(DebugLogLevel.ERROR, e);
402 }
403
404 Message message =
405 ERR_LDAP_RESULT_DECODE_ERROR_MESSAGE.get(String.valueOf(e));
406 throw new LDAPException(PROTOCOL_ERROR, message, e);
407 }
408
409
410 ArrayList<String> referralURLs;
411 if (numElements == 3)
412 {
413 referralURLs = null;
414 }
415 else
416 {
417 try
418 {
419 ArrayList<ASN1Element> referralElements =
420 elements.get(3).decodeAsSequence().elements();
421 referralURLs = new ArrayList<String>(referralElements.size());
422
423 for (ASN1Element e : referralElements)
424 {
425 referralURLs.add(e.decodeAsOctetString().stringValue());
426 }
427 }
428 catch (Exception e)
429 {
430 if (debugEnabled())
431 {
432 TRACER.debugCaught(DebugLogLevel.ERROR, e);
433 }
434
435 Message message =
436 ERR_LDAP_RESULT_DECODE_REFERRALS.get(String.valueOf(e));
437 throw new LDAPException(PROTOCOL_ERROR, message, e);
438 }
439 }
440
441
442 return new SearchResultDoneProtocolOp(resultCode, errorMessage, matchedDN,
443 referralURLs);
444 }
445
446
447
448 /**
449 * Appends a string representation of this LDAP protocol op to the provided
450 * buffer.
451 *
452 * @param buffer The buffer to which the string should be appended.
453 */
454 public void toString(StringBuilder buffer)
455 {
456 buffer.append("SearchResultDone(resultCode=");
457 buffer.append(resultCode);
458
459 if ((errorMessage != null) && (errorMessage.length() > 0))
460 {
461 buffer.append(", errorMessage=");
462 buffer.append(errorMessage);
463 }
464
465 if (matchedDN != null)
466 {
467 buffer.append(", matchedDN=");
468 buffer.append(matchedDN.toString());
469 }
470
471 if ((referralURLs != null) && (! referralURLs.isEmpty()))
472 {
473 buffer.append(", referralURLs={");
474
475 Iterator<String> iterator = referralURLs.iterator();
476 buffer.append(iterator.next());
477
478 while (iterator.hasNext())
479 {
480 buffer.append(", ");
481 buffer.append(iterator.next());
482 }
483
484 buffer.append("}");
485 }
486
487 buffer.append(")");
488 }
489
490
491
492 /**
493 * Appends a multi-line string representation of this LDAP protocol op to the
494 * provided buffer.
495 *
496 * @param buffer The buffer to which the information should be appended.
497 * @param indent The number of spaces from the margin that the lines should
498 * be indented.
499 */
500 public void toString(StringBuilder buffer, int indent)
501 {
502 StringBuilder indentBuf = new StringBuilder(indent);
503 for (int i=0 ; i < indent; i++)
504 {
505 indentBuf.append(' ');
506 }
507
508 buffer.append(indentBuf);
509 buffer.append("Search Result Done");
510 buffer.append(EOL);
511
512 buffer.append(indentBuf);
513 buffer.append(" Result Code: ");
514 buffer.append(resultCode);
515 buffer.append(EOL);
516
517 if (errorMessage != null)
518 {
519 buffer.append(indentBuf);
520 buffer.append(" Error Message: ");
521 buffer.append(errorMessage);
522 buffer.append(EOL);
523 }
524
525 if (matchedDN != null)
526 {
527 buffer.append(indentBuf);
528 buffer.append(" Matched DN: ");
529 matchedDN.toString(buffer);
530 buffer.append(EOL);
531 }
532
533 if ((referralURLs != null) && (! referralURLs.isEmpty()))
534 {
535 buffer.append(indentBuf);
536 buffer.append(" Referral URLs: ");
537 buffer.append(EOL);
538
539 for (String s : referralURLs)
540 {
541 buffer.append(indentBuf);
542 buffer.append(" ");
543 buffer.append(s);
544 buffer.append(EOL);
545 }
546 }
547 }
548 }
549