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