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