001    /*
002     * Copyright 2007-2015 UnboundID Corp.
003     * All Rights Reserved.
004     */
005    /*
006     * Copyright (C) 2008-2015 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     */
021    package com.unboundid.ldap.sdk;
022    
023    
024    
025    import com.unboundid.util.LDAPSDKException;
026    import com.unboundid.util.NotExtensible;
027    import com.unboundid.util.NotMutable;
028    import com.unboundid.util.StaticUtils;
029    import com.unboundid.util.ThreadSafety;
030    import 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)
043    public 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       * {@inheritDoc}
534       */
535      @Override()
536      public void toString(final StringBuilder buffer)
537      {
538        buffer.append("LDAPException(resultCode=");
539        buffer.append(resultCode);
540    
541        final String errorMessage = getMessage();
542        if (errorMessage != null)
543        {
544          buffer.append(", errorMessage='");
545          buffer.append(errorMessage);
546          buffer.append('\'');
547        }
548    
549        if (matchedDN != null)
550        {
551          buffer.append(", matchedDN='");
552          buffer.append(matchedDN);
553          buffer.append('\'');
554        }
555    
556        if (diagnosticMessage != null)
557        {
558          buffer.append(", diagnosticMessage='");
559          buffer.append(diagnosticMessage);
560          buffer.append('\'');
561        }
562    
563        if (referralURLs.length > 0)
564        {
565          buffer.append(", referralURLs={");
566    
567          for (int i=0; i < referralURLs.length; i++)
568          {
569            if (i > 0)
570            {
571              buffer.append(", ");
572            }
573    
574            buffer.append('\'');
575            buffer.append(referralURLs[i]);
576            buffer.append('\'');
577          }
578    
579          buffer.append('}');
580        }
581    
582        if (responseControls.length > 0)
583        {
584          buffer.append(", responseControls={");
585    
586          for (int i=0; i < responseControls.length; i++)
587          {
588            if (i > 0)
589            {
590              buffer.append(", ");
591            }
592    
593            buffer.append(responseControls[i]);
594          }
595    
596          buffer.append('}');
597        }
598    
599        buffer.append(')');
600      }
601    
602    
603    
604      /**
605       * {@inheritDoc}
606       */
607      @Override()
608      public final String getExceptionMessage()
609      {
610        return toString();
611      }
612    }