001/* 002 * Copyright 2007-2024 Ping Identity Corporation 003 * All Rights Reserved. 004 */ 005/* 006 * Copyright 2007-2024 Ping Identity Corporation 007 * 008 * Licensed under the Apache License, Version 2.0 (the "License"); 009 * you may not use this file except in compliance with the License. 010 * You may obtain a copy of the License at 011 * 012 * http://www.apache.org/licenses/LICENSE-2.0 013 * 014 * Unless required by applicable law or agreed to in writing, software 015 * distributed under the License is distributed on an "AS IS" BASIS, 016 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 017 * See the License for the specific language governing permissions and 018 * limitations under the License. 019 */ 020/* 021 * Copyright (C) 2007-2024 Ping Identity Corporation 022 * 023 * This program is free software; you can redistribute it and/or modify 024 * it under the terms of the GNU General Public License (GPLv2 only) 025 * or the terms of the GNU Lesser General Public License (LGPLv2.1 only) 026 * as published by the Free Software Foundation. 027 * 028 * This program is distributed in the hope that it will be useful, 029 * but WITHOUT ANY WARRANTY; without even the implied warranty of 030 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 031 * GNU General Public License for more details. 032 * 033 * You should have received a copy of the GNU General Public License 034 * along with this program; if not, see <http://www.gnu.org/licenses>. 035 */ 036package com.unboundid.ldap.sdk; 037 038 039 040import java.util.List; 041 042import com.unboundid.util.NotMutable; 043import com.unboundid.util.NotNull; 044import com.unboundid.util.Nullable; 045import com.unboundid.util.StaticUtils; 046import com.unboundid.util.ThreadSafety; 047import com.unboundid.util.ThreadSafetyLevel; 048 049 050 051/** 052 * This class defines an exception that can be thrown if a problem occurs while 053 * performing LDAP-related processing. It includes all of the elements of the 054 * {@link SearchResult} object, potentially including entries and references 055 * returned before the failure result. 056 */ 057@NotMutable() 058@ThreadSafety(level=ThreadSafetyLevel.COMPLETELY_THREADSAFE) 059public final class LDAPSearchException 060 extends LDAPException 061{ 062 /** 063 * The serial version UID for this serializable class. 064 */ 065 private static final long serialVersionUID = 350230437196125113L; 066 067 068 069 // The search result with information from this exception. 070 @NotNull private final SearchResult searchResult; 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 */ 080 public LDAPSearchException(@NotNull final ResultCode resultCode, 081 @NotNull final String errorMessage) 082 { 083 super(resultCode, errorMessage); 084 085 searchResult = new SearchResult(-1, resultCode, errorMessage, null, 086 StaticUtils.NO_STRINGS, 0, 0, StaticUtils.NO_CONTROLS); 087 } 088 089 090 091 /** 092 * Creates a new LDAP search exception with the provided information. 093 * 094 * @param resultCode The result code for this LDAP search exception. 095 * @param errorMessage The error message for this LDAP search exception. 096 * @param cause The underlying exception that triggered this LDAP 097 * search exception. 098 */ 099 public LDAPSearchException(@NotNull final ResultCode resultCode, 100 @NotNull final String errorMessage, 101 @Nullable final Throwable cause) 102 { 103 super(resultCode, errorMessage, cause); 104 105 searchResult = new SearchResult(-1, resultCode, errorMessage, null, 106 StaticUtils.NO_STRINGS , 0, 0, StaticUtils.NO_CONTROLS); 107 } 108 109 110 111 /** 112 * Creates a new LDAP search exception from the provided exception. 113 * 114 * @param ldapException The LDAP exception with the information to include 115 * in this LDAP search exception. 116 */ 117 public LDAPSearchException(@NotNull final LDAPException ldapException) 118 { 119 super(ldapException.getResultCode(), ldapException.getMessage(), 120 ldapException.getMatchedDN(), ldapException.getReferralURLs(), 121 ldapException.getResponseControls(), ldapException); 122 123 if (ldapException instanceof LDAPSearchException) 124 { 125 final LDAPSearchException lse = (LDAPSearchException) ldapException; 126 searchResult = lse.searchResult; 127 } 128 else 129 { 130 searchResult = new SearchResult(-1, ldapException.getResultCode(), 131 ldapException.getMessage(), 132 ldapException.getMatchedDN(), 133 ldapException.getReferralURLs(), 0, 0, 134 ldapException.getResponseControls()); 135 } 136 } 137 138 139 140 /** 141 * Creates a new LDAP search exception with the provided result. 142 * 143 * @param searchResult The search result to use to create this LDAP search 144 * exception. 145 */ 146 public LDAPSearchException(@NotNull final SearchResult searchResult) 147 { 148 super(searchResult); 149 150 this.searchResult = searchResult; 151 } 152 153 154 155 /** 156 * Retrieves the search result object associated with this LDAP search 157 * exception. 158 * 159 * @return The search result object associated with this LDAP search 160 * exception. 161 */ 162 @NotNull() 163 public SearchResult getSearchResult() 164 { 165 return searchResult; 166 } 167 168 169 170 /** 171 * Retrieves the number of matching entries returned for the search operation 172 * before this exception was thrown. 173 * 174 * @return The number of matching entries returned for the search operation 175 * before this exception was thrown. 176 */ 177 public int getEntryCount() 178 { 179 return searchResult.getEntryCount(); 180 } 181 182 183 184 /** 185 * Retrieves the number of search references returned for the search 186 * operation before this exception was thrown. 187 * 188 * @return The number of search references returned for the search operation 189 * before this exception was thrown. 190 */ 191 public int getReferenceCount() 192 { 193 return searchResult.getReferenceCount(); 194 } 195 196 197 198 /** 199 * Retrieves a list containing the matching entries returned from the search 200 * operation before this exception was thrown. This will only be available if 201 * a {@code SearchResultListener} was not used during the search. 202 * 203 * @return A list containing the matching entries returned from the search 204 * operation before this exception was thrown, or {@code null} if a 205 * {@code SearchResultListener} was used during the search. 206 */ 207 @Nullable() 208 public List<SearchResultEntry> getSearchEntries() 209 { 210 return searchResult.getSearchEntries(); 211 } 212 213 214 215 /** 216 * Retrieves a list containing the search references returned from the search 217 * operation before this exception was thrown. This will only be available if 218 * a {@code SearchResultListener} was not used during the search. 219 * 220 * @return A list containing the search references returned from the search 221 * operation before this exception was thrown, or {@code null} if a 222 * {@code SearchResultListener} was used during the search. 223 */ 224 @Nullable() 225 public List<SearchResultReference> getSearchReferences() 226 { 227 return searchResult.getSearchReferences(); 228 } 229 230 231 232 /** 233 * Creates a new {@code SearchResult} object from this exception. 234 * 235 * @return The {@code SearchResult} object created from this exception. 236 */ 237 @Override() 238 @NotNull() 239 public SearchResult toLDAPResult() 240 { 241 return searchResult; 242 } 243 244 245 246 /** 247 * Appends a string representation of this LDAP exception to the provided 248 * buffer. 249 * 250 * @param buffer The buffer to which to append a string representation of 251 * this LDAP exception. 252 */ 253 @Override() 254 public void toString(@NotNull final StringBuilder buffer) 255 { 256 super.toString(buffer); 257 } 258 259 260 261 /** 262 * {@inheritDoc} 263 */ 264 @Override() 265 public void toString(@NotNull final StringBuilder buffer, 266 final boolean includeCause, 267 final boolean includeStackTrace) 268 { 269 buffer.append("LDAPException(resultCode="); 270 buffer.append(getResultCode()); 271 buffer.append(", numEntries="); 272 buffer.append(searchResult.getEntryCount()); 273 buffer.append(", numReferences="); 274 buffer.append(searchResult.getReferenceCount()); 275 276 final String errorMessage = getMessage(); 277 final String diagnosticMessage = getDiagnosticMessage(); 278 if ((errorMessage != null) && (! errorMessage.equals(diagnosticMessage))) 279 { 280 buffer.append(", errorMessage='"); 281 buffer.append(errorMessage); 282 buffer.append('\''); 283 } 284 285 if (diagnosticMessage != null) 286 { 287 buffer.append(", diagnosticMessage='"); 288 buffer.append(diagnosticMessage); 289 buffer.append('\''); 290 } 291 292 final String matchedDN = getMatchedDN(); 293 if (matchedDN != null) 294 { 295 buffer.append(", matchedDN='"); 296 buffer.append(matchedDN); 297 buffer.append('\''); 298 } 299 300 final String[] referralURLs = getReferralURLs(); 301 if (referralURLs.length > 0) 302 { 303 buffer.append(", referralURLs={"); 304 305 for (int i=0; i < referralURLs.length; i++) 306 { 307 if (i > 0) 308 { 309 buffer.append(", "); 310 } 311 312 buffer.append('\''); 313 buffer.append(referralURLs[i]); 314 buffer.append('\''); 315 } 316 317 buffer.append('}'); 318 } 319 320 final Control[] responseControls = getResponseControls(); 321 if (responseControls.length > 0) 322 { 323 buffer.append(", responseControls={"); 324 325 for (int i=0; i < responseControls.length; i++) 326 { 327 if (i > 0) 328 { 329 buffer.append(", "); 330 } 331 332 buffer.append(responseControls[i]); 333 } 334 335 buffer.append('}'); 336 } 337 338 if (includeStackTrace) 339 { 340 buffer.append(", trace='"); 341 StaticUtils.getStackTrace(getStackTrace(), buffer); 342 buffer.append('\''); 343 } 344 345 if (includeCause || includeStackTrace) 346 { 347 final Throwable cause = getCause(); 348 if (cause != null) 349 { 350 buffer.append(", cause="); 351 buffer.append(StaticUtils.getExceptionMessage(cause, true, 352 includeStackTrace)); 353 } 354 } 355 356 final String ldapSDKVersionString = ", ldapSDKVersion=" + 357 Version.NUMERIC_VERSION_STRING + ", revision=" + Version.REVISION_ID; 358 if (buffer.indexOf(ldapSDKVersionString) < 0) 359 { 360 buffer.append(ldapSDKVersionString); 361 } 362 363 buffer.append("')"); 364 } 365}