001/*
002 * Copyright 2007-2019 Ping Identity Corporation
003 * All Rights Reserved.
004 */
005/*
006 * Copyright (C) 2008-2019 Ping Identity Corporation
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 java.util.List;
026
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.  It includes all of the elements of the
037 * {@link SearchResult} object, potentially including entries and references
038 * returned before the failure result.
039 */
040@NotMutable()
041@ThreadSafety(level=ThreadSafetyLevel.COMPLETELY_THREADSAFE)
042public final class LDAPSearchException
043       extends LDAPException
044{
045  /**
046   * The serial version UID for this serializable class.
047   */
048  private static final long serialVersionUID = 350230437196125113L;
049
050
051
052  // The search result with information from this exception.
053  private final SearchResult searchResult;
054
055
056
057  /**
058   * Creates a new LDAP search exception with the provided information.
059   *
060   * @param  resultCode    The result code for this LDAP search exception.
061   * @param  errorMessage  The error message for this LDAP search exception.
062   */
063  public LDAPSearchException(final ResultCode resultCode,
064                             final String errorMessage)
065  {
066    super(resultCode, errorMessage);
067
068    searchResult = new SearchResult(-1, resultCode, errorMessage, null,
069         StaticUtils.NO_STRINGS, 0, 0, StaticUtils.NO_CONTROLS);
070  }
071
072
073
074  /**
075   * Creates a new LDAP search exception with the provided information.
076   *
077   * @param  resultCode    The result code for this LDAP search exception.
078   * @param  errorMessage  The error message for this LDAP search exception.
079   * @param  cause         The underlying exception that triggered this LDAP
080   *                       search exception.
081   */
082  public LDAPSearchException(final ResultCode resultCode,
083                             final String errorMessage, final Throwable cause)
084  {
085    super(resultCode, errorMessage, cause);
086
087    searchResult = new SearchResult(-1, resultCode, errorMessage, null,
088         StaticUtils.NO_STRINGS , 0, 0, StaticUtils.NO_CONTROLS);
089  }
090
091
092
093  /**
094   * Creates a new LDAP search exception from the provided exception.
095   *
096   * @param  ldapException  The LDAP exception with the information to include
097   *                        in this LDAP search exception.
098   */
099  public LDAPSearchException(final LDAPException ldapException)
100  {
101    super(ldapException.getResultCode(), ldapException.getMessage(),
102          ldapException.getMatchedDN(), ldapException.getReferralURLs(),
103          ldapException.getResponseControls(), ldapException);
104
105    if (ldapException instanceof LDAPSearchException)
106    {
107      final LDAPSearchException lse = (LDAPSearchException) ldapException;
108      searchResult = lse.searchResult;
109    }
110    else
111    {
112      searchResult = new SearchResult(-1, ldapException.getResultCode(),
113                                      ldapException.getMessage(),
114                                      ldapException.getMatchedDN(),
115                                      ldapException.getReferralURLs(), 0, 0,
116                                      ldapException.getResponseControls());
117    }
118  }
119
120
121
122  /**
123   * Creates a new LDAP search exception with the provided result.
124   *
125   * @param  searchResult  The search result to use to create this LDAP search
126   *                       exception.
127   */
128  public LDAPSearchException(final SearchResult searchResult)
129  {
130    super(searchResult);
131
132    this.searchResult = searchResult;
133  }
134
135
136
137  /**
138   * Retrieves the search result object associated with this LDAP search
139   * exception.
140   *
141   * @return  The search result object associated with this LDAP search
142   *          exception.
143   */
144  public SearchResult getSearchResult()
145  {
146    return searchResult;
147  }
148
149
150
151  /**
152   * Retrieves the number of matching entries returned for the search operation
153   * before this exception was thrown.
154   *
155   * @return  The number of matching entries returned for the search operation
156   *          before this exception was thrown.
157   */
158  public int getEntryCount()
159  {
160    return searchResult.getEntryCount();
161  }
162
163
164
165  /**
166   * Retrieves the number of search references returned for the search
167   * operation before this exception was thrown.
168   *
169   * @return  The number of search references returned for the search operation
170   *          before this exception was thrown.
171   */
172  public int getReferenceCount()
173  {
174    return searchResult.getReferenceCount();
175  }
176
177
178
179  /**
180   * Retrieves a list containing the matching entries returned from the search
181   * operation before this exception was thrown.  This will only be available if
182   * a {@code SearchResultListener} was not used during the search.
183   *
184   * @return  A list containing the matching entries returned from the search
185   *          operation before this exception was thrown, or {@code null} if a
186   *          {@code SearchResultListener} was used during the search.
187   */
188  public List<SearchResultEntry> getSearchEntries()
189  {
190    return searchResult.getSearchEntries();
191  }
192
193
194
195  /**
196   * Retrieves a list containing the search references returned from the search
197   * operation before this exception was thrown.  This will only be available if
198   * a {@code SearchResultListener} was not used during the search.
199   *
200   * @return  A list containing the search references returned from the search
201   *          operation before this exception was thrown, or {@code null} if a
202   *          {@code SearchResultListener} was used during the search.
203   */
204  public List<SearchResultReference> getSearchReferences()
205  {
206    return searchResult.getSearchReferences();
207  }
208
209
210
211  /**
212   * Creates a new {@code SearchResult} object from this exception.
213   *
214   * @return  The {@code SearchResult} object created from this exception.
215   */
216  @Override()
217  public SearchResult toLDAPResult()
218  {
219    return searchResult;
220  }
221
222
223
224  /**
225   * Appends a string representation of this LDAP exception to the provided
226   * buffer.
227   *
228   * @param  buffer  The buffer to which to append a string representation of
229   *                 this LDAP exception.
230   */
231  @Override()
232  public void toString(final StringBuilder buffer)
233  {
234    super.toString(buffer);
235  }
236
237
238
239  /**
240   * {@inheritDoc}
241   */
242  @Override()
243  public void toString(final StringBuilder buffer, final boolean includeCause,
244                       final boolean includeStackTrace)
245  {
246    buffer.append("LDAPException(resultCode=");
247    buffer.append(getResultCode());
248    buffer.append(", numEntries=");
249    buffer.append(searchResult.getEntryCount());
250    buffer.append(", numReferences=");
251    buffer.append(searchResult.getReferenceCount());
252
253    final String errorMessage = getMessage();
254    final String diagnosticMessage = getDiagnosticMessage();
255    if ((errorMessage != null) && (! errorMessage.equals(diagnosticMessage)))
256    {
257      buffer.append(", errorMessage='");
258      buffer.append(errorMessage);
259      buffer.append('\'');
260    }
261
262    if (diagnosticMessage != null)
263    {
264      buffer.append(", diagnosticMessage='");
265      buffer.append(diagnosticMessage);
266      buffer.append('\'');
267    }
268
269    final String matchedDN = getMatchedDN();
270    if (matchedDN != null)
271    {
272      buffer.append(", matchedDN='");
273      buffer.append(matchedDN);
274      buffer.append('\'');
275    }
276
277    final String[] referralURLs = getReferralURLs();
278    if (referralURLs.length > 0)
279    {
280      buffer.append(", referralURLs={");
281
282      for (int i=0; i < referralURLs.length; i++)
283      {
284        if (i > 0)
285        {
286          buffer.append(", ");
287        }
288
289        buffer.append('\'');
290        buffer.append(referralURLs[i]);
291        buffer.append('\'');
292      }
293
294      buffer.append('}');
295    }
296
297    final Control[] responseControls = getResponseControls();
298    if (responseControls.length > 0)
299    {
300      buffer.append(", responseControls={");
301
302      for (int i=0; i < responseControls.length; i++)
303      {
304        if (i > 0)
305        {
306          buffer.append(", ");
307        }
308
309        buffer.append(responseControls[i]);
310      }
311
312      buffer.append('}');
313    }
314
315    if (includeStackTrace)
316    {
317      buffer.append(", trace='");
318      StaticUtils.getStackTrace(getStackTrace(), buffer);
319      buffer.append('\'');
320    }
321
322    if (includeCause || includeStackTrace)
323    {
324      final Throwable cause = getCause();
325      if (cause != null)
326      {
327        buffer.append(", cause=");
328        buffer.append(StaticUtils.getExceptionMessage(cause, true,
329             includeStackTrace));
330      }
331    }
332
333    final String ldapSDKVersionString = ", ldapSDKVersion=" +
334         Version.NUMERIC_VERSION_STRING + ", revision=" + Version.REVISION_ID;
335    if (buffer.indexOf(ldapSDKVersionString) < 0)
336    {
337      buffer.append(ldapSDKVersionString);
338    }
339
340    buffer.append("')");
341  }
342}