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