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