001/*
002 * Copyright 2007-2017 UnboundID Corp.
003 * All Rights Reserved.
004 */
005/*
006 * Copyright (C) 2008-2017 UnboundID Corp.
007 *
008 * This program is free software; you can redistribute it and/or modify
009 * it under the terms of the GNU General Public License (GPLv2 only)
010 * or the terms of the GNU Lesser General Public License (LGPLv2.1 only)
011 * as published by the Free Software Foundation.
012 *
013 * This program is distributed in the hope that it will be useful,
014 * but WITHOUT ANY WARRANTY; without even the implied warranty of
015 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
016 * GNU General Public License for more details.
017 *
018 * You should have received a copy of the GNU General Public License
019 * along with this program; if not, see <http://www.gnu.org/licenses>.
020 */
021package com.unboundid.ldap.sdk;
022
023
024
025import com.unboundid.util.LDAPSDKException;
026import com.unboundid.util.NotExtensible;
027import com.unboundid.util.NotMutable;
028import com.unboundid.util.StaticUtils;
029import com.unboundid.util.ThreadSafety;
030import com.unboundid.util.ThreadSafetyLevel;
031
032
033
034/**
035 * This class defines an exception that can be thrown if a problem occurs while
036 * performing LDAP-related processing.  An LDAP exception can include all of
037 * the elements of an {@link LDAPResult}, so that all of the response elements
038 * will be available.
039 */
040@NotExtensible()
041@NotMutable()
042@ThreadSafety(level=ThreadSafetyLevel.COMPLETELY_THREADSAFE)
043public class LDAPException
044       extends LDAPSDKException
045{
046  /**
047   * The serial version UID for this serializable class.
048   */
049  private static final long serialVersionUID = -4257171063946350327L;
050
051
052
053  /**
054   * An empty array that will be used when no controls were provided.
055   */
056  protected static final Control[] NO_CONTROLS = StaticUtils.NO_CONTROLS;
057
058
059
060  /**
061   * An empty array that will be used when no referrals were provided.
062   */
063  protected static final String[] NO_REFERRALS = StaticUtils.NO_STRINGS;
064
065
066
067  // The set of response controls for this LDAP exception.
068  private final Control[] responseControls;
069
070  // The result code for this LDAP exception.
071  private final ResultCode resultCode;
072
073  // The set of referral URLs for this LDAP exception.
074  private final String[] referralURLs;
075
076  // The diagnostic message returned by the directory server.
077  private final String diagnosticMessage;
078
079  // The matched DN for this LDAP exception.
080  private final String matchedDN;
081
082
083
084  /**
085   * Creates a new LDAP exception with the provided result code.  A default
086   * message (based on the result code) will be used.
087   *
088   * @param  resultCode  The result code for this LDAP exception.
089   */
090  public LDAPException(final ResultCode resultCode)
091  {
092    super(resultCode.getName());
093
094    this.resultCode = resultCode;
095
096    matchedDN         = null;
097    diagnosticMessage = null;
098    referralURLs      = NO_REFERRALS;
099    responseControls  = NO_CONTROLS;
100  }
101
102
103
104  /**
105   * Creates a new LDAP exception with the provided result code.  A default
106   * message (based on the result code) will be used.
107   *
108   * @param  resultCode  The result code for this LDAP exception.
109   * @param  cause       The underlying exception that triggered this exception.
110   */
111  public LDAPException(final ResultCode resultCode, final Throwable cause)
112  {
113    super(resultCode.getName(), cause);
114
115    this.resultCode = resultCode;
116
117    matchedDN         = null;
118    diagnosticMessage = null;
119    referralURLs      = NO_REFERRALS;
120    responseControls  = NO_CONTROLS;
121  }
122
123
124
125  /**
126   * Creates a new LDAP exception with the provided result code and message.
127   *
128   * @param  resultCode    The result code for this LDAP exception.
129   * @param  errorMessage  The error message for this LDAP exception.
130   */
131  public LDAPException(final ResultCode resultCode, final String errorMessage)
132  {
133    super(errorMessage);
134
135    this.resultCode = resultCode;
136
137    matchedDN         = null;
138    diagnosticMessage = null;
139    referralURLs      = NO_REFERRALS;
140    responseControls  = NO_CONTROLS;
141  }
142
143
144
145  /**
146   * Creates a new LDAP exception with the provided result code and message.
147   *
148   * @param  resultCode    The result code for this LDAP exception.
149   * @param  errorMessage  The error message for this LDAP exception.
150   * @param  cause         The underlying exception that triggered this
151   *                       exception.
152   */
153  public LDAPException(final ResultCode resultCode, final String errorMessage,
154                       final Throwable cause)
155  {
156    super(errorMessage, cause);
157
158    this.resultCode = resultCode;
159
160    matchedDN         = null;
161    diagnosticMessage = null;
162    referralURLs      = NO_REFERRALS;
163    responseControls  = NO_CONTROLS;
164  }
165
166
167
168  /**
169   * Creates a new LDAP exception with the provided information.
170   *
171   * @param  resultCode    The result code for this LDAP exception.
172   * @param  errorMessage  The error message for this LDAP exception.
173   * @param  matchedDN     The matched DN for this LDAP exception.
174   * @param  referralURLs  The set of referral URLs for this LDAP exception.
175   */
176  public LDAPException(final ResultCode resultCode, final String errorMessage,
177                       final String matchedDN, final String[] referralURLs)
178  {
179    super(errorMessage);
180
181    this.resultCode = resultCode;
182    this.matchedDN  = matchedDN;
183
184    if (referralURLs == null)
185    {
186      this.referralURLs = NO_REFERRALS;
187    }
188    else
189    {
190      this.referralURLs = referralURLs;
191    }
192
193    diagnosticMessage = null;
194    responseControls  = NO_CONTROLS;
195  }
196
197
198
199  /**
200   * Creates a new LDAP exception with the provided information.
201   *
202   * @param  resultCode    The result code for this LDAP exception.
203   * @param  errorMessage  The error message for this LDAP exception.
204   * @param  matchedDN     The matched DN for this LDAP exception.
205   * @param  referralURLs  The set of referral URLs for this LDAP exception.
206   * @param  cause         The underlying exception that triggered this
207   *                       exception.
208   */
209  public LDAPException(final ResultCode resultCode, final String errorMessage,
210                       final String matchedDN, final String[] referralURLs,
211                       final Throwable cause)
212  {
213    super(errorMessage, cause);
214
215    this.resultCode = resultCode;
216    this.matchedDN  = matchedDN;
217
218    if (referralURLs == null)
219    {
220      this.referralURLs = NO_REFERRALS;
221    }
222    else
223    {
224      this.referralURLs = referralURLs;
225    }
226
227    diagnosticMessage = null;
228    responseControls  = NO_CONTROLS;
229  }
230
231
232
233  /**
234   * Creates a new LDAP exception with the provided information.
235   *
236   * @param  resultCode    The result code for this LDAP exception.
237   * @param  errorMessage  The error message for this LDAP exception.
238   * @param  matchedDN     The matched DN for this LDAP exception.
239   * @param  referralURLs  The set of referral URLs for this LDAP exception.
240   * @param  controls      The set of response controls for this LDAP exception.
241   */
242  public LDAPException(final ResultCode resultCode, final String errorMessage,
243                       final String matchedDN, final String[] referralURLs,
244                       final Control[] controls)
245  {
246    super(errorMessage);
247
248    this.resultCode = resultCode;
249    this.matchedDN  = matchedDN;
250
251    diagnosticMessage = null;
252
253    if (referralURLs == null)
254    {
255      this.referralURLs = NO_REFERRALS;
256    }
257    else
258    {
259      this.referralURLs = referralURLs;
260    }
261
262    if (controls == null)
263    {
264      responseControls = NO_CONTROLS;
265    }
266    else
267    {
268      responseControls = controls;
269    }
270  }
271
272
273
274  /**
275   * Creates a new LDAP exception with the provided information.
276   *
277   * @param  resultCode    The result code for this LDAP exception.
278   * @param  errorMessage  The error message for this LDAP exception.
279   * @param  matchedDN     The matched DN for this LDAP exception.
280   * @param  referralURLs  The set of referral URLs for this LDAP exception.
281   * @param  controls      The set of response controls for this LDAP exception.
282   * @param  cause         The underlying exception that triggered this
283   *                       exception.
284   */
285  public LDAPException(final ResultCode resultCode, final String errorMessage,
286                       final String matchedDN, final String[] referralURLs,
287                       final Control[] controls, final Throwable cause)
288  {
289    super(errorMessage, cause);
290
291    this.resultCode = resultCode;
292    this.matchedDN  = matchedDN;
293
294    diagnosticMessage = null;
295
296    if (referralURLs == null)
297    {
298      this.referralURLs = NO_REFERRALS;
299    }
300    else
301    {
302      this.referralURLs = referralURLs;
303    }
304
305    if (controls == null)
306    {
307      responseControls = NO_CONTROLS;
308    }
309    else
310    {
311      responseControls = controls;
312    }
313  }
314
315
316
317  /**
318   * Creates a new LDAP exception using the information contained in the
319   * provided LDAP result object.
320   *
321   * @param  ldapResult  The LDAP result object containing the information to
322   *                     use for this LDAP exception.
323   */
324  public LDAPException(final LDAPResult ldapResult)
325  {
326    super((ldapResult.getDiagnosticMessage() == null)
327          ? ldapResult.getResultCode().getName()
328          : ldapResult.getDiagnosticMessage());
329
330    resultCode        = ldapResult.getResultCode();
331    matchedDN         = ldapResult.getMatchedDN();
332    diagnosticMessage = ldapResult.getDiagnosticMessage();
333    referralURLs      = ldapResult.getReferralURLs();
334    responseControls  = ldapResult.getResponseControls();
335  }
336
337
338
339  /**
340   * Creates a new LDAP exception using the information contained in the
341   * provided LDAP result object.
342   *
343   * @param  ldapResult  The LDAP result object containing the information to
344   *                     use for this LDAP exception.
345   * @param  cause       The underlying exception that triggered this exception.
346   */
347  public LDAPException(final LDAPResult ldapResult, final Throwable cause)
348  {
349    super(((ldapResult.getDiagnosticMessage() == null)
350           ? ldapResult.getResultCode().getName()
351           : ldapResult.getDiagnosticMessage()),
352          cause);
353
354    resultCode        = ldapResult.getResultCode();
355    matchedDN         = ldapResult.getMatchedDN();
356    diagnosticMessage = ldapResult.getDiagnosticMessage();
357    referralURLs      = ldapResult.getReferralURLs();
358    responseControls  = ldapResult.getResponseControls();
359  }
360
361
362
363  /**
364   * Creates a new LDAP exception using the information contained in the
365   * provided LDAP exception.
366   *
367   * @param  e  The LDAP exception to use to create this exception.
368   */
369  public LDAPException(final LDAPException e)
370  {
371    super(e.getMessage(), e.getCause());
372
373    resultCode        = e.getResultCode();
374    matchedDN         = e.getMatchedDN();
375    diagnosticMessage = e.getDiagnosticMessage();
376    referralURLs      = e.getReferralURLs();
377    responseControls  = e.getResponseControls();
378  }
379
380
381
382  /**
383   * Retrieves the result code for this LDAP exception.
384   *
385   * @return  The result code for this LDAP exception.
386   */
387  public final ResultCode getResultCode()
388  {
389    return resultCode;
390  }
391
392
393
394  /**
395   * Retrieves the matched DN for this LDAP exception.
396   *
397   * @return  The matched DN for this LDAP exception, or {@code null} if there
398   *          is none.
399   */
400  public final String getMatchedDN()
401  {
402    return matchedDN;
403  }
404
405
406
407  /**
408   * Retrieves the diagnostic message returned by the directory server.
409   *
410   * @return  The diagnostic message returned by the directory server, or
411   *          {@code null} if there is none.
412   */
413  public final String getDiagnosticMessage()
414  {
415    return diagnosticMessage;
416  }
417
418
419
420  /**
421   * Retrieves the set of referral URLs for this LDAP exception.
422   *
423   * @return  The set of referral URLs for this LDAP exception, or an empty
424   *          array if there are none.
425   */
426  public final String[] getReferralURLs()
427  {
428    return referralURLs;
429  }
430
431
432
433  /**
434   * Indicates whether this result contains at least one control.
435   *
436   * @return  {@code true} if this result contains at least one control, or
437   *          {@code false} if not.
438   */
439  public final boolean hasResponseControl()
440  {
441    return (responseControls.length > 0);
442  }
443
444
445
446  /**
447   * Indicates whether this result contains at least one control with the
448   * specified OID.
449   *
450   * @param  oid  The object identifier for which to make the determination.  It
451   *              must not be {@code null}.
452   *
453   * @return  {@code true} if this result contains at least one control with
454   *          the specified OID, or {@code false} if not.
455   */
456  public final boolean hasResponseControl(final String oid)
457  {
458    for (final Control c : responseControls)
459    {
460      if (c.getOID().equals(oid))
461      {
462        return true;
463      }
464    }
465
466    return false;
467  }
468
469
470
471  /**
472   * Retrieves the set of response controls for this LDAP exception.
473   * Individual response controls of a specific type may be retrieved and
474   * decoded using the {@code get} method in the response control class, using
475   * the {@link #toLDAPResult()} method to convert this exception to an
476   * {@link LDAPResult}.
477   *
478   * @return  The set of response controls for this LDAP exception, or an empty
479   *          array if there are none.
480   */
481  public final Control[] getResponseControls()
482  {
483    return responseControls;
484  }
485
486
487
488  /**
489   * Retrieves the response control with the specified OID.
490   *
491   * @param  oid  The OID of the control to retrieve.
492   *
493   * @return  The response control with the specified OID, or {@code null} if
494   *          there is no such control.
495   */
496  public final Control getResponseControl(final String oid)
497  {
498    for (final Control c : responseControls)
499    {
500      if (c.getOID().equals(oid))
501      {
502        return c;
503      }
504    }
505
506    return null;
507  }
508
509
510
511  /**
512   * Creates a new {@code LDAPResult} object from this exception.
513   *
514   * @return  The {@code LDAPResult} object created from this exception.
515   */
516  public LDAPResult toLDAPResult()
517  {
518    if ((diagnosticMessage == null) && (getMessage() != null))
519    {
520      return new LDAPResult(-1, resultCode, getMessage(), matchedDN,
521           referralURLs, responseControls);
522    }
523    else
524    {
525      return new LDAPResult(-1, resultCode, diagnosticMessage, matchedDN,
526           referralURLs, responseControls);
527    }
528  }
529
530
531
532  /**
533   * Retrieves a string representation of this LDAP result, consisting of
534   * the result code, diagnostic message (if present), matched DN (if present),
535   * and referral URLs (if present).
536   *
537   * @return  A string representation of this LDAP result.
538   */
539  public String getResultString()
540  {
541    final StringBuilder buffer = new StringBuilder();
542    buffer.append("result code='");
543    buffer.append(resultCode);
544    buffer.append('\'');
545
546    if ((diagnosticMessage != null) && (diagnosticMessage.length() > 0))
547    {
548      buffer.append(" diagnostic message='");
549      buffer.append(diagnosticMessage);
550      buffer.append('\'');
551    }
552
553    if ((matchedDN != null) && (matchedDN.length() > 0))
554    {
555      buffer.append("  matched DN='");
556      buffer.append(matchedDN);
557      buffer.append('\'');
558    }
559
560    if ((referralURLs != null) && (referralURLs.length > 0))
561    {
562      buffer.append("  referral URLs={");
563
564      for (int i=0; i < referralURLs.length; i++)
565      {
566        if (i > 0)
567        {
568          buffer.append(", ");
569        }
570
571        buffer.append('\'');
572        buffer.append(referralURLs[i]);
573        buffer.append('\'');
574      }
575
576      buffer.append('}');
577    }
578
579    return buffer.toString();
580  }
581
582
583
584  /**
585   * {@inheritDoc}
586   */
587  @Override()
588  public void toString(final StringBuilder buffer)
589  {
590    buffer.append("LDAPException(resultCode=");
591    buffer.append(resultCode);
592
593    final String errorMessage = getMessage();
594    if (errorMessage != null)
595    {
596      buffer.append(", errorMessage='");
597      buffer.append(errorMessage);
598      buffer.append('\'');
599    }
600
601    if (matchedDN != null)
602    {
603      buffer.append(", matchedDN='");
604      buffer.append(matchedDN);
605      buffer.append('\'');
606    }
607
608    if (diagnosticMessage != null)
609    {
610      buffer.append(", diagnosticMessage='");
611      buffer.append(diagnosticMessage);
612      buffer.append('\'');
613    }
614
615    if (referralURLs.length > 0)
616    {
617      buffer.append(", referralURLs={");
618
619      for (int i=0; i < referralURLs.length; i++)
620      {
621        if (i > 0)
622        {
623          buffer.append(", ");
624        }
625
626        buffer.append('\'');
627        buffer.append(referralURLs[i]);
628        buffer.append('\'');
629      }
630
631      buffer.append('}');
632    }
633
634    if (responseControls.length > 0)
635    {
636      buffer.append(", responseControls={");
637
638      for (int i=0; i < responseControls.length; i++)
639      {
640        if (i > 0)
641        {
642          buffer.append(", ");
643        }
644
645        buffer.append(responseControls[i]);
646      }
647
648      buffer.append('}');
649    }
650
651    buffer.append(')');
652  }
653
654
655
656  /**
657   * {@inheritDoc}
658   */
659  @Override()
660  public final String getExceptionMessage()
661  {
662    return toString();
663  }
664}