001 /* 002 * Copyright 2009-2016 UnboundID Corp. 003 * All Rights Reserved. 004 */ 005 /* 006 * Copyright (C) 2009-2016 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 java.io.Closeable; 026 import java.util.ArrayList; 027 import java.util.Collection; 028 import java.util.EnumSet; 029 import java.util.List; 030 import java.util.Set; 031 import java.util.concurrent.TimeUnit; 032 import java.util.concurrent.TimeoutException; 033 034 import com.unboundid.asn1.ASN1OctetString; 035 import com.unboundid.ldap.sdk.extensions.StartTLSExtendedRequest; 036 import com.unboundid.ldap.sdk.schema.Schema; 037 import com.unboundid.ldif.LDIFException; 038 039 import static com.unboundid.ldap.sdk.LDAPMessages.*; 040 import static com.unboundid.util.Debug.*; 041 import static com.unboundid.util.StaticUtils.*; 042 import static com.unboundid.util.Validator.*; 043 044 045 046 /** 047 * This class provides the base class for LDAP connection pool implementations 048 * provided by the LDAP SDK for Java. 049 */ 050 public abstract class AbstractConnectionPool 051 implements LDAPInterface, Closeable 052 { 053 /** 054 * Closes this connection pool. All connections currently held in the pool 055 * that are not in use will be closed, and any outstanding connections will be 056 * automatically closed when they are released back to the pool. 057 */ 058 public abstract void close(); 059 060 061 062 /** 063 * Closes this connection pool, optionally using multiple threads to close the 064 * connections in parallel. 065 * 066 * @param unbind Indicates whether to try to send an unbind request to 067 * the server before closing the connection. 068 * @param numThreads The number of threads to use when closing the 069 * connections. 070 */ 071 public abstract void close(final boolean unbind, final int numThreads); 072 073 074 075 /** 076 * Indicates whether this connection pool has been closed. 077 * 078 * @return {@code true} if this connection pool has been closed, or 079 * {@code false} if not. 080 */ 081 public abstract boolean isClosed(); 082 083 084 085 /** 086 * Retrieves an LDAP connection from the pool. 087 * 088 * @return The LDAP connection taken from the pool. 089 * 090 * @throws LDAPException If no connection is available, or a problem occurs 091 * while creating a new connection to return. 092 */ 093 public abstract LDAPConnection getConnection() 094 throws LDAPException; 095 096 097 098 /** 099 * Releases the provided connection back to this pool. 100 * 101 * @param connection The connection to be released back to the pool. 102 */ 103 public abstract void releaseConnection(final LDAPConnection connection); 104 105 106 107 /** 108 * Indicates that the provided connection is no longer in use, but is also no 109 * longer fit for use. The provided connection will be terminated and a new 110 * connection will be created and added to the pool in its place. 111 * 112 * @param connection The defunct connection being released. 113 */ 114 public abstract void releaseDefunctConnection( 115 final LDAPConnection connection); 116 117 118 119 /** 120 * Releases the provided connection back to the pool after an exception has 121 * been encountered while processing an operation on that connection. The 122 * connection pool health check instance associated with this pool will be 123 * used to determine whether the provided connection is still valid and will 124 * either release it back for use in processing other operations on the 125 * connection or will terminate the connection and create a new one to take 126 * its place. 127 * 128 * @param connection The connection to be evaluated and released back to the 129 * pool or replaced with a new connection. 130 * @param exception The exception caught while processing an operation on 131 * the connection. 132 */ 133 public final void releaseConnectionAfterException( 134 final LDAPConnection connection, 135 final LDAPException exception) 136 { 137 final LDAPConnectionPoolHealthCheck healthCheck = getHealthCheck(); 138 139 try 140 { 141 healthCheck.ensureConnectionValidAfterException(connection, exception); 142 releaseConnection(connection); 143 } 144 catch (LDAPException le) 145 { 146 debugException(le); 147 releaseDefunctConnection(connection); 148 } 149 } 150 151 152 153 /** 154 * Releases the provided connection as defunct and creates a new connection to 155 * replace it, if possible, optionally connected to a different directory 156 * server instance than the instance with which the original connection was 157 * established. 158 * 159 * @param connection The defunct connection to be replaced. 160 * 161 * @return The newly-created connection intended to replace the provided 162 * connection. 163 * 164 * @throws LDAPException If a problem is encountered while trying to create 165 * the new connection. Note that even if an exception 166 * is thrown, then the provided connection must have 167 * been properly released as defunct. 168 */ 169 public abstract LDAPConnection replaceDefunctConnection( 170 final LDAPConnection connection) 171 throws LDAPException; 172 173 174 175 /** 176 * Attempts to replace the provided connection. However, if an exception is 177 * encountered while obtaining the new connection then an exception will be 178 * thrown based on the provided {@code Throwable} object. 179 * 180 * @param t The {@code Throwable} that was caught and prompted the 181 * connection to be replaced. 182 * @param connection The defunct connection to be replaced. 183 * 184 * @return The newly-created connection intended to replace the provided 185 * connection. 186 * 187 * @throws LDAPException If an exception is encountered while attempting to 188 * obtain the new connection. Note that this 189 * exception will be generated from the provided 190 * {@code Throwable} rather than based on the 191 * exception caught while trying to create the new 192 * connection. 193 */ 194 private LDAPConnection replaceDefunctConnection(final Throwable t, 195 final LDAPConnection connection) 196 throws LDAPException 197 { 198 try 199 { 200 return replaceDefunctConnection(connection); 201 } 202 catch (final LDAPException le) 203 { 204 debugException(le); 205 206 if (t instanceof LDAPException) 207 { 208 throw (LDAPException) t; 209 } 210 else 211 { 212 throw new LDAPException(ResultCode.LOCAL_ERROR, 213 ERR_POOL_OP_EXCEPTION.get(getExceptionMessage(t)), t); 214 } 215 } 216 } 217 218 219 220 /** 221 * Indicates whether attempts to process operations should be retried on a 222 * newly-created connection if the initial attempt fails in a manner that 223 * indicates that the connection used to process that request may no longer 224 * be valid. Only a single retry will be attempted for any operation. 225 * <BR><BR> 226 * Note that this only applies to methods used to process operations in the 227 * context pool (e.g., using methods that are part of {@code LDAPInterface}), 228 * and will not automatically be used for operations processed on connections 229 * checked out of the pool. 230 * <BR><BR> 231 * This method is provided for the purpose of backward compatibility, but new 232 * functionality has been added to control retry on a per-operation-type 233 * basis via the {@code setRetryFailedOperationsDueToInvalidConnections(Set)} 234 * method. If retry is enabled for any operation type, then this method will 235 * return {@code true}, and it will only return {@code false} if retry should 236 * not be used for any operation type. To determine the operation types for 237 * which failed operations may be retried, use the 238 * {@code getOperationTypesToRetryDueToInvalidConnections()} method. 239 * 240 * @return {@code true} if the connection pool should attempt to retry 241 * operations on a newly-created connection if they fail in a way 242 * that indicates the associated connection may no longer be usable, 243 * or {@code false} if operations should only be attempted once. 244 */ 245 public final boolean retryFailedOperationsDueToInvalidConnections() 246 { 247 return (! getOperationTypesToRetryDueToInvalidConnections().isEmpty()); 248 } 249 250 251 252 /** 253 * Retrieves the set of operation types for which operations should be 254 * retried if the initial attempt fails in a manner that indicates that the 255 * connection used to process the request may no longer be valid. 256 * 257 * @return The set of operation types for which operations should be 258 * retried if the initial attempt fails in a manner that indicates 259 * that the connection used to process the request may no longer be 260 * valid, or an empty set if retries should not be performed for any 261 * type of operation. 262 */ 263 public abstract Set<OperationType> 264 getOperationTypesToRetryDueToInvalidConnections(); 265 266 267 268 /** 269 * Specifies whether attempts to process operations should be retried on a 270 * newly-created connection if the initial attempt fails in a manner that 271 * indicates that the connection used to process that request may no longer 272 * be valid. Only a single retry will be attempted for any operation. 273 * <BR><BR> 274 * Note that this only applies to methods used to process operations in the 275 * context pool (e.g., using methods that are part of {@code LDAPInterface}), 276 * and will not automatically be used for operations processed on connections 277 * checked out of the pool. 278 * <BR><BR> 279 * This method is provided for the purpose of backward compatibility, but new 280 * functionality has been added to control retry on a per-operation-type 281 * basis via the {@code setRetryFailedOperationsDueToInvalidConnections(Set)} 282 * method. If this is called with a value of {@code true}, then retry will be 283 * enabled for all types of operations. If it is called with a value of 284 * {@code false}, then retry will be disabled for all types of operations. 285 * 286 * @param retryFailedOperationsDueToInvalidConnections 287 * Indicates whether attempts to process operations should be 288 * retried on a newly-created connection if they fail in a way 289 * that indicates the associated connection may no longer be 290 * usable. 291 */ 292 public final void setRetryFailedOperationsDueToInvalidConnections( 293 final boolean retryFailedOperationsDueToInvalidConnections) 294 { 295 if (retryFailedOperationsDueToInvalidConnections) 296 { 297 setRetryFailedOperationsDueToInvalidConnections( 298 EnumSet.allOf(OperationType.class)); 299 } 300 else 301 { 302 setRetryFailedOperationsDueToInvalidConnections( 303 EnumSet.noneOf(OperationType.class)); 304 } 305 } 306 307 308 309 /** 310 * Specifies the types of operations that should be retried on a newly-created 311 * connection if the initial attempt fails in a manner that indicates that 312 * the connection used to process the request may no longer be valid. Only a 313 * single retry will be attempted for any operation. 314 * <BR><BR> 315 * Note that this only applies to methods used to process operations in the 316 * context pool (e.g., using methods that are part of {@code LDAPInterface}), 317 * and will not automatically be used for operations processed on connections 318 * checked out of the pool. 319 * 320 * @param operationTypes The types of operations for which to retry failed 321 * operations if they fail in a way that indicates the 322 * associated connection may no longer be usable. It 323 * may be {@code null} or empty to indicate that no 324 * types of operations should be retried. 325 */ 326 public abstract void setRetryFailedOperationsDueToInvalidConnections( 327 final Set<OperationType> operationTypes); 328 329 330 331 /** 332 * Retrieves the number of connections that are currently available for use in 333 * this connection pool, if applicable. 334 * 335 * @return The number of connections that are currently available for use in 336 * this connection pool, or -1 if that is not applicable for this 337 * type of connection pool. 338 */ 339 public abstract int getCurrentAvailableConnections(); 340 341 342 343 /** 344 * Retrieves the maximum number of connections to be maintained in this 345 * connection pool, which is the maximum number of available connections that 346 * should be available at any time, if applicable. 347 * 348 * @return The number of connections to be maintained in this connection 349 * pool, or -1 if that is not applicable for this type of connection 350 * pool. 351 */ 352 public abstract int getMaximumAvailableConnections(); 353 354 355 356 /** 357 * Retrieves the set of statistics maintained for this LDAP connection pool. 358 * 359 * @return The set of statistics maintained for this LDAP connection pool. 360 */ 361 public abstract LDAPConnectionPoolStatistics getConnectionPoolStatistics(); 362 363 364 365 /** 366 * Retrieves the user-friendly name that has been assigned to this connection 367 * pool. 368 * 369 * @return The user-friendly name that has been assigned to this connection 370 * pool, or {@code null} if none has been assigned. 371 */ 372 public abstract String getConnectionPoolName(); 373 374 375 376 /** 377 * Specifies the user-friendly name that should be used for this connection 378 * pool. This name may be used in debugging to help identify the purpose of 379 * this connection pool. It will also be assigned to all connections 380 * associated with this connection pool. 381 * 382 * @param connectionPoolName The user-friendly name that should be used for 383 * this connection pool. 384 */ 385 public abstract void setConnectionPoolName(final String connectionPoolName); 386 387 388 389 /** 390 * Retrieves the health check implementation for this connection pool. 391 * 392 * @return The health check implementation for this connection pool. 393 */ 394 public abstract LDAPConnectionPoolHealthCheck getHealthCheck(); 395 396 397 398 /** 399 * Retrieves the length of time in milliseconds between periodic background 400 * health checks against the available connections in this pool. 401 * 402 * @return The length of time in milliseconds between the periodic background 403 * health checks against the available connections in this pool. 404 */ 405 public abstract long getHealthCheckIntervalMillis(); 406 407 408 409 /** 410 * Specifies the length of time in milliseconds between periodic background 411 * health checks against the available connections in this pool. 412 * 413 * @param healthCheckInterval The length of time in milliseconds between 414 * periodic background health checks against the 415 * available connections in this pool. The 416 * provided value must be greater than zero. 417 */ 418 public abstract void setHealthCheckIntervalMillis( 419 final long healthCheckInterval); 420 421 422 423 /** 424 * Performs a health check against all connections currently available in this 425 * connection pool. This should only be invoked by the connection pool health 426 * check thread. 427 */ 428 protected abstract void doHealthCheck(); 429 430 431 432 /** 433 * Retrieves the directory server root DSE using a connection from this 434 * connection pool. 435 * 436 * @return The directory server root DSE, or {@code null} if it is not 437 * available. 438 * 439 * @throws LDAPException If a problem occurs while attempting to retrieve 440 * the server root DSE. 441 */ 442 public final RootDSE getRootDSE() 443 throws LDAPException 444 { 445 final LDAPConnection conn = getConnection(); 446 447 try 448 { 449 final RootDSE rootDSE = conn.getRootDSE(); 450 releaseConnection(conn); 451 return rootDSE; 452 } 453 catch (final Throwable t) 454 { 455 throwLDAPExceptionIfShouldNotRetry(t, OperationType.SEARCH, conn); 456 457 // If we have gotten here, then we should retry the operation with a 458 // newly-created connection. 459 final LDAPConnection newConn = replaceDefunctConnection(t, conn); 460 461 try 462 { 463 final RootDSE rootDSE = newConn.getRootDSE(); 464 releaseConnection(newConn); 465 return rootDSE; 466 } 467 catch (final Throwable t2) 468 { 469 throwLDAPException(t2, newConn); 470 } 471 472 // This return statement should never be reached. 473 return null; 474 } 475 } 476 477 478 479 /** 480 * Retrieves the directory server schema definitions using a connection from 481 * this connection pool, using the subschema subentry DN contained in the 482 * server's root DSE. For directory servers containing a single schema, this 483 * should be sufficient for all purposes. For servers with multiple schemas, 484 * it may be necessary to specify the DN of the target entry for which to 485 * obtain the associated schema. 486 * 487 * @return The directory server schema definitions, or {@code null} if the 488 * schema information could not be retrieved (e.g, the client does 489 * not have permission to read the server schema). 490 * 491 * @throws LDAPException If a problem occurs while attempting to retrieve 492 * the server schema. 493 */ 494 public final Schema getSchema() 495 throws LDAPException 496 { 497 return getSchema(""); 498 } 499 500 501 502 /** 503 * Retrieves the directory server schema definitions that govern the specified 504 * entry using a connection from this connection pool. The subschemaSubentry 505 * attribute will be retrieved from the target entry, and then the appropriate 506 * schema definitions will be loaded from the entry referenced by that 507 * attribute. This may be necessary to ensure correct behavior in servers 508 * that support multiple schemas. 509 * 510 * @param entryDN The DN of the entry for which to retrieve the associated 511 * schema definitions. It may be {@code null} or an empty 512 * string if the subschemaSubentry attribute should be 513 * retrieved from the server's root DSE. 514 * 515 * @return The directory server schema definitions, or {@code null} if the 516 * schema information could not be retrieved (e.g, the client does 517 * not have permission to read the server schema). 518 * 519 * @throws LDAPException If a problem occurs while attempting to retrieve 520 * the server schema. 521 */ 522 public final Schema getSchema(final String entryDN) 523 throws LDAPException 524 { 525 final LDAPConnection conn = getConnection(); 526 527 try 528 { 529 final Schema schema = conn.getSchema(entryDN); 530 releaseConnection(conn); 531 return schema; 532 } 533 catch (Throwable t) 534 { 535 throwLDAPExceptionIfShouldNotRetry(t, OperationType.SEARCH, conn); 536 537 // If we have gotten here, then we should retry the operation with a 538 // newly-created connection. 539 final LDAPConnection newConn = replaceDefunctConnection(t, conn); 540 541 try 542 { 543 final Schema schema = newConn.getSchema(entryDN); 544 releaseConnection(newConn); 545 return schema; 546 } 547 catch (final Throwable t2) 548 { 549 throwLDAPException(t2, newConn); 550 } 551 552 // This return statement should never be reached. 553 return null; 554 } 555 } 556 557 558 559 /** 560 * Retrieves the entry with the specified DN using a connection from this 561 * connection pool. All user attributes will be requested in the entry to 562 * return. 563 * 564 * @param dn The DN of the entry to retrieve. It must not be {@code null}. 565 * 566 * @return The requested entry, or {@code null} if the target entry does not 567 * exist or no entry was returned (e.g., if the authenticated user 568 * does not have permission to read the target entry). 569 * 570 * @throws LDAPException If a problem occurs while sending the request or 571 * reading the response. 572 */ 573 public final SearchResultEntry getEntry(final String dn) 574 throws LDAPException 575 { 576 return getEntry(dn, NO_STRINGS); 577 } 578 579 580 581 /** 582 * Retrieves the entry with the specified DN using a connection from this 583 * connection pool. 584 * 585 * @param dn The DN of the entry to retrieve. It must not be 586 * {@code null}. 587 * @param attributes The set of attributes to request for the target entry. 588 * If it is {@code null}, then all user attributes will be 589 * requested. 590 * 591 * @return The requested entry, or {@code null} if the target entry does not 592 * exist or no entry was returned (e.g., if the authenticated user 593 * does not have permission to read the target entry). 594 * 595 * @throws LDAPException If a problem occurs while sending the request or 596 * reading the response. 597 */ 598 public final SearchResultEntry getEntry(final String dn, 599 final String... attributes) 600 throws LDAPException 601 { 602 final LDAPConnection conn = getConnection(); 603 604 try 605 { 606 final SearchResultEntry entry = conn.getEntry(dn, attributes); 607 releaseConnection(conn); 608 return entry; 609 } 610 catch (Throwable t) 611 { 612 throwLDAPExceptionIfShouldNotRetry(t, OperationType.SEARCH, conn); 613 614 // If we have gotten here, then we should retry the operation with a 615 // newly-created connection. 616 final LDAPConnection newConn = replaceDefunctConnection(t, conn); 617 618 try 619 { 620 final SearchResultEntry entry = newConn.getEntry(dn, attributes); 621 releaseConnection(newConn); 622 return entry; 623 } 624 catch (final Throwable t2) 625 { 626 throwLDAPException(t2, newConn); 627 } 628 629 // This return statement should never be reached. 630 return null; 631 } 632 } 633 634 635 636 /** 637 * Processes an add operation with the provided information using a connection 638 * from this connection pool. 639 * 640 * @param dn The DN of the entry to add. It must not be 641 * {@code null}. 642 * @param attributes The set of attributes to include in the entry to add. 643 * It must not be {@code null}. 644 * 645 * @return The result of processing the add operation. 646 * 647 * @throws LDAPException If the server rejects the add request, or if a 648 * problem is encountered while sending the request or 649 * reading the response. 650 */ 651 public final LDAPResult add(final String dn, final Attribute... attributes) 652 throws LDAPException 653 { 654 return add(new AddRequest(dn, attributes)); 655 } 656 657 658 659 /** 660 * Processes an add operation with the provided information using a connection 661 * from this connection pool. 662 * 663 * @param dn The DN of the entry to add. It must not be 664 * {@code null}. 665 * @param attributes The set of attributes to include in the entry to add. 666 * It must not be {@code null}. 667 * 668 * @return The result of processing the add operation. 669 * 670 * @throws LDAPException If the server rejects the add request, or if a 671 * problem is encountered while sending the request or 672 * reading the response. 673 */ 674 public final LDAPResult add(final String dn, 675 final Collection<Attribute> attributes) 676 throws LDAPException 677 { 678 return add(new AddRequest(dn, attributes)); 679 } 680 681 682 683 /** 684 * Processes an add operation with the provided information using a connection 685 * from this connection pool. 686 * 687 * @param entry The entry to add. It must not be {@code null}. 688 * 689 * @return The result of processing the add operation. 690 * 691 * @throws LDAPException If the server rejects the add request, or if a 692 * problem is encountered while sending the request or 693 * reading the response. 694 */ 695 public final LDAPResult add(final Entry entry) 696 throws LDAPException 697 { 698 return add(new AddRequest(entry)); 699 } 700 701 702 703 /** 704 * Processes an add operation with the provided information using a connection 705 * from this connection pool. 706 * 707 * @param ldifLines The lines that comprise an LDIF representation of the 708 * entry to add. It must not be empty or {@code null}. 709 * 710 * @return The result of processing the add operation. 711 * 712 * @throws LDIFException If the provided entry lines cannot be decoded as an 713 * entry in LDIF form. 714 * 715 * @throws LDAPException If the server rejects the add request, or if a 716 * problem is encountered while sending the request or 717 * reading the response. 718 */ 719 public final LDAPResult add(final String... ldifLines) 720 throws LDIFException, LDAPException 721 { 722 return add(new AddRequest(ldifLines)); 723 } 724 725 726 727 /** 728 * Processes the provided add request using a connection from this connection 729 * pool. 730 * 731 * @param addRequest The add request to be processed. It must not be 732 * {@code null}. 733 * 734 * @return The result of processing the add operation. 735 * 736 * @throws LDAPException If the server rejects the add request, or if a 737 * problem is encountered while sending the request or 738 * reading the response. 739 */ 740 public final LDAPResult add(final AddRequest addRequest) 741 throws LDAPException 742 { 743 final LDAPConnection conn = getConnection(); 744 745 try 746 { 747 final LDAPResult result = conn.add(addRequest); 748 releaseConnection(conn); 749 return result; 750 } 751 catch (Throwable t) 752 { 753 throwLDAPExceptionIfShouldNotRetry(t, OperationType.ADD, conn); 754 755 // If we have gotten here, then we should retry the operation with a 756 // newly-created connection. 757 final LDAPConnection newConn = replaceDefunctConnection(t, conn); 758 759 try 760 { 761 final LDAPResult result = newConn.add(addRequest); 762 releaseConnection(newConn); 763 return result; 764 } 765 catch (final Throwable t2) 766 { 767 throwLDAPException(t2, newConn); 768 } 769 770 // This return statement should never be reached. 771 return null; 772 } 773 } 774 775 776 777 /** 778 * Processes the provided add request using a connection from this connection 779 * pool. 780 * 781 * @param addRequest The add request to be processed. It must not be 782 * {@code null}. 783 * 784 * @return The result of processing the add operation. 785 * 786 * @throws LDAPException If the server rejects the add request, or if a 787 * problem is encountered while sending the request or 788 * reading the response. 789 */ 790 public final LDAPResult add(final ReadOnlyAddRequest addRequest) 791 throws LDAPException 792 { 793 return add((AddRequest) addRequest); 794 } 795 796 797 798 /** 799 * Processes a simple bind request with the provided DN and password using a 800 * connection from this connection pool. Note that this will impact the state 801 * of the connection in the pool, and therefore this method should only be 802 * used if this connection pool is used exclusively for processing bind 803 * operations, or if the retain identity request control (only available in 804 * the Commercial Edition of the LDAP SDK for use with the Ping Identity, 805 * UnboundID, or Alcatel-Lucent 8661 Directory Server) is included in the bind 806 * request to ensure that the authentication state is not impacted. 807 * 808 * @param bindDN The bind DN for the bind operation. 809 * @param password The password for the simple bind operation. 810 * 811 * @return The result of processing the bind operation. 812 * 813 * @throws LDAPException If the server rejects the bind request, or if a 814 * problem occurs while sending the request or reading 815 * the response. 816 */ 817 public final BindResult bind(final String bindDN, final String password) 818 throws LDAPException 819 { 820 return bind(new SimpleBindRequest(bindDN, password)); 821 } 822 823 824 825 /** 826 * Processes the provided bind request using a connection from this connection 827 * pool. Note that this will impact the state of the connection in the pool, 828 * and therefore this method should only be used if this connection pool is 829 * used exclusively for processing bind operations, or if the retain identity 830 * request control (only available in the Commercial Edition of the LDAP SDK 831 * for use with the Ping Identity, UnboundID, or Alcatel-Lucent 8661 Directory 832 * Server) is included in the bind request to ensure that the authentication 833 * state is not impacted. 834 * 835 * @param bindRequest The bind request to be processed. It must not be 836 * {@code null}. 837 * 838 * @return The result of processing the bind operation. 839 * 840 * @throws LDAPException If the server rejects the bind request, or if a 841 * problem occurs while sending the request or reading 842 * the response. 843 */ 844 public final BindResult bind(final BindRequest bindRequest) 845 throws LDAPException 846 { 847 final LDAPConnection conn = getConnection(); 848 849 try 850 { 851 final BindResult result = conn.bind(bindRequest); 852 releaseConnection(conn); 853 return result; 854 } 855 catch (Throwable t) 856 { 857 throwLDAPExceptionIfShouldNotRetry(t, OperationType.BIND, conn); 858 859 // If we have gotten here, then we should retry the operation with a 860 // newly-created connection. 861 final LDAPConnection newConn = replaceDefunctConnection(t, conn); 862 863 try 864 { 865 final BindResult result = newConn.bind(bindRequest); 866 releaseConnection(newConn); 867 return result; 868 } 869 catch (final Throwable t2) 870 { 871 throwLDAPException(t2, newConn); 872 } 873 874 // This return statement should never be reached. 875 return null; 876 } 877 } 878 879 880 881 /** 882 * Processes a compare operation with the provided information using a 883 * connection from this connection pool. 884 * 885 * @param dn The DN of the entry in which to make the 886 * comparison. It must not be {@code null}. 887 * @param attributeName The attribute name for which to make the 888 * comparison. It must not be {@code null}. 889 * @param assertionValue The assertion value to verify in the target entry. 890 * It must not be {@code null}. 891 * 892 * @return The result of processing the compare operation. 893 * 894 * @throws LDAPException If the server rejects the compare request, or if a 895 * problem is encountered while sending the request or 896 * reading the response. 897 */ 898 public final CompareResult compare(final String dn, 899 final String attributeName, 900 final String assertionValue) 901 throws LDAPException 902 { 903 return compare(new CompareRequest(dn, attributeName, assertionValue)); 904 } 905 906 907 908 /** 909 * Processes the provided compare request using a connection from this 910 * connection pool. 911 * 912 * @param compareRequest The compare request to be processed. It must not 913 * be {@code null}. 914 * 915 * @return The result of processing the compare operation. 916 * 917 * @throws LDAPException If the server rejects the compare request, or if a 918 * problem is encountered while sending the request or 919 * reading the response. 920 */ 921 public final CompareResult compare(final CompareRequest compareRequest) 922 throws LDAPException 923 { 924 final LDAPConnection conn = getConnection(); 925 926 try 927 { 928 final CompareResult result = conn.compare(compareRequest); 929 releaseConnection(conn); 930 return result; 931 } 932 catch (Throwable t) 933 { 934 throwLDAPExceptionIfShouldNotRetry(t, OperationType.COMPARE, conn); 935 936 // If we have gotten here, then we should retry the operation with a 937 // newly-created connection. 938 final LDAPConnection newConn = replaceDefunctConnection(t, conn); 939 940 try 941 { 942 final CompareResult result = newConn.compare(compareRequest); 943 releaseConnection(newConn); 944 return result; 945 } 946 catch (final Throwable t2) 947 { 948 throwLDAPException(t2, newConn); 949 } 950 951 // This return statement should never be reached. 952 return null; 953 } 954 } 955 956 957 958 /** 959 * Processes the provided compare request using a connection from this 960 * connection pool. 961 * 962 * @param compareRequest The compare request to be processed. It must not 963 * be {@code null}. 964 * 965 * @return The result of processing the compare operation. 966 * 967 * @throws LDAPException If the server rejects the compare request, or if a 968 * problem is encountered while sending the request or 969 * reading the response. 970 */ 971 public final CompareResult compare( 972 final ReadOnlyCompareRequest compareRequest) 973 throws LDAPException 974 { 975 return compare((CompareRequest) compareRequest); 976 } 977 978 979 980 /** 981 * Deletes the entry with the specified DN using a connection from this 982 * connection pool. 983 * 984 * @param dn The DN of the entry to delete. It must not be {@code null}. 985 * 986 * @return The result of processing the delete operation. 987 * 988 * @throws LDAPException If the server rejects the delete request, or if a 989 * problem is encountered while sending the request or 990 * reading the response. 991 */ 992 public final LDAPResult delete(final String dn) 993 throws LDAPException 994 { 995 return delete(new DeleteRequest(dn)); 996 } 997 998 999 1000 /** 1001 * Processes the provided delete request using a connection from this 1002 * connection pool. 1003 * 1004 * @param deleteRequest The delete request to be processed. It must not be 1005 * {@code null}. 1006 * 1007 * @return The result of processing the delete operation. 1008 * 1009 * @throws LDAPException If the server rejects the delete request, or if a 1010 * problem is encountered while sending the request or 1011 * reading the response. 1012 */ 1013 public final LDAPResult delete(final DeleteRequest deleteRequest) 1014 throws LDAPException 1015 { 1016 final LDAPConnection conn = getConnection(); 1017 1018 try 1019 { 1020 final LDAPResult result = conn.delete(deleteRequest); 1021 releaseConnection(conn); 1022 return result; 1023 } 1024 catch (Throwable t) 1025 { 1026 throwLDAPExceptionIfShouldNotRetry(t, OperationType.DELETE, conn); 1027 1028 // If we have gotten here, then we should retry the operation with a 1029 // newly-created connection. 1030 final LDAPConnection newConn = replaceDefunctConnection(t, conn); 1031 1032 try 1033 { 1034 final LDAPResult result = newConn.delete(deleteRequest); 1035 releaseConnection(newConn); 1036 return result; 1037 } 1038 catch (final Throwable t2) 1039 { 1040 throwLDAPException(t2, newConn); 1041 } 1042 1043 // This return statement should never be reached. 1044 return null; 1045 } 1046 } 1047 1048 1049 1050 /** 1051 * Processes the provided delete request using a connection from this 1052 * connection pool. 1053 * 1054 * @param deleteRequest The delete request to be processed. It must not be 1055 * {@code null}. 1056 * 1057 * @return The result of processing the delete operation. 1058 * 1059 * @throws LDAPException If the server rejects the delete request, or if a 1060 * problem is encountered while sending the request or 1061 * reading the response. 1062 */ 1063 public final LDAPResult delete(final ReadOnlyDeleteRequest deleteRequest) 1064 throws LDAPException 1065 { 1066 return delete((DeleteRequest) deleteRequest); 1067 } 1068 1069 1070 1071 /** 1072 * Processes an extended operation with the provided request OID using a 1073 * connection from this connection pool. Note that this method should not be 1074 * used to perform any operation that will alter the state of the connection 1075 * in the pool (e.g., a StartTLS operation) or that involves multiple 1076 * distinct operations on the same connection (e.g., LDAP transactions). 1077 * 1078 * @param requestOID The OID for the extended request to process. It must 1079 * not be {@code null}. 1080 * 1081 * @return The extended result object that provides information about the 1082 * result of the request processing. 1083 * 1084 * @throws LDAPException If a problem occurs while sending the request or 1085 * reading the response. 1086 */ 1087 public final ExtendedResult processExtendedOperation(final String requestOID) 1088 throws LDAPException 1089 { 1090 return processExtendedOperation(new ExtendedRequest(requestOID)); 1091 } 1092 1093 1094 1095 /** 1096 * Processes an extended operation with the provided request OID and value 1097 * using a connection from this connection pool. Note that this method should 1098 * not be used to perform any operation that will alter the state of the 1099 * connection in the pool (e.g., a StartTLS operation) or that involves 1100 * multiple distinct operations on the same connection (e.g., LDAP 1101 * transactions). 1102 * 1103 * @param requestOID The OID for the extended request to process. It must 1104 * not be {@code null}. 1105 * @param requestValue The encoded value for the extended request to 1106 * process. It may be {@code null} if there does not 1107 * need to be a value for the requested operation. 1108 * 1109 * @return The extended result object that provides information about the 1110 * result of the request processing. 1111 * 1112 * @throws LDAPException If a problem occurs while sending the request or 1113 * reading the response. 1114 */ 1115 public final ExtendedResult processExtendedOperation(final String requestOID, 1116 final ASN1OctetString requestValue) 1117 throws LDAPException 1118 { 1119 return processExtendedOperation(new ExtendedRequest(requestOID, 1120 requestValue)); 1121 } 1122 1123 1124 1125 /** 1126 * Processes the provided extended request using a connection from this 1127 * connection pool. Note that this method should not be used to perform any 1128 * operation that will alter the state of the connection in the pool (e.g., a 1129 * StartTLS operation) or that involves multiple distinct operations on the 1130 * same connection (e.g., LDAP transactions). 1131 * 1132 * @param extendedRequest The extended request to be processed. It must not 1133 * be {@code null}. 1134 * 1135 * @return The extended result object that provides information about the 1136 * result of the request processing. 1137 * 1138 * @throws LDAPException If a problem occurs while sending the request or 1139 * reading the response. 1140 */ 1141 public final ExtendedResult processExtendedOperation( 1142 final ExtendedRequest extendedRequest) 1143 throws LDAPException 1144 { 1145 if (extendedRequest.getOID().equals( 1146 StartTLSExtendedRequest.STARTTLS_REQUEST_OID)) 1147 { 1148 throw new LDAPException(ResultCode.NOT_SUPPORTED, 1149 ERR_POOL_STARTTLS_NOT_ALLOWED.get()); 1150 } 1151 1152 final LDAPConnection conn = getConnection(); 1153 1154 try 1155 { 1156 final ExtendedResult result = 1157 conn.processExtendedOperation(extendedRequest); 1158 releaseConnection(conn); 1159 return result; 1160 } 1161 catch (Throwable t) 1162 { 1163 throwLDAPExceptionIfShouldNotRetry(t, OperationType.EXTENDED, conn); 1164 1165 // If we have gotten here, then we should retry the operation with a 1166 // newly-created connection. 1167 final LDAPConnection newConn = replaceDefunctConnection(t, conn); 1168 1169 try 1170 { 1171 final ExtendedResult result = 1172 newConn.processExtendedOperation(extendedRequest); 1173 releaseConnection(newConn); 1174 return result; 1175 } 1176 catch (final Throwable t2) 1177 { 1178 throwLDAPException(t2, newConn); 1179 } 1180 1181 // This return statement should never be reached. 1182 return null; 1183 } 1184 } 1185 1186 1187 1188 /** 1189 * Applies the provided modification to the specified entry using a connection 1190 * from this connection pool. 1191 * 1192 * @param dn The DN of the entry to modify. It must not be {@code null}. 1193 * @param mod The modification to apply to the target entry. It must not 1194 * be {@code null}. 1195 * 1196 * @return The result of processing the modify operation. 1197 * 1198 * @throws LDAPException If the server rejects the modify request, or if a 1199 * problem is encountered while sending the request or 1200 * reading the response. 1201 */ 1202 public final LDAPResult modify(final String dn, final Modification mod) 1203 throws LDAPException 1204 { 1205 return modify(new ModifyRequest(dn, mod)); 1206 } 1207 1208 1209 1210 /** 1211 * Applies the provided set of modifications to the specified entry using a 1212 * connection from this connection pool. 1213 * 1214 * @param dn The DN of the entry to modify. It must not be {@code null}. 1215 * @param mods The set of modifications to apply to the target entry. It 1216 * must not be {@code null} or empty. * 1217 * @return The result of processing the modify operation. 1218 * 1219 * @throws LDAPException If the server rejects the modify request, or if a 1220 * problem is encountered while sending the request or 1221 * reading the response. 1222 */ 1223 public final LDAPResult modify(final String dn, final Modification... mods) 1224 throws LDAPException 1225 { 1226 return modify(new ModifyRequest(dn, mods)); 1227 } 1228 1229 1230 1231 /** 1232 * Applies the provided set of modifications to the specified entry using a 1233 * connection from this connection pool. 1234 * 1235 * @param dn The DN of the entry to modify. It must not be {@code null}. 1236 * @param mods The set of modifications to apply to the target entry. It 1237 * must not be {@code null} or empty. 1238 * 1239 * @return The result of processing the modify operation. 1240 * 1241 * @throws LDAPException If the server rejects the modify request, or if a 1242 * problem is encountered while sending the request or 1243 * reading the response. 1244 */ 1245 public final LDAPResult modify(final String dn, final List<Modification> mods) 1246 throws LDAPException 1247 { 1248 return modify(new ModifyRequest(dn, mods)); 1249 } 1250 1251 1252 1253 /** 1254 * Processes a modify request from the provided LDIF representation of the 1255 * changes using a connection from this connection pool. 1256 * 1257 * @param ldifModificationLines The lines that comprise an LDIF 1258 * representation of a modify change record. 1259 * It must not be {@code null} or empty. 1260 * 1261 * @return The result of processing the modify operation. 1262 * 1263 * @throws LDIFException If the provided set of lines cannot be parsed as an 1264 * LDIF modify change record. 1265 * 1266 * @throws LDAPException If the server rejects the modify request, or if a 1267 * problem is encountered while sending the request or 1268 * reading the response. 1269 * 1270 */ 1271 public final LDAPResult modify(final String... ldifModificationLines) 1272 throws LDIFException, LDAPException 1273 { 1274 return modify(new ModifyRequest(ldifModificationLines)); 1275 } 1276 1277 1278 1279 /** 1280 * Processes the provided modify request using a connection from this 1281 * connection pool. 1282 * 1283 * @param modifyRequest The modify request to be processed. It must not be 1284 * {@code null}. 1285 * 1286 * @return The result of processing the modify operation. 1287 * 1288 * @throws LDAPException If the server rejects the modify request, or if a 1289 * problem is encountered while sending the request or 1290 * reading the response. 1291 */ 1292 public final LDAPResult modify(final ModifyRequest modifyRequest) 1293 throws LDAPException 1294 { 1295 final LDAPConnection conn = getConnection(); 1296 1297 try 1298 { 1299 final LDAPResult result = conn.modify(modifyRequest); 1300 releaseConnection(conn); 1301 return result; 1302 } 1303 catch (Throwable t) 1304 { 1305 throwLDAPExceptionIfShouldNotRetry(t, OperationType.MODIFY, conn); 1306 1307 // If we have gotten here, then we should retry the operation with a 1308 // newly-created connection. 1309 final LDAPConnection newConn = replaceDefunctConnection(t, conn); 1310 1311 try 1312 { 1313 final LDAPResult result = newConn.modify(modifyRequest); 1314 releaseConnection(newConn); 1315 return result; 1316 } 1317 catch (final Throwable t2) 1318 { 1319 throwLDAPException(t2, newConn); 1320 } 1321 1322 // This return statement should never be reached. 1323 return null; 1324 } 1325 } 1326 1327 1328 1329 /** 1330 * Processes the provided modify request using a connection from this 1331 * connection pool. 1332 * 1333 * @param modifyRequest The modify request to be processed. It must not be 1334 * {@code null}. 1335 * 1336 * @return The result of processing the modify operation. 1337 * 1338 * @throws LDAPException If the server rejects the modify request, or if a 1339 * problem is encountered while sending the request or 1340 * reading the response. 1341 */ 1342 public final LDAPResult modify(final ReadOnlyModifyRequest modifyRequest) 1343 throws LDAPException 1344 { 1345 return modify((ModifyRequest) modifyRequest); 1346 } 1347 1348 1349 1350 /** 1351 * Performs a modify DN operation with the provided information using a 1352 * connection from this connection pool. 1353 * 1354 * @param dn The current DN for the entry to rename. It must not 1355 * be {@code null}. 1356 * @param newRDN The new RDN to use for the entry. It must not be 1357 * {@code null}. 1358 * @param deleteOldRDN Indicates whether to delete the current RDN value 1359 * from the entry. 1360 * 1361 * @return The result of processing the modify DN operation. 1362 * 1363 * @throws LDAPException If the server rejects the modify DN request, or if 1364 * a problem is encountered while sending the request 1365 * or reading the response. 1366 */ 1367 public final LDAPResult modifyDN(final String dn, final String newRDN, 1368 final boolean deleteOldRDN) 1369 throws LDAPException 1370 { 1371 return modifyDN(new ModifyDNRequest(dn, newRDN, deleteOldRDN)); 1372 } 1373 1374 1375 1376 /** 1377 * Performs a modify DN operation with the provided information using a 1378 * connection from this connection pool. 1379 * 1380 * @param dn The current DN for the entry to rename. It must not 1381 * be {@code null}. 1382 * @param newRDN The new RDN to use for the entry. It must not be 1383 * {@code null}. 1384 * @param deleteOldRDN Indicates whether to delete the current RDN value 1385 * from the entry. 1386 * @param newSuperiorDN The new superior DN for the entry. It may be 1387 * {@code null} if the entry is not to be moved below a 1388 * new parent. 1389 * 1390 * @return The result of processing the modify DN operation. 1391 * 1392 * @throws LDAPException If the server rejects the modify DN request, or if 1393 * a problem is encountered while sending the request 1394 * or reading the response. 1395 */ 1396 public final LDAPResult modifyDN(final String dn, final String newRDN, 1397 final boolean deleteOldRDN, 1398 final String newSuperiorDN) 1399 throws LDAPException 1400 { 1401 return modifyDN(new ModifyDNRequest(dn, newRDN, deleteOldRDN, 1402 newSuperiorDN)); 1403 } 1404 1405 1406 1407 /** 1408 * Processes the provided modify DN request using a connection from this 1409 * connection pool. 1410 * 1411 * @param modifyDNRequest The modify DN request to be processed. It must 1412 * not be {@code null}. 1413 * 1414 * @return The result of processing the modify DN operation. 1415 * 1416 * @throws LDAPException If the server rejects the modify DN request, or if 1417 * a problem is encountered while sending the request 1418 * or reading the response. 1419 */ 1420 public final LDAPResult modifyDN(final ModifyDNRequest modifyDNRequest) 1421 throws LDAPException 1422 { 1423 final LDAPConnection conn = getConnection(); 1424 1425 try 1426 { 1427 final LDAPResult result = conn.modifyDN(modifyDNRequest); 1428 releaseConnection(conn); 1429 return result; 1430 } 1431 catch (Throwable t) 1432 { 1433 throwLDAPExceptionIfShouldNotRetry(t, OperationType.MODIFY_DN, conn); 1434 1435 // If we have gotten here, then we should retry the operation with a 1436 // newly-created connection. 1437 final LDAPConnection newConn = replaceDefunctConnection(t, conn); 1438 1439 try 1440 { 1441 final LDAPResult result = newConn.modifyDN(modifyDNRequest); 1442 releaseConnection(newConn); 1443 return result; 1444 } 1445 catch (final Throwable t2) 1446 { 1447 throwLDAPException(t2, newConn); 1448 } 1449 1450 // This return statement should never be reached. 1451 return null; 1452 } 1453 } 1454 1455 1456 1457 /** 1458 * Processes the provided modify DN request using a connection from this 1459 * connection pool. 1460 * 1461 * @param modifyDNRequest The modify DN request to be processed. It must 1462 * not be {@code null}. 1463 * 1464 * @return The result of processing the modify DN operation. 1465 * 1466 * @throws LDAPException If the server rejects the modify DN request, or if 1467 * a problem is encountered while sending the request 1468 * or reading the response. 1469 */ 1470 public final LDAPResult modifyDN( 1471 final ReadOnlyModifyDNRequest modifyDNRequest) 1472 throws LDAPException 1473 { 1474 return modifyDN((ModifyDNRequest) modifyDNRequest); 1475 } 1476 1477 1478 1479 /** 1480 * Processes a search operation with the provided information using a 1481 * connection from this connection pool. The search result entries and 1482 * references will be collected internally and included in the 1483 * {@code SearchResult} object that is returned. 1484 * <BR><BR> 1485 * Note that if the search does not complete successfully, an 1486 * {@code LDAPSearchException} will be thrown In some cases, one or more 1487 * search result entries or references may have been returned before the 1488 * failure response is received. In this case, the 1489 * {@code LDAPSearchException} methods like {@code getEntryCount}, 1490 * {@code getSearchEntries}, {@code getReferenceCount}, and 1491 * {@code getSearchReferences} may be used to obtain information about those 1492 * entries and references. 1493 * 1494 * @param baseDN The base DN for the search request. It must not be 1495 * {@code null}. 1496 * @param scope The scope that specifies the range of entries that 1497 * should be examined for the search. 1498 * @param filter The string representation of the filter to use to 1499 * identify matching entries. It must not be 1500 * {@code null}. 1501 * @param attributes The set of attributes that should be returned in 1502 * matching entries. It may be {@code null} or empty if 1503 * the default attribute set (all user attributes) is to 1504 * be requested. 1505 * 1506 * @return A search result object that provides information about the 1507 * processing of the search, including the set of matching entries 1508 * and search references returned by the server. 1509 * 1510 * @throws LDAPSearchException If the search does not complete successfully, 1511 * or if a problem is encountered while parsing 1512 * the provided filter string, sending the 1513 * request, or reading the response. If one or 1514 * more entries or references were returned 1515 * before the failure was encountered, then the 1516 * {@code LDAPSearchException} object may be 1517 * examined to obtain information about those 1518 * entries and/or references. 1519 */ 1520 public final SearchResult search(final String baseDN, final SearchScope scope, 1521 final String filter, 1522 final String... attributes) 1523 throws LDAPSearchException 1524 { 1525 return search(new SearchRequest(baseDN, scope, parseFilter(filter), 1526 attributes)); 1527 } 1528 1529 1530 1531 /** 1532 * Processes a search operation with the provided information using a 1533 * connection from this connection pool. The search result entries and 1534 * references will be collected internally and included in the 1535 * {@code SearchResult} object that is returned. 1536 * <BR><BR> 1537 * Note that if the search does not complete successfully, an 1538 * {@code LDAPSearchException} will be thrown In some cases, one or more 1539 * search result entries or references may have been returned before the 1540 * failure response is received. In this case, the 1541 * {@code LDAPSearchException} methods like {@code getEntryCount}, 1542 * {@code getSearchEntries}, {@code getReferenceCount}, and 1543 * {@code getSearchReferences} may be used to obtain information about those 1544 * entries and references. 1545 * 1546 * @param baseDN The base DN for the search request. It must not be 1547 * {@code null}. 1548 * @param scope The scope that specifies the range of entries that 1549 * should be examined for the search. 1550 * @param filter The filter to use to identify matching entries. It 1551 * must not be {@code null}. 1552 * @param attributes The set of attributes that should be returned in 1553 * matching entries. It may be {@code null} or empty if 1554 * the default attribute set (all user attributes) is to 1555 * be requested. 1556 * 1557 * @return A search result object that provides information about the 1558 * processing of the search, including the set of matching entries 1559 * and search references returned by the server. 1560 * 1561 * @throws LDAPSearchException If the search does not complete successfully, 1562 * or if a problem is encountered while sending 1563 * the request or reading the response. If one 1564 * or more entries or references were returned 1565 * before the failure was encountered, then the 1566 * {@code LDAPSearchException} object may be 1567 * examined to obtain information about those 1568 * entries and/or references. 1569 */ 1570 public final SearchResult search(final String baseDN, final SearchScope scope, 1571 final Filter filter, 1572 final String... attributes) 1573 throws LDAPSearchException 1574 { 1575 return search(new SearchRequest(baseDN, scope, filter, attributes)); 1576 } 1577 1578 1579 1580 /** 1581 * Processes a search operation with the provided information using a 1582 * connection from this connection pool. 1583 * <BR><BR> 1584 * Note that if the search does not complete successfully, an 1585 * {@code LDAPSearchException} will be thrown In some cases, one or more 1586 * search result entries or references may have been returned before the 1587 * failure response is received. In this case, the 1588 * {@code LDAPSearchException} methods like {@code getEntryCount}, 1589 * {@code getSearchEntries}, {@code getReferenceCount}, and 1590 * {@code getSearchReferences} may be used to obtain information about those 1591 * entries and references (although if a search result listener was provided, 1592 * then it will have been used to make any entries and references available, 1593 * and they will not be available through the {@code getSearchEntries} and 1594 * {@code getSearchReferences} methods). 1595 * 1596 * @param searchResultListener The search result listener that should be 1597 * used to return results to the client. It may 1598 * be {@code null} if the search results should 1599 * be collected internally and returned in the 1600 * {@code SearchResult} object. 1601 * @param baseDN The base DN for the search request. It must 1602 * not be {@code null}. 1603 * @param scope The scope that specifies the range of entries 1604 * that should be examined for the search. 1605 * @param filter The string representation of the filter to 1606 * use to identify matching entries. It must 1607 * not be {@code null}. 1608 * @param attributes The set of attributes that should be returned 1609 * in matching entries. It may be {@code null} 1610 * or empty if the default attribute set (all 1611 * user attributes) is to be requested. 1612 * 1613 * @return A search result object that provides information about the 1614 * processing of the search, potentially including the set of 1615 * matching entries and search references returned by the server. 1616 * 1617 * @throws LDAPSearchException If the search does not complete successfully, 1618 * or if a problem is encountered while parsing 1619 * the provided filter string, sending the 1620 * request, or reading the response. If one 1621 * or more entries or references were returned 1622 * before the failure was encountered, then the 1623 * {@code LDAPSearchException} object may be 1624 * examined to obtain information about those 1625 * entries and/or references. 1626 */ 1627 public final SearchResult 1628 search(final SearchResultListener searchResultListener, 1629 final String baseDN, final SearchScope scope, final String filter, 1630 final String... attributes) 1631 throws LDAPSearchException 1632 { 1633 return search(new SearchRequest(searchResultListener, baseDN, scope, 1634 parseFilter(filter), attributes)); 1635 } 1636 1637 1638 1639 /** 1640 * Processes a search operation with the provided information using a 1641 * connection from this connection pool. 1642 * <BR><BR> 1643 * Note that if the search does not complete successfully, an 1644 * {@code LDAPSearchException} will be thrown In some cases, one or more 1645 * search result entries or references may have been returned before the 1646 * failure response is received. In this case, the 1647 * {@code LDAPSearchException} methods like {@code getEntryCount}, 1648 * {@code getSearchEntries}, {@code getReferenceCount}, and 1649 * {@code getSearchReferences} may be used to obtain information about those 1650 * entries and references (although if a search result listener was provided, 1651 * then it will have been used to make any entries and references available, 1652 * and they will not be available through the {@code getSearchEntries} and 1653 * {@code getSearchReferences} methods). 1654 * 1655 * @param searchResultListener The search result listener that should be 1656 * used to return results to the client. It may 1657 * be {@code null} if the search results should 1658 * be collected internally and returned in the 1659 * {@code SearchResult} object. 1660 * @param baseDN The base DN for the search request. It must 1661 * not be {@code null}. 1662 * @param scope The scope that specifies the range of entries 1663 * that should be examined for the search. 1664 * @param filter The filter to use to identify matching 1665 * entries. It must not be {@code null}. 1666 * @param attributes The set of attributes that should be returned 1667 * in matching entries. It may be {@code null} 1668 * or empty if the default attribute set (all 1669 * user attributes) is to be requested. 1670 * 1671 * @return A search result object that provides information about the 1672 * processing of the search, potentially including the set of 1673 * matching entries and search references returned by the server. 1674 * 1675 * @throws LDAPSearchException If the search does not complete successfully, 1676 * or if a problem is encountered while sending 1677 * the request or reading the response. If one 1678 * or more entries or references were returned 1679 * before the failure was encountered, then the 1680 * {@code LDAPSearchException} object may be 1681 * examined to obtain information about those 1682 * entries and/or references. 1683 */ 1684 public final SearchResult 1685 search(final SearchResultListener searchResultListener, 1686 final String baseDN, final SearchScope scope, final Filter filter, 1687 final String... attributes) 1688 throws LDAPSearchException 1689 { 1690 return search(new SearchRequest(searchResultListener, baseDN, scope, 1691 filter, attributes)); 1692 } 1693 1694 1695 1696 /** 1697 * Processes a search operation with the provided information using a 1698 * connection from this connection pool. The search result entries and 1699 * references will be collected internally and included in the 1700 * {@code SearchResult} object that is returned. 1701 * <BR><BR> 1702 * Note that if the search does not complete successfully, an 1703 * {@code LDAPSearchException} will be thrown In some cases, one or more 1704 * search result entries or references may have been returned before the 1705 * failure response is received. In this case, the 1706 * {@code LDAPSearchException} methods like {@code getEntryCount}, 1707 * {@code getSearchEntries}, {@code getReferenceCount}, and 1708 * {@code getSearchReferences} may be used to obtain information about those 1709 * entries and references. 1710 * 1711 * @param baseDN The base DN for the search request. It must not be 1712 * {@code null}. 1713 * @param scope The scope that specifies the range of entries that 1714 * should be examined for the search. 1715 * @param derefPolicy The dereference policy the server should use for any 1716 * aliases encountered while processing the search. 1717 * @param sizeLimit The maximum number of entries that the server should 1718 * return for the search. A value of zero indicates that 1719 * there should be no limit. 1720 * @param timeLimit The maximum length of time in seconds that the server 1721 * should spend processing this search request. A value 1722 * of zero indicates that there should be no limit. 1723 * @param typesOnly Indicates whether to return only attribute names in 1724 * matching entries, or both attribute names and values. 1725 * @param filter The string representation of the filter to use to 1726 * identify matching entries. It must not be 1727 * {@code null}. 1728 * @param attributes The set of attributes that should be returned in 1729 * matching entries. It may be {@code null} or empty if 1730 * the default attribute set (all user attributes) is to 1731 * be requested. 1732 * 1733 * @return A search result object that provides information about the 1734 * processing of the search, including the set of matching entries 1735 * and search references returned by the server. 1736 * 1737 * @throws LDAPSearchException If the search does not complete successfully, 1738 * or if a problem is encountered while parsing 1739 * the provided filter string, sending the 1740 * request, or reading the response. If one 1741 * or more entries or references were returned 1742 * before the failure was encountered, then the 1743 * {@code LDAPSearchException} object may be 1744 * examined to obtain information about those 1745 * entries and/or references. 1746 */ 1747 public final SearchResult search(final String baseDN, final SearchScope scope, 1748 final DereferencePolicy derefPolicy, 1749 final int sizeLimit, final int timeLimit, 1750 final boolean typesOnly, final String filter, 1751 final String... attributes) 1752 throws LDAPSearchException 1753 { 1754 return search(new SearchRequest(baseDN, scope, derefPolicy, sizeLimit, 1755 timeLimit, typesOnly, parseFilter(filter), attributes)); 1756 } 1757 1758 1759 1760 /** 1761 * Processes a search operation with the provided information using a 1762 * connection from this connection pool. The search result entries and 1763 * references will be collected internally and included in the 1764 * {@code SearchResult} object that is returned. 1765 * <BR><BR> 1766 * Note that if the search does not complete successfully, an 1767 * {@code LDAPSearchException} will be thrown In some cases, one or more 1768 * search result entries or references may have been returned before the 1769 * failure response is received. In this case, the 1770 * {@code LDAPSearchException} methods like {@code getEntryCount}, 1771 * {@code getSearchEntries}, {@code getReferenceCount}, and 1772 * {@code getSearchReferences} may be used to obtain information about those 1773 * entries and references. 1774 * 1775 * @param baseDN The base DN for the search request. It must not be 1776 * {@code null}. 1777 * @param scope The scope that specifies the range of entries that 1778 * should be examined for the search. 1779 * @param derefPolicy The dereference policy the server should use for any 1780 * aliases encountered while processing the search. 1781 * @param sizeLimit The maximum number of entries that the server should 1782 * return for the search. A value of zero indicates that 1783 * there should be no limit. 1784 * @param timeLimit The maximum length of time in seconds that the server 1785 * should spend processing this search request. A value 1786 * of zero indicates that there should be no limit. 1787 * @param typesOnly Indicates whether to return only attribute names in 1788 * matching entries, or both attribute names and values. 1789 * @param filter The filter to use to identify matching entries. It 1790 * must not be {@code null}. 1791 * @param attributes The set of attributes that should be returned in 1792 * matching entries. It may be {@code null} or empty if 1793 * the default attribute set (all user attributes) is to 1794 * be requested. 1795 * 1796 * @return A search result object that provides information about the 1797 * processing of the search, including the set of matching entries 1798 * and search references returned by the server. 1799 * 1800 * @throws LDAPSearchException If the search does not complete successfully, 1801 * or if a problem is encountered while sending 1802 * the request or reading the response. If one 1803 * or more entries or references were returned 1804 * before the failure was encountered, then the 1805 * {@code LDAPSearchException} object may be 1806 * examined to obtain information about those 1807 * entries and/or references. 1808 */ 1809 public final SearchResult search(final String baseDN, final SearchScope scope, 1810 final DereferencePolicy derefPolicy, 1811 final int sizeLimit, final int timeLimit, 1812 final boolean typesOnly, final Filter filter, 1813 final String... attributes) 1814 throws LDAPSearchException 1815 { 1816 return search(new SearchRequest(baseDN, scope, derefPolicy, sizeLimit, 1817 timeLimit, typesOnly, filter, attributes)); 1818 } 1819 1820 1821 1822 /** 1823 * Processes a search operation with the provided information using a 1824 * connection from this connection pool. 1825 * <BR><BR> 1826 * Note that if the search does not complete successfully, an 1827 * {@code LDAPSearchException} will be thrown In some cases, one or more 1828 * search result entries or references may have been returned before the 1829 * failure response is received. In this case, the 1830 * {@code LDAPSearchException} methods like {@code getEntryCount}, 1831 * {@code getSearchEntries}, {@code getReferenceCount}, and 1832 * {@code getSearchReferences} may be used to obtain information about those 1833 * entries and references (although if a search result listener was provided, 1834 * then it will have been used to make any entries and references available, 1835 * and they will not be available through the {@code getSearchEntries} and 1836 * {@code getSearchReferences} methods). 1837 * 1838 * @param searchResultListener The search result listener that should be 1839 * used to return results to the client. It may 1840 * be {@code null} if the search results should 1841 * be collected internally and returned in the 1842 * {@code SearchResult} object. 1843 * @param baseDN The base DN for the search request. It must 1844 * not be {@code null}. 1845 * @param scope The scope that specifies the range of entries 1846 * that should be examined for the search. 1847 * @param derefPolicy The dereference policy the server should use 1848 * for any aliases encountered while processing 1849 * the search. 1850 * @param sizeLimit The maximum number of entries that the server 1851 * should return for the search. A value of 1852 * zero indicates that there should be no limit. 1853 * @param timeLimit The maximum length of time in seconds that 1854 * the server should spend processing this 1855 * search request. A value of zero indicates 1856 * that there should be no limit. 1857 * @param typesOnly Indicates whether to return only attribute 1858 * names in matching entries, or both attribute 1859 * names and values. 1860 * @param filter The string representation of the filter to 1861 * use to identify matching entries. It must 1862 * not be {@code null}. 1863 * @param attributes The set of attributes that should be returned 1864 * in matching entries. It may be {@code null} 1865 * or empty if the default attribute set (all 1866 * user attributes) is to be requested. 1867 * 1868 * @return A search result object that provides information about the 1869 * processing of the search, potentially including the set of 1870 * matching entries and search references returned by the server. 1871 * 1872 * @throws LDAPSearchException If the search does not complete successfully, 1873 * or if a problem is encountered while parsing 1874 * the provided filter string, sending the 1875 * request, or reading the response. If one 1876 * or more entries or references were returned 1877 * before the failure was encountered, then the 1878 * {@code LDAPSearchException} object may be 1879 * examined to obtain information about those 1880 * entries and/or references. 1881 */ 1882 public final SearchResult 1883 search(final SearchResultListener searchResultListener, 1884 final String baseDN, final SearchScope scope, 1885 final DereferencePolicy derefPolicy, final int sizeLimit, 1886 final int timeLimit, final boolean typesOnly, final String filter, 1887 final String... attributes) 1888 throws LDAPSearchException 1889 { 1890 return search(new SearchRequest(searchResultListener, baseDN, scope, 1891 derefPolicy, sizeLimit, timeLimit, typesOnly, parseFilter(filter), 1892 attributes)); 1893 } 1894 1895 1896 1897 /** 1898 * Processes a search operation with the provided information using a 1899 * connection from this connection pool. 1900 * <BR><BR> 1901 * Note that if the search does not complete successfully, an 1902 * {@code LDAPSearchException} will be thrown In some cases, one or more 1903 * search result entries or references may have been returned before the 1904 * failure response is received. In this case, the 1905 * {@code LDAPSearchException} methods like {@code getEntryCount}, 1906 * {@code getSearchEntries}, {@code getReferenceCount}, and 1907 * {@code getSearchReferences} may be used to obtain information about those 1908 * entries and references (although if a search result listener was provided, 1909 * then it will have been used to make any entries and references available, 1910 * and they will not be available through the {@code getSearchEntries} and 1911 * {@code getSearchReferences} methods). 1912 * 1913 * @param searchResultListener The search result listener that should be 1914 * used to return results to the client. It may 1915 * be {@code null} if the search results should 1916 * be collected internally and returned in the 1917 * {@code SearchResult} object. 1918 * @param baseDN The base DN for the search request. It must 1919 * not be {@code null}. 1920 * @param scope The scope that specifies the range of entries 1921 * that should be examined for the search. 1922 * @param derefPolicy The dereference policy the server should use 1923 * for any aliases encountered while processing 1924 * the search. 1925 * @param sizeLimit The maximum number of entries that the server 1926 * should return for the search. A value of 1927 * zero indicates that there should be no limit. 1928 * @param timeLimit The maximum length of time in seconds that 1929 * the server should spend processing this 1930 * search request. A value of zero indicates 1931 * that there should be no limit. 1932 * @param typesOnly Indicates whether to return only attribute 1933 * names in matching entries, or both attribute 1934 * names and values. 1935 * @param filter The filter to use to identify matching 1936 * entries. It must not be {@code null}. 1937 * @param attributes The set of attributes that should be returned 1938 * in matching entries. It may be {@code null} 1939 * or empty if the default attribute set (all 1940 * user attributes) is to be requested. 1941 * 1942 * @return A search result object that provides information about the 1943 * processing of the search, potentially including the set of 1944 * matching entries and search references returned by the server. 1945 * 1946 * @throws LDAPSearchException If the search does not complete successfully, 1947 * or if a problem is encountered while sending 1948 * the request or reading the response. If one 1949 * or more entries or references were returned 1950 * before the failure was encountered, then the 1951 * {@code LDAPSearchException} object may be 1952 * examined to obtain information about those 1953 * entries and/or references. 1954 */ 1955 public final SearchResult 1956 search(final SearchResultListener searchResultListener, 1957 final String baseDN, final SearchScope scope, 1958 final DereferencePolicy derefPolicy, final int sizeLimit, 1959 final int timeLimit, final boolean typesOnly, 1960 final Filter filter, final String... attributes) 1961 throws LDAPSearchException 1962 { 1963 return search(new SearchRequest(searchResultListener, baseDN, scope, 1964 derefPolicy, sizeLimit, timeLimit, typesOnly, filter, attributes)); 1965 } 1966 1967 1968 1969 /** 1970 * Processes the provided search request using a connection from this 1971 * connection pool. 1972 * <BR><BR> 1973 * Note that if the search does not complete successfully, an 1974 * {@code LDAPSearchException} will be thrown In some cases, one or more 1975 * search result entries or references may have been returned before the 1976 * failure response is received. In this case, the 1977 * {@code LDAPSearchException} methods like {@code getEntryCount}, 1978 * {@code getSearchEntries}, {@code getReferenceCount}, and 1979 * {@code getSearchReferences} may be used to obtain information about those 1980 * entries and references (although if a search result listener was provided, 1981 * then it will have been used to make any entries and references available, 1982 * and they will not be available through the {@code getSearchEntries} and 1983 * {@code getSearchReferences} methods). 1984 * 1985 * @param searchRequest The search request to be processed. It must not be 1986 * {@code null}. 1987 * 1988 * @return A search result object that provides information about the 1989 * processing of the search, potentially including the set of 1990 * matching entries and search references returned by the server. 1991 * 1992 * @throws LDAPSearchException If the search does not complete successfully, 1993 * or if a problem is encountered while sending 1994 * the request or reading the response. If one 1995 * or more entries or references were returned 1996 * before the failure was encountered, then the 1997 * {@code LDAPSearchException} object may be 1998 * examined to obtain information about those 1999 * entries and/or references. 2000 */ 2001 public final SearchResult search(final SearchRequest searchRequest) 2002 throws LDAPSearchException 2003 { 2004 final LDAPConnection conn; 2005 try 2006 { 2007 conn = getConnection(); 2008 } 2009 catch (LDAPException le) 2010 { 2011 debugException(le); 2012 throw new LDAPSearchException(le); 2013 } 2014 2015 try 2016 { 2017 final SearchResult result = conn.search(searchRequest); 2018 releaseConnection(conn); 2019 return result; 2020 } 2021 catch (Throwable t) 2022 { 2023 throwLDAPSearchExceptionIfShouldNotRetry(t, conn); 2024 2025 // If we have gotten here, then we should retry the operation with a 2026 // newly-created connection. 2027 final LDAPConnection newConn; 2028 try 2029 { 2030 newConn = replaceDefunctConnection(t, conn); 2031 } 2032 catch (final LDAPException le) 2033 { 2034 debugException(le); 2035 throw new LDAPSearchException(le); 2036 } 2037 2038 try 2039 { 2040 final SearchResult result = newConn.search(searchRequest); 2041 releaseConnection(newConn); 2042 return result; 2043 } 2044 catch (final Throwable t2) 2045 { 2046 throwLDAPSearchException(t2, newConn); 2047 } 2048 2049 // This return statement should never be reached. 2050 return null; 2051 } 2052 } 2053 2054 2055 2056 /** 2057 * Processes the provided search request using a connection from this 2058 * connection pool. 2059 * <BR><BR> 2060 * Note that if the search does not complete successfully, an 2061 * {@code LDAPSearchException} will be thrown In some cases, one or more 2062 * search result entries or references may have been returned before the 2063 * failure response is received. In this case, the 2064 * {@code LDAPSearchException} methods like {@code getEntryCount}, 2065 * {@code getSearchEntries}, {@code getReferenceCount}, and 2066 * {@code getSearchReferences} may be used to obtain information about those 2067 * entries and references (although if a search result listener was provided, 2068 * then it will have been used to make any entries and references available, 2069 * and they will not be available through the {@code getSearchEntries} and 2070 * {@code getSearchReferences} methods). 2071 * 2072 * @param searchRequest The search request to be processed. It must not be 2073 * {@code null}. 2074 * 2075 * @return A search result object that provides information about the 2076 * processing of the search, potentially including the set of 2077 * matching entries and search references returned by the server. 2078 * 2079 * @throws LDAPSearchException If the search does not complete successfully, 2080 * or if a problem is encountered while sending 2081 * the request or reading the response. If one 2082 * or more entries or references were returned 2083 * before the failure was encountered, then the 2084 * {@code LDAPSearchException} object may be 2085 * examined to obtain information about those 2086 * entries and/or references. 2087 */ 2088 public final SearchResult search(final ReadOnlySearchRequest searchRequest) 2089 throws LDAPSearchException 2090 { 2091 return search((SearchRequest) searchRequest); 2092 } 2093 2094 2095 2096 /** 2097 * Processes a search operation with the provided information using a 2098 * connection from this connection pool. It is expected that at most one 2099 * entry will be returned from the search, and that no additional content from 2100 * the successful search result (e.g., diagnostic message or response 2101 * controls) are needed. 2102 * <BR><BR> 2103 * Note that if the search does not complete successfully, an 2104 * {@code LDAPSearchException} will be thrown In some cases, one or more 2105 * search result entries or references may have been returned before the 2106 * failure response is received. In this case, the 2107 * {@code LDAPSearchException} methods like {@code getEntryCount}, 2108 * {@code getSearchEntries}, {@code getReferenceCount}, and 2109 * {@code getSearchReferences} may be used to obtain information about those 2110 * entries and references. 2111 * 2112 * @param baseDN The base DN for the search request. It must not be 2113 * {@code null}. 2114 * @param scope The scope that specifies the range of entries that 2115 * should be examined for the search. 2116 * @param filter The string representation of the filter to use to 2117 * identify matching entries. It must not be 2118 * {@code null}. 2119 * @param attributes The set of attributes that should be returned in 2120 * matching entries. It may be {@code null} or empty if 2121 * the default attribute set (all user attributes) is to 2122 * be requested. 2123 * 2124 * @return The entry that was returned from the search, or {@code null} if no 2125 * entry was returned or the base entry does not exist. 2126 * 2127 * @throws LDAPSearchException If the search does not complete successfully, 2128 * if more than a single entry is returned, or 2129 * if a problem is encountered while parsing the 2130 * provided filter string, sending the request, 2131 * or reading the response. If one or more 2132 * entries or references were returned before 2133 * the failure was encountered, then the 2134 * {@code LDAPSearchException} object may be 2135 * examined to obtain information about those 2136 * entries and/or references. 2137 */ 2138 public final SearchResultEntry searchForEntry(final String baseDN, 2139 final SearchScope scope, 2140 final String filter, 2141 final String... attributes) 2142 throws LDAPSearchException 2143 { 2144 return searchForEntry(new SearchRequest(baseDN, scope, 2145 DereferencePolicy.NEVER, 1, 0, false, parseFilter(filter), 2146 attributes)); 2147 } 2148 2149 2150 2151 /** 2152 * Processes a search operation with the provided information using a 2153 * connection from this connection pool. It is expected that at most one 2154 * entry will be returned from the search, and that no additional content from 2155 * the successful search result (e.g., diagnostic message or response 2156 * controls) are needed. 2157 * <BR><BR> 2158 * Note that if the search does not complete successfully, an 2159 * {@code LDAPSearchException} will be thrown In some cases, one or more 2160 * search result entries or references may have been returned before the 2161 * failure response is received. In this case, the 2162 * {@code LDAPSearchException} methods like {@code getEntryCount}, 2163 * {@code getSearchEntries}, {@code getReferenceCount}, and 2164 * {@code getSearchReferences} may be used to obtain information about those 2165 * entries and references. 2166 * 2167 * @param baseDN The base DN for the search request. It must not be 2168 * {@code null}. 2169 * @param scope The scope that specifies the range of entries that 2170 * should be examined for the search. 2171 * @param filter The string representation of the filter to use to 2172 * identify matching entries. It must not be 2173 * {@code null}. 2174 * @param attributes The set of attributes that should be returned in 2175 * matching entries. It may be {@code null} or empty if 2176 * the default attribute set (all user attributes) is to 2177 * be requested. 2178 * 2179 * @return The entry that was returned from the search, or {@code null} if no 2180 * entry was returned or the base entry does not exist. 2181 * 2182 * @throws LDAPSearchException If the search does not complete successfully, 2183 * if more than a single entry is returned, or 2184 * if a problem is encountered while parsing the 2185 * provided filter string, sending the request, 2186 * or reading the response. If one or more 2187 * entries or references were returned before 2188 * the failure was encountered, then the 2189 * {@code LDAPSearchException} object may be 2190 * examined to obtain information about those 2191 * entries and/or references. 2192 */ 2193 public final SearchResultEntry searchForEntry(final String baseDN, 2194 final SearchScope scope, 2195 final Filter filter, 2196 final String... attributes) 2197 throws LDAPSearchException 2198 { 2199 return searchForEntry(new SearchRequest(baseDN, scope, 2200 DereferencePolicy.NEVER, 1, 0, false, filter, attributes)); 2201 } 2202 2203 2204 2205 /** 2206 * Processes a search operation with the provided information using a 2207 * connection from this connection pool. It is expected that at most one 2208 * entry will be returned from the search, and that no additional content from 2209 * the successful search result (e.g., diagnostic message or response 2210 * controls) are needed. 2211 * <BR><BR> 2212 * Note that if the search does not complete successfully, an 2213 * {@code LDAPSearchException} will be thrown In some cases, one or more 2214 * search result entries or references may have been returned before the 2215 * failure response is received. In this case, the 2216 * {@code LDAPSearchException} methods like {@code getEntryCount}, 2217 * {@code getSearchEntries}, {@code getReferenceCount}, and 2218 * {@code getSearchReferences} may be used to obtain information about those 2219 * entries and references. 2220 * 2221 * @param baseDN The base DN for the search request. It must not be 2222 * {@code null}. 2223 * @param scope The scope that specifies the range of entries that 2224 * should be examined for the search. 2225 * @param derefPolicy The dereference policy the server should use for any 2226 * aliases encountered while processing the search. 2227 * @param timeLimit The maximum length of time in seconds that the server 2228 * should spend processing this search request. A value 2229 * of zero indicates that there should be no limit. 2230 * @param typesOnly Indicates whether to return only attribute names in 2231 * matching entries, or both attribute names and values. 2232 * @param filter The string representation of the filter to use to 2233 * identify matching entries. It must not be 2234 * {@code null}. 2235 * @param attributes The set of attributes that should be returned in 2236 * matching entries. It may be {@code null} or empty if 2237 * the default attribute set (all user attributes) is to 2238 * be requested. 2239 * 2240 * @return The entry that was returned from the search, or {@code null} if no 2241 * entry was returned or the base entry does not exist. 2242 * 2243 * @throws LDAPSearchException If the search does not complete successfully, 2244 * if more than a single entry is returned, or 2245 * if a problem is encountered while parsing the 2246 * provided filter string, sending the request, 2247 * or reading the response. If one or more 2248 * entries or references were returned before 2249 * the failure was encountered, then the 2250 * {@code LDAPSearchException} object may be 2251 * examined to obtain information about those 2252 * entries and/or references. 2253 */ 2254 public final SearchResultEntry 2255 searchForEntry(final String baseDN, final SearchScope scope, 2256 final DereferencePolicy derefPolicy, final int timeLimit, 2257 final boolean typesOnly, final String filter, 2258 final String... attributes) 2259 throws LDAPSearchException 2260 { 2261 return searchForEntry(new SearchRequest(baseDN, scope, derefPolicy, 1, 2262 timeLimit, typesOnly, parseFilter(filter), attributes)); 2263 } 2264 2265 2266 2267 /** 2268 * Processes a search operation with the provided information using a 2269 * connection from this connection pool. It is expected that at most one 2270 * entry will be returned from the search, and that no additional content from 2271 * the successful search result (e.g., diagnostic message or response 2272 * controls) are needed. 2273 * <BR><BR> 2274 * Note that if the search does not complete successfully, an 2275 * {@code LDAPSearchException} will be thrown In some cases, one or more 2276 * search result entries or references may have been returned before the 2277 * failure response is received. In this case, the 2278 * {@code LDAPSearchException} methods like {@code getEntryCount}, 2279 * {@code getSearchEntries}, {@code getReferenceCount}, and 2280 * {@code getSearchReferences} may be used to obtain information about those 2281 * entries and references. 2282 * 2283 * @param baseDN The base DN for the search request. It must not be 2284 * {@code null}. 2285 * @param scope The scope that specifies the range of entries that 2286 * should be examined for the search. 2287 * @param derefPolicy The dereference policy the server should use for any 2288 * aliases encountered while processing the search. 2289 * @param timeLimit The maximum length of time in seconds that the server 2290 * should spend processing this search request. A value 2291 * of zero indicates that there should be no limit. 2292 * @param typesOnly Indicates whether to return only attribute names in 2293 * matching entries, or both attribute names and values. 2294 * @param filter The filter to use to identify matching entries. It 2295 * must not be {@code null}. 2296 * @param attributes The set of attributes that should be returned in 2297 * matching entries. It may be {@code null} or empty if 2298 * the default attribute set (all user attributes) is to 2299 * be requested. 2300 * 2301 * @return The entry that was returned from the search, or {@code null} if no 2302 * entry was returned or the base entry does not exist. 2303 * 2304 * @throws LDAPSearchException If the search does not complete successfully, 2305 * if more than a single entry is returned, or 2306 * if a problem is encountered while parsing the 2307 * provided filter string, sending the request, 2308 * or reading the response. If one or more 2309 * entries or references were returned before 2310 * the failure was encountered, then the 2311 * {@code LDAPSearchException} object may be 2312 * examined to obtain information about those 2313 * entries and/or references. 2314 */ 2315 public final SearchResultEntry 2316 searchForEntry(final String baseDN, final SearchScope scope, 2317 final DereferencePolicy derefPolicy, final int timeLimit, 2318 final boolean typesOnly, final Filter filter, 2319 final String... attributes) 2320 throws LDAPSearchException 2321 { 2322 return searchForEntry(new SearchRequest(baseDN, scope, derefPolicy, 1, 2323 timeLimit, typesOnly, filter, attributes)); 2324 } 2325 2326 2327 2328 /** 2329 * Processes a search operation with the provided information using a 2330 * connection from this connection pool. It is expected that at most one 2331 * entry will be returned from the search, and that no additional content from 2332 * the successful search result (e.g., diagnostic message or response 2333 * controls) are needed. 2334 * <BR><BR> 2335 * Note that if the search does not complete successfully, an 2336 * {@code LDAPSearchException} will be thrown In some cases, one or more 2337 * search result entries or references may have been returned before the 2338 * failure response is received. In this case, the 2339 * {@code LDAPSearchException} methods like {@code getEntryCount}, 2340 * {@code getSearchEntries}, {@code getReferenceCount}, and 2341 * {@code getSearchReferences} may be used to obtain information about those 2342 * entries and references. 2343 * 2344 * @param searchRequest The search request to be processed. If it is 2345 * configured with a search result listener or a size 2346 * limit other than one, then the provided request will 2347 * be duplicated with the appropriate settings. 2348 * 2349 * @return The entry that was returned from the search, or {@code null} if no 2350 * entry was returned or the base entry does not exist. 2351 * 2352 * @throws LDAPSearchException If the search does not complete successfully, 2353 * if more than a single entry is returned, or 2354 * if a problem is encountered while parsing the 2355 * provided filter string, sending the request, 2356 * or reading the response. If one or more 2357 * entries or references were returned before 2358 * the failure was encountered, then the 2359 * {@code LDAPSearchException} object may be 2360 * examined to obtain information about those 2361 * entries and/or references. 2362 */ 2363 public final SearchResultEntry searchForEntry( 2364 final SearchRequest searchRequest) 2365 throws LDAPSearchException 2366 { 2367 final LDAPConnection conn; 2368 try 2369 { 2370 conn = getConnection(); 2371 } 2372 catch (LDAPException le) 2373 { 2374 debugException(le); 2375 throw new LDAPSearchException(le); 2376 } 2377 2378 try 2379 { 2380 final SearchResultEntry entry = conn.searchForEntry(searchRequest); 2381 releaseConnection(conn); 2382 return entry; 2383 } 2384 catch (Throwable t) 2385 { 2386 throwLDAPSearchExceptionIfShouldNotRetry(t, conn); 2387 2388 // If we have gotten here, then we should retry the operation with a 2389 // newly-created connection. 2390 final LDAPConnection newConn; 2391 try 2392 { 2393 newConn = replaceDefunctConnection(t, conn); 2394 } 2395 catch (final LDAPException le) 2396 { 2397 debugException(le); 2398 throw new LDAPSearchException(le); 2399 } 2400 2401 try 2402 { 2403 final SearchResultEntry entry = newConn.searchForEntry(searchRequest); 2404 releaseConnection(newConn); 2405 return entry; 2406 } 2407 catch (final Throwable t2) 2408 { 2409 throwLDAPSearchException(t2, newConn); 2410 } 2411 2412 // This return statement should never be reached. 2413 return null; 2414 } 2415 } 2416 2417 2418 2419 /** 2420 * Processes a search operation with the provided information using a 2421 * connection from this connection pool. It is expected that at most one 2422 * entry will be returned from the search, and that no additional content from 2423 * the successful search result (e.g., diagnostic message or response 2424 * controls) are needed. 2425 * <BR><BR> 2426 * Note that if the search does not complete successfully, an 2427 * {@code LDAPSearchException} will be thrown In some cases, one or more 2428 * search result entries or references may have been returned before the 2429 * failure response is received. In this case, the 2430 * {@code LDAPSearchException} methods like {@code getEntryCount}, 2431 * {@code getSearchEntries}, {@code getReferenceCount}, and 2432 * {@code getSearchReferences} may be used to obtain information about those 2433 * entries and references. 2434 * 2435 * @param searchRequest The search request to be processed. If it is 2436 * configured with a search result listener or a size 2437 * limit other than one, then the provided request will 2438 * be duplicated with the appropriate settings. 2439 * 2440 * @return The entry that was returned from the search, or {@code null} if no 2441 * entry was returned or the base entry does not exist. 2442 * 2443 * @throws LDAPSearchException If the search does not complete successfully, 2444 * if more than a single entry is returned, or 2445 * if a problem is encountered while parsing the 2446 * provided filter string, sending the request, 2447 * or reading the response. If one or more 2448 * entries or references were returned before 2449 * the failure was encountered, then the 2450 * {@code LDAPSearchException} object may be 2451 * examined to obtain information about those 2452 * entries and/or references. 2453 */ 2454 public final SearchResultEntry searchForEntry( 2455 final ReadOnlySearchRequest searchRequest) 2456 throws LDAPSearchException 2457 { 2458 return searchForEntry((SearchRequest) searchRequest); 2459 } 2460 2461 2462 2463 /** 2464 * Parses the provided string as a {@code Filter} object. 2465 * 2466 * @param filterString The string to parse as a {@code Filter}. 2467 * 2468 * @return The parsed {@code Filter}. 2469 * 2470 * @throws LDAPSearchException If the provided string does not represent a 2471 * valid search filter. 2472 */ 2473 private static Filter parseFilter(final String filterString) 2474 throws LDAPSearchException 2475 { 2476 try 2477 { 2478 return Filter.create(filterString); 2479 } 2480 catch (final LDAPException le) 2481 { 2482 debugException(le); 2483 throw new LDAPSearchException(le); 2484 } 2485 } 2486 2487 2488 2489 /** 2490 * Processes multiple requests in the order they are provided over a single 2491 * connection from this pool. Note that the 2492 * {@code retryFailedOperationsDueToInvalidConnections()} setting will be 2493 * ignored when processing the provided operations, so that any failed 2494 * operations will not be retried. 2495 * 2496 * @param requests The list of requests to be processed. It must not 2497 * be {@code null} or empty. 2498 * @param continueOnError Indicates whether to attempt to process subsequent 2499 * requests if any of the operations does not 2500 * complete successfully. 2501 * 2502 * @return The set of results from the requests that were processed. The 2503 * order of result objects will correspond to the order of the 2504 * request objects, although the list of results may contain fewer 2505 * elements than the list of requests if an error occurred during 2506 * processing and {@code continueOnError} is {@code false}. 2507 * 2508 * @throws LDAPException If a problem occurs while trying to obtain a 2509 * connection to use for the requests. 2510 */ 2511 public final List<LDAPResult> processRequests( 2512 final List<LDAPRequest> requests, 2513 final boolean continueOnError) 2514 throws LDAPException 2515 { 2516 ensureNotNull(requests); 2517 ensureFalse(requests.isEmpty(), 2518 "LDAPConnectionPool.processRequests.requests must not be empty."); 2519 2520 final LDAPConnection conn; 2521 try 2522 { 2523 conn = getConnection(); 2524 } 2525 catch (LDAPException le) 2526 { 2527 debugException(le); 2528 throw new LDAPSearchException(le); 2529 } 2530 2531 final ArrayList<LDAPResult> results = 2532 new ArrayList<LDAPResult>(requests.size()); 2533 boolean isDefunct = false; 2534 2535 try 2536 { 2537 requestLoop: 2538 for (final LDAPRequest request : requests) 2539 { 2540 try 2541 { 2542 final LDAPResult result = request.process(conn, 1); 2543 results.add(result); 2544 switch (result.getResultCode().intValue()) 2545 { 2546 case ResultCode.SUCCESS_INT_VALUE: 2547 case ResultCode.COMPARE_FALSE_INT_VALUE: 2548 case ResultCode.COMPARE_TRUE_INT_VALUE: 2549 case ResultCode.NO_OPERATION_INT_VALUE: 2550 // These will be considered successful operations. 2551 break; 2552 2553 default: 2554 // Anything else will be considered a failure. 2555 if (! ResultCode.isConnectionUsable(result.getResultCode())) 2556 { 2557 isDefunct = true; 2558 } 2559 2560 if (! continueOnError) 2561 { 2562 break requestLoop; 2563 } 2564 break; 2565 } 2566 } 2567 catch (LDAPException le) 2568 { 2569 debugException(le); 2570 results.add(new LDAPResult(request.getLastMessageID(), 2571 le.getResultCode(), le.getMessage(), 2572 le.getMatchedDN(), le.getReferralURLs(), 2573 le.getResponseControls())); 2574 2575 if (! ResultCode.isConnectionUsable(le.getResultCode())) 2576 { 2577 isDefunct = true; 2578 } 2579 2580 if (! continueOnError) 2581 { 2582 break; 2583 } 2584 } 2585 } 2586 } 2587 finally 2588 { 2589 if (isDefunct) 2590 { 2591 releaseDefunctConnection(conn); 2592 } 2593 else 2594 { 2595 releaseConnection(conn); 2596 } 2597 } 2598 2599 return results; 2600 } 2601 2602 2603 2604 /** 2605 * Processes multiple requests over a single connection from this pool using 2606 * asynchronous processing to cause the operations to be processed 2607 * concurrently. The list of requests may contain only add, compare, delete, 2608 * modify, modify DN, and search operations (and any search operations to be 2609 * processed must be configured with an {@code AsyncSearchResultListener}. 2610 * This method will not return until all operations have completed, or until 2611 * the specified timeout period has elapsed. The order of elements in the 2612 * list of the {@code AsyncRequestID} objects returned will correspond to the 2613 * order of elements in the list of requests. The operation results may be 2614 * obtained from the returned {@code AsyncRequestID} objects using the 2615 * {@code java.util.concurrent.Future} API. 2616 * 2617 * @param requests The list of requests to be processed. It must 2618 * not be {@code null} or empty, and it must 2619 * contain only add, compare, modify, modify DN, 2620 * and search requests. Any search requests must 2621 * be configured with an 2622 * {@code AsyncSearchResultListener}. 2623 * @param maxWaitTimeMillis The maximum length of time in milliseconds to 2624 * wait for the operations to complete before 2625 * returning. A value that is less than or equal 2626 * to zero indicates that the client should wait 2627 * indefinitely for the operations to complete. 2628 * 2629 * @return The list of {@code AsyncRequestID} objects that may be used to 2630 * retrieve the results for the operations. The order of elements in 2631 * this list will correspond to the order of the provided requests. 2632 * 2633 * @throws LDAPException If there is a problem with any of the requests, or 2634 * if connections in the pool are configured to use 2635 * synchronous mode and therefore cannot be used to 2636 * process asynchronous operations. 2637 */ 2638 public final List<AsyncRequestID> processRequestsAsync( 2639 final List<LDAPRequest> requests, 2640 final long maxWaitTimeMillis) 2641 throws LDAPException 2642 { 2643 // Make sure the set of requests is not null or empty. 2644 ensureNotNull(requests); 2645 ensureFalse(requests.isEmpty(), 2646 "LDAPConnectionPool.processRequests.requests must not be empty."); 2647 2648 // Make sure that all the requests are acceptable. 2649 for (final LDAPRequest r : requests) 2650 { 2651 switch (r.getOperationType()) 2652 { 2653 case ADD: 2654 case COMPARE: 2655 case DELETE: 2656 case MODIFY: 2657 case MODIFY_DN: 2658 // These operation types are always acceptable for asynchronous 2659 // processing. 2660 break; 2661 2662 case SEARCH: 2663 // Search operations will only be acceptable if they have been 2664 // configured with an async search result listener. 2665 final SearchRequest searchRequest = (SearchRequest) r; 2666 if ((searchRequest.getSearchResultListener() == null) || 2667 (! (searchRequest.getSearchResultListener() instanceof 2668 AsyncSearchResultListener))) 2669 { 2670 throw new LDAPException(ResultCode.PARAM_ERROR, 2671 ERR_POOL_PROCESS_REQUESTS_ASYNC_SEARCH_NOT_ASYNC.get( 2672 String.valueOf(r))); 2673 } 2674 break; 2675 2676 case ABANDON: 2677 case BIND: 2678 case EXTENDED: 2679 case UNBIND: 2680 default: 2681 // These operation types are never acceptable for asynchronous 2682 // processing. 2683 throw new LDAPException(ResultCode.PARAM_ERROR, 2684 ERR_POOL_PROCESS_REQUESTS_ASYNC_OP_NOT_ASYNC.get( 2685 String.valueOf(r))); 2686 } 2687 } 2688 2689 2690 final LDAPConnection conn; 2691 try 2692 { 2693 conn = getConnection(); 2694 } 2695 catch (LDAPException le) 2696 { 2697 debugException(le); 2698 throw new LDAPSearchException(le); 2699 } 2700 2701 2702 final ArrayList<AsyncRequestID> requestIDs = 2703 new ArrayList<AsyncRequestID>(); 2704 boolean isDefunct = false; 2705 2706 try 2707 { 2708 // Make sure that the connection is not configured to use synchronous 2709 // mode, because asynchronous operations are not allowed in that mode. 2710 if (conn.synchronousMode()) 2711 { 2712 throw new LDAPException(ResultCode.PARAM_ERROR, 2713 ERR_POOL_PROCESS_REQUESTS_ASYNC_SYNCHRONOUS_MODE.get()); 2714 } 2715 2716 2717 // Issue all of the requests. If an exception is encountered while 2718 // issuing a request, then convert it into an AsyncRequestID with the 2719 // exception as the result. 2720 for (final LDAPRequest r : requests) 2721 { 2722 AsyncRequestID requestID = null; 2723 try 2724 { 2725 switch (r.getOperationType()) 2726 { 2727 case ADD: 2728 requestID = conn.asyncAdd((AddRequest) r, null); 2729 break; 2730 case COMPARE: 2731 requestID = conn.asyncCompare((CompareRequest) r, null); 2732 break; 2733 case DELETE: 2734 requestID = conn.asyncDelete((DeleteRequest) r, null); 2735 break; 2736 case MODIFY: 2737 requestID = conn.asyncModify((ModifyRequest) r, null); 2738 break; 2739 case MODIFY_DN: 2740 requestID = conn.asyncModifyDN((ModifyDNRequest) r, null); 2741 break; 2742 case SEARCH: 2743 requestID = conn.asyncSearch((SearchRequest) r); 2744 break; 2745 } 2746 } 2747 catch (final LDAPException le) 2748 { 2749 debugException(le); 2750 requestID = new AsyncRequestID(r.getLastMessageID(), conn); 2751 requestID.setResult(le.toLDAPResult()); 2752 } 2753 2754 requestIDs.add(requestID); 2755 } 2756 2757 2758 // Wait for the operations to complete. If any operation does not 2759 // complete before the specified timeout, then create a failure result for 2760 // it. If any operation does not complete successfully, then attempt to 2761 // determine whether the failure may indicate that the connection is no 2762 // longer valid. 2763 final long startWaitingTime = System.currentTimeMillis(); 2764 final long stopWaitingTime; 2765 if (maxWaitTimeMillis > 0) 2766 { 2767 stopWaitingTime = startWaitingTime + maxWaitTimeMillis; 2768 } 2769 else 2770 { 2771 stopWaitingTime = Long.MAX_VALUE; 2772 } 2773 2774 for (final AsyncRequestID requestID : requestIDs) 2775 { 2776 LDAPResult result; 2777 final long waitTime = stopWaitingTime - System.currentTimeMillis(); 2778 if (waitTime > 0) 2779 { 2780 try 2781 { 2782 result = requestID.get(waitTime, TimeUnit.MILLISECONDS); 2783 } 2784 catch (final Exception e) 2785 { 2786 debugException(e); 2787 requestID.cancel(true); 2788 2789 if (e instanceof TimeoutException) 2790 { 2791 result = new LDAPResult(requestID.getMessageID(), 2792 ResultCode.TIMEOUT, 2793 ERR_POOL_PROCESS_REQUESTS_ASYNC_RESULT_TIMEOUT.get( 2794 (System.currentTimeMillis() - startWaitingTime)), 2795 null, NO_STRINGS, NO_CONTROLS); 2796 } 2797 else 2798 { 2799 result = new LDAPResult(requestID.getMessageID(), 2800 ResultCode.LOCAL_ERROR, 2801 ERR_POOL_PROCESS_REQUESTS_ASYNC_RESULT_EXCEPTION.get( 2802 getExceptionMessage(e)), 2803 null, NO_STRINGS, NO_CONTROLS); 2804 } 2805 requestID.setResult(result); 2806 } 2807 } 2808 else 2809 { 2810 requestID.cancel(true); 2811 result = new LDAPResult(requestID.getMessageID(), 2812 ResultCode.TIMEOUT, 2813 ERR_POOL_PROCESS_REQUESTS_ASYNC_RESULT_TIMEOUT.get( 2814 (System.currentTimeMillis() - startWaitingTime)), 2815 null, NO_STRINGS, NO_CONTROLS); 2816 requestID.setResult(result); 2817 } 2818 2819 2820 // See if we think that the connection may be defunct. 2821 if (! ResultCode.isConnectionUsable(result.getResultCode())) 2822 { 2823 isDefunct = true; 2824 } 2825 } 2826 2827 return requestIDs; 2828 } 2829 finally 2830 { 2831 if (isDefunct) 2832 { 2833 releaseDefunctConnection(conn); 2834 } 2835 else 2836 { 2837 releaseConnection(conn); 2838 } 2839 } 2840 } 2841 2842 2843 2844 /** 2845 * Examines the provided {@code Throwable} object to determine whether it 2846 * represents an {@code LDAPException} that indicates the associated 2847 * connection may no longer be valid. If that is the case, and if such 2848 * operations should be retried, then no exception will be thrown. Otherwise, 2849 * an appropriate {@code LDAPException} will be thrown. 2850 * 2851 * @param t The {@code Throwable} object that was caught. 2852 * @param o The type of operation for which to make the determination. 2853 * @param conn The connection to be released to the pool. 2854 * 2855 * @throws LDAPException To indicate that a problem occurred during LDAP 2856 * processing and the operation should not be retried. 2857 */ 2858 private void throwLDAPExceptionIfShouldNotRetry(final Throwable t, 2859 final OperationType o, 2860 final LDAPConnection conn) 2861 throws LDAPException 2862 { 2863 if ((t instanceof LDAPException) && 2864 getOperationTypesToRetryDueToInvalidConnections().contains(o)) 2865 { 2866 final LDAPException le = (LDAPException) t; 2867 final LDAPConnectionPoolHealthCheck healthCheck = getHealthCheck(); 2868 2869 try 2870 { 2871 healthCheck.ensureConnectionValidAfterException(conn, le); 2872 } 2873 catch (final Exception e) 2874 { 2875 // If we have gotten this exception, then it indicates that the 2876 // connection is no longer valid and the operation should be retried. 2877 debugException(e); 2878 return; 2879 } 2880 } 2881 2882 throwLDAPException(t, conn); 2883 } 2884 2885 2886 2887 /** 2888 * Examines the provided {@code Throwable} object to determine whether it 2889 * represents an {@code LDAPException} that indicates the associated 2890 * connection may no longer be valid. If that is the case, and if such 2891 * operations should be retried, then no exception will be thrown. Otherwise, 2892 * an appropriate {@code LDAPSearchException} will be thrown. 2893 * 2894 * @param t The {@code Throwable} object that was caught. 2895 * @param conn The connection to be released to the pool. 2896 * 2897 * @throws LDAPSearchException To indicate that a problem occurred during 2898 * LDAP processing and the operation should not 2899 * be retried. 2900 */ 2901 private void throwLDAPSearchExceptionIfShouldNotRetry(final Throwable t, 2902 final LDAPConnection conn) 2903 throws LDAPSearchException 2904 { 2905 if ((t instanceof LDAPException) && 2906 getOperationTypesToRetryDueToInvalidConnections().contains( 2907 OperationType.SEARCH)) 2908 { 2909 final LDAPException le = (LDAPException) t; 2910 final LDAPConnectionPoolHealthCheck healthCheck = getHealthCheck(); 2911 2912 try 2913 { 2914 healthCheck.ensureConnectionValidAfterException(conn, le); 2915 } 2916 catch (final Exception e) 2917 { 2918 // If we have gotten this exception, then it indicates that the 2919 // connection is no longer valid and the operation should be retried. 2920 debugException(e); 2921 return; 2922 } 2923 } 2924 2925 throwLDAPSearchException(t, conn); 2926 } 2927 2928 2929 2930 /** 2931 * Handles the provided {@code Throwable} object by ensuring that the provided 2932 * connection is released to the pool and throwing an appropriate 2933 * {@code LDAPException} object. 2934 * 2935 * @param t The {@code Throwable} object that was caught. 2936 * @param conn The connection to be released to the pool. 2937 * 2938 * @throws LDAPException To indicate that a problem occurred during LDAP 2939 * processing. 2940 */ 2941 void throwLDAPException(final Throwable t, final LDAPConnection conn) 2942 throws LDAPException 2943 { 2944 debugException(t); 2945 if (t instanceof LDAPException) 2946 { 2947 final LDAPException le = (LDAPException) t; 2948 releaseConnectionAfterException(conn, le); 2949 throw le; 2950 } 2951 else 2952 { 2953 releaseDefunctConnection(conn); 2954 throw new LDAPException(ResultCode.LOCAL_ERROR, 2955 ERR_POOL_OP_EXCEPTION.get(getExceptionMessage(t)), t); 2956 } 2957 } 2958 2959 2960 2961 /** 2962 * Handles the provided {@code Throwable} object by ensuring that the provided 2963 * connection is released to the pool and throwing an appropriate 2964 * {@code LDAPSearchException} object. 2965 * 2966 * @param t The {@code Throwable} object that was caught. 2967 * @param conn The connection to be released to the pool. 2968 * 2969 * @throws LDAPSearchException To indicate that a problem occurred during 2970 * LDAP search processing. 2971 */ 2972 void throwLDAPSearchException(final Throwable t, final LDAPConnection conn) 2973 throws LDAPSearchException 2974 { 2975 debugException(t); 2976 if (t instanceof LDAPException) 2977 { 2978 final LDAPSearchException lse; 2979 if (t instanceof LDAPSearchException) 2980 { 2981 lse = (LDAPSearchException) t; 2982 } 2983 else 2984 { 2985 lse = new LDAPSearchException((LDAPException) t); 2986 } 2987 2988 releaseConnectionAfterException(conn, lse); 2989 throw lse; 2990 } 2991 else 2992 { 2993 releaseDefunctConnection(conn); 2994 throw new LDAPSearchException(ResultCode.LOCAL_ERROR, 2995 ERR_POOL_OP_EXCEPTION.get(getExceptionMessage(t)), t); 2996 } 2997 } 2998 2999 3000 3001 /** 3002 * Retrieves a string representation of this connection pool. 3003 * 3004 * @return A string representation of this connection pool. 3005 */ 3006 @Override() 3007 public final String toString() 3008 { 3009 final StringBuilder buffer = new StringBuilder(); 3010 toString(buffer); 3011 return buffer.toString(); 3012 } 3013 3014 3015 3016 /** 3017 * Appends a string representation of this connection pool to the provided 3018 * buffer. 3019 * 3020 * @param buffer The buffer to which the string representation should be 3021 * appended. 3022 */ 3023 public abstract void toString(final StringBuilder buffer); 3024 }