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