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