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