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