001    /*
002     * Copyright 2007-2014 UnboundID Corp.
003     * All Rights Reserved.
004     */
005    /*
006     * Copyright (C) 2008-2014 UnboundID Corp.
007     *
008     * This program is free software; you can redistribute it and/or modify
009     * it under the terms of the GNU General Public License (GPLv2 only)
010     * or the terms of the GNU Lesser General Public License (LGPLv2.1 only)
011     * as published by the Free Software Foundation.
012     *
013     * This program is distributed in the hope that it will be useful,
014     * but WITHOUT ANY WARRANTY; without even the implied warranty of
015     * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
016     * GNU General Public License for more details.
017     *
018     * You should have received a copy of the GNU General Public License
019     * along with this program; if not, see <http://www.gnu.org/licenses>.
020     */
021    package com.unboundid.ldap.sdk;
022    
023    
024    
025    import com.unboundid.util.StaticUtils;
026    import com.unboundid.util.ssl.SSLSocketVerifier;
027    import com.unboundid.util.ssl.TrustAllSSLSocketVerifier;
028    
029    import static com.unboundid.util.Validator.*;
030    
031    
032    
033    /**
034     * This class provides a data structure that may be used to configure a number
035     * of connection-related properties.  Elements included in the set of connection
036     * options include:
037     * <UL>
038     *   <LI>A flag that indicates whether the SDK should attempt to automatically
039     *       re-establish a connection if it is unexpectedly closed.  By default,
040     *       it will not attempt to do so.</LI>
041     *   <LI>A flag that indicates whether simple bind attempts that contain a
042     *       non-empty DN will be required to have a non-empty password.  By
043     *       default, a password will be required in such cases.</LI>
044     *   <LI>A flag that indicates whether to automatically attempt to follow any
045     *       referrals that may be returned by the server.  By default, it will not
046     *       automatically attempt to follow referrals.</LI>
047     *   <LI>A referral hop limit, which indicates the maximum number of hops that
048     *       the connection may take when trying to follow a referral.  The default
049     *       referral hop limit is five.</LI>
050     *   <LI>The referral connector that should be used to create and optionally
051     *       authenticate connections used to follow referrals encountered during
052     *       processing.  By default, referral connections will use the same socket
053     *       factory and bind request as the client connection on which the referral
054     *       was received.</LI>
055     *   <LI>A flag that indicates whether to use the SO_KEEPALIVE socket option to
056     *       attempt to more quickly detect when idle TCP connections have been lost
057     *       or to prevent them from being unexpectedly closed by intermediate
058     *       network hardware.  By default, the SO_KEEPALIVE socket option will be
059     *       used.</LI>
060     *   <LI>A flag that indicates whether to use the SO_LINGER socket option to
061     *       indicate how long a connection should linger after it has been closed,
062     *       and a value that specifies the length of time that it should linger.
063     *       By default, the SO_LINGER option will be used with a timeout of 5
064     *       seconds.</LI>
065     *   <LI>A flag that indicates whether to use the SO_REUSEADDR socket option to
066     *       indicate that a socket in a TIME_WAIT state may be reused.  By default,
067     *       the SO_REUSEADDR socket option will be used.</LI>
068     *   <LI>A flag that indicates whether to operate in synchronous mode, in which
069     *       connections may exhibit better performance and will not require a
070     *       separate reader thread, but will not allow multiple concurrent
071     *       operations to be used on the same connection.</LI>
072     *   <LI>A flag that indicates whether to use the TCP_NODELAY socket option to
073     *       indicate that any data written to the socket will be sent immediately
074     *       rather than delaying for a short amount of time to see if any more data
075     *       is to be sent that could potentially be included in the same packet.
076     *       By default, the TCP_NODELAY socket option will be used.</LI>
077     *   <LI>A value which specifies the maximum length of time in milliseconds that
078     *       an attempt to establish a connection should be allowed to block before
079     *       failing.  By default, a timeout of 60,000 milliseconds (1 minute) will
080     *       be used.</LI>
081     *   <LI>A value which specifies the default timeout in milliseconds that the
082     *       SDK should wait for a response from the server before failing.  By
083     *       default, a timeout of 300,000 milliseconds (5 minutes) will be
084     *       used.</LI>
085     *   <LI>A flag that indicates whether to attempt to abandon any request for
086     *       which no response is received after waiting for the maximum response
087     *       timeout.  By default, no abandon request will be sent.</LI>
088     *   <LI>A value which specifies the largest LDAP message size that the SDK will
089     *       be willing to read from the directory server.  By default, the SDK will
090     *       not allow responses larger than 20971520 bytes (20MB).  If it
091     *       encounters a message that may be larger than the maximum allowed
092     *       message size, then the SDK will terminate the connection to the
093     *       server.</LI>
094     *   <LI>The {@code DisconnectHandler} that should be used to receive
095     *       notification if connection is disconnected for any reason.  By default,
096     *       no {@code DisconnectHandler} will be used.</LI>
097     *   <LI>The {@code UnsolicitedNotificationHandler} that should be used to
098     *       receive notification about any unsolicited notifications returned by
099     *       the server.  By default, no {@code UnsolicitedNotificationHandler} will
100     *       be used.</LI>
101     *   <LI>A flag that indicates whether to capture a thread stack trace whenever
102     *       a new connection is established.  Capturing a thread stack trace when
103     *       establishing a connection may be marginally expensive, but can be
104     *       useful for debugging certain kinds of problems like leaked connections
105     *       (connections that are established but never explicitly closed).  By
106     *       default, connect stack traces will not be captured.</LI>
107     *   <LI>A flag that indicates whether connections should try to retrieve schema
108     *       information from the server, which may be used to better determine
109     *       which matching rules should be used when comparing attribute values.
110     *       By default, server schema information will not be retrieved.</LI>
111     *   <LI>The size of the socket receive buffer, which may be used for
112     *       temporarily holding data received from the directory server until it
113     *       can be read and processed by the LDAP SDK.  By default, the receive
114     *       buffer size will be automatically determined by the JVM based on the
115     *       underlying system settings.</LI>
116     *   <LI>The size of the socket send buffer, which may be used for temporarily
117     *       holding data to be sent to the directory server until it can actually
118     *       be transmitted over the network.  By default, the send buffer size will
119     *       be automatically determined by the JVM based on the underlying system
120     *       settings.</LI>
121     *  <LI>A flag which indicates whether to allow a single socket factory instance
122     *      (which may be shared across multiple connections) to be used to create
123     *      multiple concurrent connections.  This offers better and more
124     *      predictable performance on some JVM implementations (especially when
125     *      connection attempts fail as a result of a connection timeout), but some
126     *      JVMs are known to use non-threadsafe socket factory implementations and
127     *      may fail from concurrent use (for example, at least some IBM JVMs
128     *      exhibit this behavior).  By default, Sun/Oracle JVMs will allow
129     *      concurrent socket factory use, but JVMs from other vendors will use
130     *      synchronization to ensure that a socket factory will only be allowed to
131     *      create one connection at a time.</LI>
132     *  <LI>A class that may be used to perform additional verification (e.g.,
133     *      hostname validation) for any {@code SSLSocket} instances created.  By
134     *      default, no special verification will be performed.</LI>
135     * </UL>
136     */
137    public final class LDAPConnectionOptions
138    {
139      /**
140       * The default value ({@code false}) for the setting that controls whether to
141       * attempt to abandon any request for which no response is received within the
142       * maximum response timeout.
143       */
144      static final boolean DEFAULT_ABANDON_ON_TIMEOUT = false;
145    
146    
147    
148      /**
149       * The default value ({@code false}) for the setting that controls whether to
150       * automatically attempt to reconnect if a connection is unexpectedly lost.
151       */
152      static final boolean DEFAULT_AUTO_RECONNECT = false;
153    
154    
155    
156      /**
157       * The default value ({@code true}) for the setting that controls whether
158       * simple bind requests with a DN are also required to contain a password.
159       */
160      static final boolean DEFAULT_BIND_WITH_DN_REQUIRES_PASSWORD = true;
161    
162    
163    
164      /**
165       * The default value ({@code false}) for the setting that controls whether to
166       * capture a thread stack trace whenever an attempt is made to establish a
167       * connection.
168       */
169      static final boolean DEFAULT_CAPTURE_CONNECT_STACK_TRACE = false;
170    
171    
172    
173      /**
174       * The default value ({@code false}) for the setting that controls whether to
175       * attempt to automatically follow referrals.
176       */
177      static final boolean DEFAULT_FOLLOW_REFERRALS = false;
178    
179    
180    
181      /**
182       * The default value ({@code false}) for the setting that controls whether all
183       * connections in a connection pool should use the same cached schema object.
184       */
185      static final boolean DEFAULT_USE_POOLED_SCHEMA = false;
186    
187    
188    
189      /**
190       * The default value ({@code true}) for the setting that controls whether to
191       * use the {@code SO_KEEPALIVE} socket option.
192       */
193      static final boolean DEFAULT_USE_KEEPALIVE = true;
194    
195    
196    
197      /**
198       * The default value ({@code true}) for the setting that controls whether to
199       * use the {@code SO_LINGER} socket option.
200       */
201      static final boolean DEFAULT_USE_LINGER = true;
202    
203    
204    
205      /**
206       * The default value ({@code true}) for the setting that controls whether to
207       * use the {@code SO_REUSEADDR} socket option.
208       */
209      static final boolean DEFAULT_USE_REUSE_ADDRESS = true;
210    
211    
212    
213      /**
214       * The default value ({@code false}) for the setting that controls whether to
215       * use schema when reading data from the server.
216       */
217      static final boolean DEFAULT_USE_SCHEMA = false;
218    
219    
220    
221      /**
222       * The default value ({@code false}) for the setting that controls whether to
223       * operate in synchronous mode, in which only a single outstanding operation
224       * may be in progress on an associated connection at any given time.
225       */
226      static final boolean DEFAULT_USE_SYNCHRONOUS_MODE = false;
227    
228    
229    
230      /**
231       * The default value ({@code true}) for the setting that controls whether to
232       * use the {@code TCP_NODELAY} socket option.
233       */
234      static final boolean DEFAULT_USE_TCP_NODELAY = true;
235    
236    
237    
238      /**
239       * The default value (60000) for the setting that controls the timeout in
240       * milliseconds when trying to establish a new connection.
241       */
242      static final int DEFAULT_CONNECT_TIMEOUT_MILLIS = 60000;
243    
244    
245    
246      /**
247       * The default value (5) for the setting that controls the timeout in seconds
248       * that will be used with the {@code SO_LINGER} socket option.
249       */
250      static final int DEFAULT_LINGER_TIMEOUT_SECONDS = 5;
251    
252    
253    
254      /**
255       * The default value (20971520 bytes, or 20MB) for the setting that controls
256       * the maximum LDAP message size in bytes that will be allowed when reading
257       * data from a directory server.
258       */
259      static final int DEFAULT_MAX_MESSAGE_SIZE = 20971520;
260    
261    
262    
263      /**
264       * The default size to use for the receive buffer.
265       */
266      static final int DEFAULT_RECEIVE_BUFFER_SIZE = 0;
267    
268    
269    
270      /**
271       * The default value (5) for the setting that controls the referral hop limit.
272       */
273      static final int DEFAULT_REFERRAL_HOP_LIMIT = 5;
274    
275    
276    
277      /**
278       * The default size to use for the send buffer.
279       */
280      static final int DEFAULT_SEND_BUFFER_SIZE = 0;
281    
282    
283    
284      /**
285       * The default value (3600000 milliseconds, or one hour) for the setting that
286       * controls the default pooled schema timeout.
287       */
288      static final long DEFAULT_POOLED_SCHEMA_TIMEOUT_MILLIS = 3600000L;
289    
290    
291    
292      /**
293       * The default value (300000) for the setting that controls the default
294       * response timeout in milliseconds.
295       */
296      static final long DEFAULT_RESPONSE_TIMEOUT_MILLIS = 300000L;
297    
298    
299    
300      /**
301       * The default value for the setting that controls the default behavior with
302       * regard to whether to allow concurrent use of a socket factory to create
303       * client connections.
304       */
305      static final boolean DEFAULT_ALLOW_CONCURRENT_SOCKET_FACTORY_USE;
306      static
307      {
308        final String vmVendor =
309             StaticUtils.toLowerCase(System.getProperty("java.vm.vendor"));
310        DEFAULT_ALLOW_CONCURRENT_SOCKET_FACTORY_USE = ((vmVendor != null) &&
311             (vmVendor.contains("sun microsystems") ||
312              vmVendor.contains("oracle") ||
313              vmVendor.contains("apple")));
314      }
315    
316    
317    
318      /**
319       * The default {@code SSLSocketVerifier} instance that will be used for
320       * performing extra validation for {@code SSLSocket} instances.
321       */
322      static final SSLSocketVerifier DEFAULT_SSL_SOCKET_VERIFIER =
323           TrustAllSSLSocketVerifier.getInstance();
324    
325    
326    
327      // Indicates whether to send an abandon request for any operation for which no
328      // response is received in the maximum response timeout.
329      private boolean abandonOnTimeout;
330    
331      // Indicates whether to use synchronization prevent concurrent use of the
332      // socket factory instance associated with a connection or set of connections.
333      private boolean allowConcurrentSocketFactoryUse;
334    
335      // Indicates whether the connection should attempt to automatically reconnect
336      // if the connection to the server is lost.
337      private boolean autoReconnect;
338    
339      // Indicates whether to allow simple binds that contain a DN but no password.
340      private boolean bindWithDNRequiresPassword;
341    
342      // Indicates whether to capture a thread stack trace whenever an attempt is
343      // made to establish a connection;
344      private boolean captureConnectStackTrace;
345    
346      // Indicates whether to attempt to follow any referrals that are encountered.
347      private boolean followReferrals;
348    
349      // Indicates whether to use SO_KEEPALIVE for the underlying sockets.
350      private boolean useKeepAlive;
351    
352      // Indicates whether to use SO_LINGER for the underlying sockets.
353      private boolean useLinger;
354    
355      // Indicates whether to use SO_REUSEADDR for the underlying sockets.
356      private boolean useReuseAddress;
357    
358      // Indicates whether all connections in a connection pool should reference
359      // the same schema.
360      private boolean usePooledSchema;
361    
362      // Indicates whether to try to use schema information when reading data from
363      // the server.
364      private boolean useSchema;
365    
366      // Indicates whether to use synchronous mode in which only a single operation
367      // may be in progress on associated connections at any given time.
368      private boolean useSynchronousMode;
369    
370      // Indicates whether to use TCP_NODELAY for the underlying sockets.
371      private boolean useTCPNoDelay;
372    
373      // The disconnect handler for associated connections.
374      private DisconnectHandler disconnectHandler;
375    
376      // The connect timeout, in milliseconds.
377      private int connectTimeout;
378    
379      // The linger timeout to use if SO_LINGER is to be used.
380      private int lingerTimeout;
381    
382      // The maximum message size in bytes that will be allowed when reading data
383      // from a directory server.
384      private int maxMessageSize;
385    
386      // The socket receive buffer size to request.
387      private int receiveBufferSize;
388    
389      // The referral hop limit to use if referral following is enabled.
390      private int referralHopLimit;
391    
392      // The socket send buffer size to request.
393      private int sendBufferSize;
394    
395      // The pooled schema timeout, in milliseconds.
396      private long pooledSchemaTimeout;
397    
398      // The response timeout, in milliseconds.
399      private long responseTimeout;
400    
401      // Tne default referral connector that should be used for associated
402      // connections.
403      private ReferralConnector referralConnector;
404    
405      // The SSLSocketVerifier instance to use to perform extra validation on
406      // newly-established SSLSocket instances.
407      private SSLSocketVerifier sslSocketVerifier;
408    
409      // The unsolicited notification handler for associated connections.
410      private UnsolicitedNotificationHandler unsolicitedNotificationHandler;
411    
412    
413    
414      /**
415       * Creates a new set of LDAP connection options with the default settings.
416       */
417      public LDAPConnectionOptions()
418      {
419        abandonOnTimeout               = DEFAULT_ABANDON_ON_TIMEOUT;
420        autoReconnect                  = DEFAULT_AUTO_RECONNECT;
421        bindWithDNRequiresPassword     = DEFAULT_BIND_WITH_DN_REQUIRES_PASSWORD;
422        captureConnectStackTrace       = DEFAULT_CAPTURE_CONNECT_STACK_TRACE;
423        followReferrals                = DEFAULT_FOLLOW_REFERRALS;
424        useKeepAlive                   = DEFAULT_USE_KEEPALIVE;
425        useLinger                      = DEFAULT_USE_LINGER;
426        useReuseAddress                = DEFAULT_USE_REUSE_ADDRESS;
427        usePooledSchema                = DEFAULT_USE_POOLED_SCHEMA;
428        useSchema                      = DEFAULT_USE_SCHEMA;
429        useSynchronousMode             = DEFAULT_USE_SYNCHRONOUS_MODE;
430        useTCPNoDelay                  = DEFAULT_USE_TCP_NODELAY;
431        connectTimeout                 = DEFAULT_CONNECT_TIMEOUT_MILLIS;
432        lingerTimeout                  = DEFAULT_LINGER_TIMEOUT_SECONDS;
433        maxMessageSize                 = DEFAULT_MAX_MESSAGE_SIZE;
434        referralHopLimit               = DEFAULT_REFERRAL_HOP_LIMIT;
435        pooledSchemaTimeout            = DEFAULT_POOLED_SCHEMA_TIMEOUT_MILLIS;
436        responseTimeout                = DEFAULT_RESPONSE_TIMEOUT_MILLIS;
437        receiveBufferSize              = DEFAULT_RECEIVE_BUFFER_SIZE;
438        sendBufferSize                 = DEFAULT_SEND_BUFFER_SIZE;
439        disconnectHandler              = null;
440        referralConnector              = null;
441        sslSocketVerifier              = DEFAULT_SSL_SOCKET_VERIFIER;
442        unsolicitedNotificationHandler = null;
443    
444        allowConcurrentSocketFactoryUse =
445             DEFAULT_ALLOW_CONCURRENT_SOCKET_FACTORY_USE;
446      }
447    
448    
449    
450      /**
451       * Returns a duplicate of this LDAP connection options object that may be
452       * modified without impacting this instance.
453       *
454       * @return  A duplicate of this LDAP connection options object that may be
455       *          modified without impacting this instance.
456       */
457      public LDAPConnectionOptions duplicate()
458      {
459        final LDAPConnectionOptions o = new LDAPConnectionOptions();
460    
461        o.abandonOnTimeout                = abandonOnTimeout;
462        o.allowConcurrentSocketFactoryUse = allowConcurrentSocketFactoryUse;
463        o.autoReconnect                   = autoReconnect;
464        o.bindWithDNRequiresPassword      = bindWithDNRequiresPassword;
465        o.captureConnectStackTrace        = captureConnectStackTrace;
466        o.followReferrals                 = followReferrals;
467        o.useKeepAlive                    = useKeepAlive;
468        o.useLinger                       = useLinger;
469        o.useReuseAddress                 = useReuseAddress;
470        o.usePooledSchema                 = usePooledSchema;
471        o.useSchema                       = useSchema;
472        o.useSynchronousMode              = useSynchronousMode;
473        o.useTCPNoDelay                   = useTCPNoDelay;
474        o.connectTimeout                  = connectTimeout;
475        o.lingerTimeout                   = lingerTimeout;
476        o.maxMessageSize                  = maxMessageSize;
477        o.pooledSchemaTimeout             = pooledSchemaTimeout;
478        o.responseTimeout                 = responseTimeout;
479        o.referralConnector               = referralConnector;
480        o.referralHopLimit                = referralHopLimit;
481        o.disconnectHandler               = disconnectHandler;
482        o.unsolicitedNotificationHandler  = unsolicitedNotificationHandler;
483        o.receiveBufferSize               = receiveBufferSize;
484        o.sendBufferSize                  = sendBufferSize;
485        o.sslSocketVerifier               = sslSocketVerifier;
486    
487        return o;
488      }
489    
490    
491    
492      /**
493       * Indicates whether associated connections should attempt to automatically
494       * reconnect to the target server if the connection is lost.  Note that this
495       * option will not have any effect on pooled connections because defunct
496       * pooled connections will be replaced by newly-created connections rather
497       * than attempting to re-establish the existing connection.
498       *
499       * @return  {@code true} if associated connections should attempt to
500       *          automatically reconnect to the target server if the connection is
501       *          lost, or {@code false} if not.
502       */
503      public boolean autoReconnect()
504      {
505        return autoReconnect;
506      }
507    
508    
509    
510      /**
511       * Specifies whether associated connections should attempt to automatically
512       * reconnect to the target server if the connection is lost.  Note that
513       * automatic reconnection will only be available for authenticated clients if
514       * the authentication mechanism used provides support for re-binding on a new
515       * connection.  Also note that this option will not have any effect on pooled
516       * connections because defunct pooled connections will be replaced by
517       * newly-created connections rather than attempting to re-establish the
518       * existing connection.  Further, auto-reconnect should not be used with
519       * connections that use StartTLS or some other mechanism to alter the state
520       * of the connection beyond authentication.
521       *
522       * @param  autoReconnect  Specifies whether associated connections should
523       *                        attempt to automatically reconnect to the target
524       *                        server if the connection is lost.
525       */
526      public void setAutoReconnect(final boolean autoReconnect)
527      {
528        this.autoReconnect = autoReconnect;
529      }
530    
531    
532    
533      /**
534       * Indicates whether the SDK should allow simple bind operations that contain
535       * a bind DN but no password.  Binds of this type may represent a security
536       * vulnerability in client applications because they may cause the client to
537       * believe that the user is properly authenticated when the server considers
538       * it to be an unauthenticated connection.
539       *
540       * @return  {@code true} if the SDK should allow simple bind operations that
541       *          contain a bind DN but no password, or {@code false} if not.
542       */
543      public boolean bindWithDNRequiresPassword()
544      {
545        return bindWithDNRequiresPassword;
546      }
547    
548    
549    
550      /**
551       * Specifies whether the SDK should allow simple bind operations that contain
552       * a bind DN but no password.
553       *
554       * @param  bindWithDNRequiresPassword  Indicates whether the SDK should allow
555       *                                     simple bind operations that contain a
556       *                                     bind DN but no password.
557       */
558      public void setBindWithDNRequiresPassword(
559                       final boolean bindWithDNRequiresPassword)
560      {
561        this.bindWithDNRequiresPassword = bindWithDNRequiresPassword;
562      }
563    
564    
565    
566      /**
567       * Indicates whether the LDAP SDK should capture a thread stack trace for each
568       * attempt made to establish a connection.  If this is enabled, then the
569       * {@code LDAPConnection#getConnectStackTrace()}  method may be used to
570       * retrieve the stack trace.
571       *
572       * @return  {@code true} if a thread stack trace should be captured whenever a
573       *          connection is established, or {@code false} if not.
574       */
575      public boolean captureConnectStackTrace()
576      {
577        return captureConnectStackTrace;
578      }
579    
580    
581    
582      /**
583       * Specifies whether the LDAP SDK should capture a thread stack trace for each
584       * attempt made to establish a connection.
585       *
586       * @param  captureConnectStackTrace  Indicates whether to capture a thread
587       *                                   stack trace for each attempt made to
588       *                                   establish a connection.
589       */
590      public void setCaptureConnectStackTrace(
591                       final boolean captureConnectStackTrace)
592      {
593        this.captureConnectStackTrace = captureConnectStackTrace;
594      }
595    
596    
597    
598      /**
599       * Retrieves the maximum length of time in milliseconds that a connection
600       * attempt should be allowed to continue before giving up.
601       *
602       * @return  The maximum length of time in milliseconds that a connection
603       *          attempt should be allowed to continue before giving up, or zero
604       *          to indicate that there should be no connect timeout.
605       */
606      public int getConnectTimeoutMillis()
607      {
608        return connectTimeout;
609      }
610    
611    
612    
613      /**
614       * Specifies the maximum length of time in milliseconds that a connection
615       * attempt should be allowed to continue before giving up.  A value of zero
616       * indicates that there should be no connect timeout.
617       *
618       * @param  connectTimeout  The maximum length of time in milliseconds that a
619       *                         connection attempt should be allowed to continue
620       *                         before giving up.
621       */
622      public void setConnectTimeoutMillis(final int connectTimeout)
623      {
624        this.connectTimeout = connectTimeout;
625      }
626    
627    
628    
629      /**
630       * Retrieves the maximum length of time in milliseconds that an operation
631       * should be allowed to block while waiting for a response from the server.
632       * This may be overridden on a per-operation basis.
633       *
634       * @return  The maximum length of time in milliseconds that an operation
635       *          should be allowed to block while waiting for a response from the
636       *          server, or zero if there should not be any default timeout.
637       */
638      public long getResponseTimeoutMillis()
639      {
640        return responseTimeout;
641      }
642    
643    
644    
645      /**
646       * Specifies the maximum length of time in milliseconds that an operation
647       * should be allowed to block while waiting for a response from the server.  A
648       * value of zero indicates that there should be no timeout.
649       *
650       * @param  responseTimeout  The maximum length of time in milliseconds that an
651       *                          operation should be allowed to block while waiting
652       *                          for a response from the server.
653       *
654       */
655      public void setResponseTimeoutMillis(final long responseTimeout)
656      {
657        if (responseTimeout < 0)
658        {
659          this.responseTimeout = 0L;
660        }
661        else
662        {
663          this.responseTimeout = responseTimeout;
664        }
665      }
666    
667    
668    
669      /**
670       * Indicates whether the LDAP SDK should attempt to abandon any request for
671       * which no response is received in the maximum response timeout period.
672       *
673       * @return  {@code true} if the LDAP SDK should attempt to abandon any request
674       *          for which no response is received in the maximum response timeout
675       *          period, or {@code false} if no abandon attempt should be made in
676       *          this circumstance.
677       */
678      public boolean abandonOnTimeout()
679      {
680        return abandonOnTimeout;
681      }
682    
683    
684    
685      /**
686       * Specifies whether the LDAP SDK should attempt to abandon any request for
687       * which no response is received in the maximum response timeout period.
688       *
689       * @param  abandonOnTimeout  Indicates whether the LDAP SDK should attempt to
690       *                           abandon any request for which no response is
691       *                           received in the maximum response timeout period.
692       */
693      public void setAbandonOnTimeout(final boolean abandonOnTimeout)
694      {
695        this.abandonOnTimeout = abandonOnTimeout;
696      }
697    
698    
699    
700      /**
701       * Indicates whether to use the SO_KEEPALIVE option for the underlying sockets
702       * used by associated connections.
703       *
704       * @return  {@code true} if the SO_KEEPALIVE option should be used for the
705       *          underlying sockets, or {@code false} if not.
706       */
707      public boolean useKeepAlive()
708      {
709        return useKeepAlive;
710      }
711    
712    
713    
714      /**
715       * Specifies whether to use the SO_KEEPALIVE option for the underlying sockets
716       * used by associated connections.  Changes to this setting will take effect
717       * only for new sockets, and not for existing sockets.
718       *
719       * @param  useKeepAlive  Indicates whether to use the SO_KEEPALIVE option for
720       *                       the underlying sockets used by associated
721       *                       connections.
722       */
723      public void setUseKeepAlive(final boolean useKeepAlive)
724      {
725        this.useKeepAlive = useKeepAlive;
726      }
727    
728    
729    
730      /**
731       * Indicates whether to use the SO_LINGER option for the underlying sockets
732       * used by associated connections.
733       *
734       * @return  {@code true} if the SO_LINGER option should be used for the
735       *          underlying sockets, or {@code false} if not.
736       */
737      public boolean useLinger()
738      {
739        return useLinger;
740      }
741    
742    
743    
744      /**
745       * Retrieves the linger timeout in seconds that will be used if the SO_LINGER
746       * socket option is enabled.
747       *
748       * @return  The linger timeout in seconds that will be used if the SO_LINGER
749       *          socket option is enabled.
750       */
751      public int getLingerTimeoutSeconds()
752      {
753        return lingerTimeout;
754      }
755    
756    
757    
758      /**
759       * Specifies whether to use the SO_LINGER option for the underlying sockets
760       * used by associated connections.  Changes to this setting will take effect
761       * only for new sockets, and not for existing sockets.
762       *
763       * @param  useLinger      Indicates whether to use the SO_LINGER option for
764       *                        the underlying sockets used by associated
765       *                        connections.
766       * @param  lingerTimeout  The linger timeout in seconds that should be used if
767       *                        this capability is enabled.
768       */
769      public void setUseLinger(final boolean useLinger, final int lingerTimeout)
770      {
771        this.useLinger     = useLinger;
772        this.lingerTimeout = lingerTimeout;
773      }
774    
775    
776    
777      /**
778       * Indicates whether to use the SO_REUSEADDR option for the underlying sockets
779       * used by associated connections.
780       *
781       * @return  {@code true} if the SO_REUSEADDR option should be used for the
782       *          underlying sockets, or {@code false} if not.
783       */
784      public boolean useReuseAddress()
785      {
786        return useReuseAddress;
787      }
788    
789    
790    
791      /**
792       * Specifies whether to use the SO_REUSEADDR option for the underlying sockets
793       * used by associated connections.  Changes to this setting will take effect
794       * only for new sockets, and not for existing sockets.
795       *
796       * @param  useReuseAddress  Indicates whether to use the SO_REUSEADDR option
797       *                          for the underlying sockets used by associated
798       *                          connections.
799       */
800      public void setUseReuseAddress(final boolean useReuseAddress)
801      {
802        this.useReuseAddress = useReuseAddress;
803      }
804    
805    
806    
807      /**
808       * Indicates whether to try to use schema information when reading data from
809       * the server (e.g., to select the appropriate matching rules for the
810       * attributes included in a search result entry).
811       *
812       * @return  {@code true} if schema should be used when reading data from the
813       *          server, or {@code false} if not.
814       */
815      public boolean useSchema()
816      {
817        return useSchema;
818      }
819    
820    
821    
822      /**
823       * Specifies whether to try to use schema information when reading data from
824       * the server (e.g., to select the appropriate matching rules for the
825       * attributes included in a search result entry).
826       * <BR><BR>
827       * Note that calling this method with a value of {@code true} will also cause
828       * the {@code usePooledSchema} setting to be given a value of false, since
829       * the two values should not both be {@code true} at the same time.
830       *
831       * @param  useSchema  Indicates whether to try to use schema information when
832       *                    reading data from the server.
833       */
834      public void setUseSchema(final boolean useSchema)
835      {
836        this.useSchema = useSchema;
837        if (useSchema)
838        {
839          usePooledSchema = false;
840        }
841      }
842    
843    
844    
845      /**
846       * Indicates whether to have connections that are part of a pool try to use
847       * shared schema information when reading data from the server (e.g., to
848       * select the appropriate matching rules for the attributes included in a
849       * search result entry).  If this is {@code true}, then connections in a
850       * connection pool will share the same cached schema information in a way that
851       * attempts to reduce network bandwidth and connection establishment time (by
852       * avoiding the need for each connection to retrieve its own copy of the
853       * schema).
854       * <BR><BR>
855       * If pooled schema is to be used, then it may be configured to expire so that
856       * the schema may be periodically re-retrieved for new connections to allow
857       * schema updates to be incorporated.  This behavior is controlled by the
858       * value returned by the {@code getPooledSchemaTimeoutMillis} method.
859       *
860       * @return  {@code true} if all connections in a connection pool should
861       *          reference the same schema object, or {@code false} if each
862       *          connection should retrieve its own copy of the schema.
863       */
864      public boolean usePooledSchema()
865      {
866        return usePooledSchema;
867      }
868    
869    
870    
871      /**
872       * Indicates whether to have connections that are part of a pool try to use
873       * shared schema information when reading data from the server (e.g., to
874       * select the appropriate matching rules for the attributes included in a
875       * search result entry).
876       * <BR><BR>
877       * Note that calling this method with a value of {@code true} will also cause
878       * the {@code useSchema} setting to be given a value of false, since the two
879       * values should not both be {@code true} at the same time.
880       *
881       * @param  usePooledSchema  Indicates whether all connections in a connection
882       *                          pool should reference the same schema object
883       *                          rather than attempting to retrieve their own copy
884       *                          of the schema.
885       */
886      public void setUsePooledSchema(final boolean usePooledSchema)
887      {
888        this.usePooledSchema = usePooledSchema;
889        if (usePooledSchema)
890        {
891          useSchema = false;
892        }
893      }
894    
895    
896    
897      /**
898       * Retrieves the maximum length of time in milliseconds that a pooled schema
899       * object should be considered fresh.  If the schema referenced by a
900       * connection pool is at least this old, then the next connection attempt may
901       * cause a new version of the schema to be retrieved.
902       * <BR><BR>
903       * This will only be used if the {@code usePooledSchema} method returns
904       * {@code true}.  A value of zero indicates that the pooled schema will never
905       * expire.
906       *
907       * @return  The maximum length of time, in milliseconds, that a pooled schema
908       *          object should be considered fresh, or zero if pooled schema
909       *          objects should never expire.
910       */
911      public long getPooledSchemaTimeoutMillis()
912      {
913        return pooledSchemaTimeout;
914      }
915    
916    
917    
918      /**
919       * Specifies the maximum length of time in milliseconds that a pooled schema
920       * object should be considered fresh.
921       *
922       * @param  pooledSchemaTimeout  The maximum length of time in milliseconds
923       *                              that a pooled schema object should be
924       *                              considered fresh.  A value less than or equal
925       *                              to zero will indicate that pooled schema
926       *                              should never expire.
927       */
928      public void setPooledSchemaTimeoutMillis(final long pooledSchemaTimeout)
929      {
930        if (pooledSchemaTimeout < 0)
931        {
932          this.pooledSchemaTimeout = 0L;
933        }
934        else
935        {
936          this.pooledSchemaTimeout = pooledSchemaTimeout;
937        }
938      }
939    
940    
941    
942      /**
943       * Indicates whether to operate in synchronous mode, in which at most one
944       * operation may be in progress at any time on a given connection, which may
945       * allow it to operate more efficiently and without requiring a separate
946       * reader thread per connection.  The LDAP SDK will not absolutely enforce
947       * this restriction, but when operating in this mode correct behavior
948       * cannot be guaranteed when multiple attempts are made to use a connection
949       * for multiple concurrent operations.
950       * <BR><BR>
951       * Note that if synchronous mode is to be used, then this connection option
952       * must be set on the connection before any attempt is made to establish the
953       * connection.  Once the connection has been established, then it will
954       * continue to operate in synchronous or asynchronous mode based on the
955       * options in place at the time it was connected.
956       *
957       * @return  {@code true} if associated connections should operate in
958       *          synchronous mode, or {@code false} if not.
959       */
960      public boolean useSynchronousMode()
961      {
962        return useSynchronousMode;
963      }
964    
965    
966    
967      /**
968       * Specifies whether to operate in synchronous mode, in which at most one
969       * operation may be in progress at any time on a given connection.
970       * <BR><BR>
971       * Note that if synchronous mode is to be used, then this connection option
972       * must be set on the connection before any attempt is made to establish the
973       * connection.  Once the connection has been established, then it will
974       * continue to operate in synchronous or asynchronous mode based on the
975       * options in place at the time it was connected.
976       *
977       * @param  useSynchronousMode  Indicates whether to operate in synchronous
978       *                             mode.
979       */
980      public void setUseSynchronousMode(final boolean useSynchronousMode)
981      {
982        this.useSynchronousMode = useSynchronousMode;
983      }
984    
985    
986    
987      /**
988       * Indicates whether to use the TCP_NODELAY option for the underlying sockets
989       * used by associated connections.
990       *
991       * @return  {@code true} if the TCP_NODELAY option should be used for the
992       *          underlying sockets, or {@code false} if not.
993       */
994      public boolean useTCPNoDelay()
995      {
996        return useTCPNoDelay;
997      }
998    
999    
1000    
1001      /**
1002       * Specifies whether to use the TCP_NODELAY option for the underlying sockets
1003       * used by associated connections.  Changes to this setting will take effect
1004       * only for new sockets, and not for existing sockets.
1005       *
1006       * @param  useTCPNoDelay  Indicates whether to use the TCP_NODELAY option for
1007       *                        the underlying sockets used by associated
1008       *                        connections.
1009       */
1010      public void setUseTCPNoDelay(final boolean useTCPNoDelay)
1011      {
1012        this.useTCPNoDelay = useTCPNoDelay;
1013      }
1014    
1015    
1016    
1017      /**
1018       * Indicates whether associated connections should attempt to follow any
1019       * referrals that they encounter.
1020       *
1021       * @return  {@code true} if associated connections should attempt to follow
1022       *          any referrals that they encounter, or {@code false} if not.
1023       */
1024      public boolean followReferrals()
1025      {
1026        return followReferrals;
1027      }
1028    
1029    
1030    
1031      /**
1032       * Specifies whether associated connections should attempt to follow any
1033       * referrals that they encounter, using the referral connector for the
1034       * associated connection.
1035       *
1036       * @param  followReferrals  Specifies whether associated connections should
1037       *                          attempt to follow any referrals that they
1038       *                          encounter.
1039       */
1040      public void setFollowReferrals(final boolean followReferrals)
1041      {
1042        this.followReferrals = followReferrals;
1043      }
1044    
1045    
1046    
1047      /**
1048       * Retrieves the maximum number of hops that a connection should take when
1049       * trying to follow a referral.
1050       *
1051       * @return  The maximum number of hops that a connection should take when
1052       *          trying to follow a referral.
1053       */
1054      public int getReferralHopLimit()
1055      {
1056        return referralHopLimit;
1057      }
1058    
1059    
1060    
1061      /**
1062       * Specifies the maximum number of hops that a connection should take when
1063       * trying to follow a referral.
1064       *
1065       * @param  referralHopLimit  The maximum number of hops that a connection
1066       *                           should take when trying to follow a referral.  It
1067       *                           must be greater than zero.
1068       */
1069      public void setReferralHopLimit(final int referralHopLimit)
1070      {
1071        ensureTrue(referralHopLimit > 0,
1072             "LDAPConnectionOptions.referralHopLimit must be greater than 0.");
1073    
1074        this.referralHopLimit = referralHopLimit;
1075      }
1076    
1077    
1078    
1079      /**
1080       * Retrieves the referral connector that will be used to establish and
1081       * optionally authenticate connections to servers when attempting to follow
1082       * referrals, if defined.
1083       *
1084       * @return  The referral connector that will be used to establish and
1085       *          optionally authenticate connections to servers when attempting to
1086       *          follow referrals, or {@code null} if no specific referral
1087       *          connector has been configured and referral connections should be
1088       *          created using the same socket factory and bind request as the
1089       *          connection on which the referral was received.
1090       */
1091      public ReferralConnector getReferralConnector()
1092      {
1093        return referralConnector;
1094      }
1095    
1096    
1097    
1098      /**
1099       * Specifies the referral connector that should be used to establish and
1100       * optionally authenticate connections to servers when attempting to follow
1101       * referrals.
1102       *
1103       * @param  referralConnector  The referral connector that will be used to
1104       *                            establish and optionally authenticate
1105       *                            connections to servers when attempting to follow
1106       *                            referrals.  It may be {@code null} to indicate
1107       *                            that the same socket factory and bind request
1108       *                            as the connection on which the referral was
1109       *                            received should be used to establish and
1110       *                            authenticate connections for following
1111       *                            referrals.
1112       */
1113      public void setReferralConnector(final ReferralConnector referralConnector)
1114      {
1115        this.referralConnector = referralConnector;
1116      }
1117    
1118    
1119    
1120      /**
1121       * Retrieves the maximum size in bytes for an LDAP message that a connection
1122       * will attempt to read from the directory server.  If it encounters an LDAP
1123       * message that is larger than this size, then the connection will be
1124       * terminated.
1125       *
1126       * @return  The maximum size in bytes for an LDAP message that a connection
1127       *          will attempt to read from the directory server, or 0 if no limit
1128       *          will be enforced.
1129       */
1130      public int getMaxMessageSize()
1131      {
1132        return maxMessageSize;
1133      }
1134    
1135    
1136    
1137      /**
1138       * Specifies the maximum size in bytes for an LDAP message that a connection
1139       * will attempt to read from the directory server.  If it encounters an LDAP
1140       * message that is larger than this size, then the connection will be
1141       * terminated.
1142       *
1143       * @param  maxMessageSize  The maximum size in bytes for an LDAP message that
1144       *                         a connection will attempt to read from the
1145       *                         directory server.  A value less than or equal to
1146       *                         zero indicates that no limit should be enforced.
1147       */
1148      public void setMaxMessageSize(final int maxMessageSize)
1149      {
1150        if (maxMessageSize > 0)
1151        {
1152          this.maxMessageSize = maxMessageSize;
1153        }
1154        else
1155        {
1156          this.maxMessageSize = 0;
1157        }
1158      }
1159    
1160    
1161    
1162      /**
1163       * Retrieves the disconnect handler to use for associated connections.
1164       *
1165       * @return  the disconnect handler to use for associated connections, or
1166       *          {@code null} if none is defined.
1167       */
1168      public DisconnectHandler getDisconnectHandler()
1169      {
1170        return disconnectHandler;
1171      }
1172    
1173    
1174    
1175      /**
1176       * Specifies the disconnect handler to use for associated connections.
1177       *
1178       * @param  handler  The disconnect handler to use for associated connections.
1179       */
1180      public void setDisconnectHandler(final DisconnectHandler handler)
1181      {
1182        disconnectHandler = handler;
1183      }
1184    
1185    
1186    
1187      /**
1188       * Retrieves the unsolicited notification handler to use for associated
1189       * connections.
1190       *
1191       * @return  The unsolicited notification handler to use for associated
1192       *          connections, or {@code null} if none is defined.
1193       */
1194      public UnsolicitedNotificationHandler getUnsolicitedNotificationHandler()
1195      {
1196        return unsolicitedNotificationHandler;
1197      }
1198    
1199    
1200    
1201      /**
1202       * Specifies the unsolicited notification handler to use for associated
1203       * connections.
1204       *
1205       * @param  handler  The unsolicited notification handler to use for associated
1206       *                  connections.
1207       */
1208      public void setUnsolicitedNotificationHandler(
1209                       final UnsolicitedNotificationHandler handler)
1210      {
1211        unsolicitedNotificationHandler = handler;
1212      }
1213    
1214    
1215    
1216      /**
1217       * Retrieves the socket receive buffer size that should be requested when
1218       * establishing a connection.
1219       *
1220       * @return  The socket receive buffer size that should be requested when
1221       *          establishing a connection, or zero if the default size should be
1222       *          used.
1223       */
1224      public int getReceiveBufferSize()
1225      {
1226        return receiveBufferSize;
1227      }
1228    
1229    
1230    
1231      /**
1232       * Specifies the socket receive buffer size that should be requested when
1233       * establishing a connection.
1234       *
1235       * @param  receiveBufferSize  The socket receive buffer size that should be
1236       *                            requested when establishing a connection, or
1237       *                            zero if the default size should be used.
1238       */
1239      public void setReceiveBufferSize(final int receiveBufferSize)
1240      {
1241        if (receiveBufferSize < 0)
1242        {
1243          this.receiveBufferSize = 0;
1244        }
1245        else
1246        {
1247          this.receiveBufferSize = receiveBufferSize;
1248        }
1249      }
1250    
1251    
1252    
1253      /**
1254       * Retrieves the socket send buffer size that should be requested when
1255       * establishing a connection.
1256       *
1257       * @return  The socket send buffer size that should be requested when
1258       *          establishing a connection, or zero if the default size should be
1259       *          used.
1260       */
1261      public int getSendBufferSize()
1262      {
1263        return sendBufferSize;
1264      }
1265    
1266    
1267    
1268      /**
1269       * Specifies the socket send buffer size that should be requested when
1270       * establishing a connection.
1271       *
1272       * @param  sendBufferSize  The socket send buffer size that should be
1273       *                         requested when establishing a connection, or zero
1274       *                         if the default size should be used.
1275       */
1276      public void setSendBufferSize(final int sendBufferSize)
1277      {
1278        if (sendBufferSize < 0)
1279        {
1280          this.sendBufferSize = 0;
1281        }
1282        else
1283        {
1284          this.sendBufferSize = sendBufferSize;
1285        }
1286      }
1287    
1288    
1289    
1290      /**
1291       * Indicates whether to allow a socket factory instance (which may be shared
1292       * across multiple connections) to be used create multiple sockets
1293       * concurrently.  In general, socket factory implementations are threadsafe
1294       * and can be to create multiple connections simultaneously across separate
1295       * threads, but this is known to not be the case in some VM implementations
1296       * (e.g., SSL socket factories in IBM JVMs).  This setting may be used to
1297       * indicate whether concurrent socket creation attempts should be allowed
1298       * (which may allow for better and more consistent performance, especially in
1299       * cases where a connection attempt fails due to a timeout) or prevented
1300       * (which may be necessary for non-threadsafe socket factory implementations).
1301       *
1302       * @return  {@code true} if multiple threads should be able to concurrently
1303       *          use the same socket factory instance, or {@code false} if Java
1304       *          synchronization should be used to ensure that no more than one
1305       *          thread is allowed to use a socket factory at any given time.
1306       */
1307      public boolean allowConcurrentSocketFactoryUse()
1308      {
1309        return allowConcurrentSocketFactoryUse;
1310      }
1311    
1312    
1313    
1314      /**
1315       * Specifies whether to allow a socket factory instance (which may be shared
1316       * across multiple connections) to be used create multiple sockets
1317       * concurrently.  In general, socket factory implementations are threadsafe
1318       * and can be to create multiple connections simultaneously across separate
1319       * threads, but this is known to not be the case in some VM implementations
1320       * (e.g., SSL socket factories in IBM JVMs).  This setting may be used to
1321       * indicate whether concurrent socket creation attempts should be allowed
1322       * (which may allow for better and more consistent performance, especially in
1323       * cases where a connection attempt fails due to a timeout) or prevented
1324       * (which may be necessary for non-threadsafe socket factory implementations).
1325       *
1326       * @param  allowConcurrentSocketFactoryUse  Indicates whether to allow a
1327       *                                          socket factory instance to be used
1328       *                                          to create multiple sockets
1329       *                                          concurrently.
1330       */
1331      public void setAllowConcurrentSocketFactoryUse(
1332                       final boolean allowConcurrentSocketFactoryUse)
1333      {
1334        this.allowConcurrentSocketFactoryUse = allowConcurrentSocketFactoryUse;
1335      }
1336    
1337    
1338    
1339      /**
1340       * Retrieves the {@code SSLSocketVerifier} that will be used to perform
1341       * additional validation for any newly-created {@code SSLSocket} instances.
1342       *
1343       * @return  The {@code SSLSocketVerifier} that will be used to perform
1344       *          additional validation for any newly-created {@code SSLSocket}
1345       *          instances.
1346       */
1347      public SSLSocketVerifier getSSLSocketVerifier()
1348      {
1349        return sslSocketVerifier;
1350      }
1351    
1352    
1353    
1354      /**
1355       * Specifies the {@code SSLSocketVerifier} that will be used to perform
1356       * additional validation for any newly-created {@code SSLSocket} instances.
1357       *
1358       * @param  sslSocketVerifier  The {@code SSLSocketVerifier} that will be used
1359       *                            to perform additional validation for any
1360       *                            newly-created {@code SSLSocket} instances.
1361       */
1362      public void setSSLSocketVerifier(final SSLSocketVerifier sslSocketVerifier)
1363      {
1364        if (sslSocketVerifier == null)
1365        {
1366          this.sslSocketVerifier = DEFAULT_SSL_SOCKET_VERIFIER;
1367        }
1368        else
1369        {
1370          this.sslSocketVerifier = sslSocketVerifier;
1371        }
1372      }
1373    
1374    
1375    
1376      /**
1377       * Retrieves a string representation of this LDAP connection.
1378       *
1379       * @return  A string representation of this LDAP connection.
1380       */
1381      @Override()
1382      public String toString()
1383      {
1384        final StringBuilder buffer = new StringBuilder();
1385        toString(buffer);
1386        return buffer.toString();
1387      }
1388    
1389    
1390    
1391      /**
1392       * Appends a string representation of this LDAP connection to the provided
1393       * buffer.
1394       *
1395       * @param  buffer  The buffer to which to append a string representation of
1396       *                 this LDAP connection.
1397       */
1398      public void toString(final StringBuilder buffer)
1399      {
1400        buffer.append("LDAPConnectionOptions(autoReconnect=");
1401        buffer.append(autoReconnect);
1402        buffer.append(", bindWithDNRequiresPassword=");
1403        buffer.append(bindWithDNRequiresPassword);
1404        buffer.append(", followReferrals=");
1405        buffer.append(followReferrals);
1406        if (followReferrals)
1407        {
1408          buffer.append(", referralHopLimit=");
1409          buffer.append(referralHopLimit);
1410        }
1411        if (referralConnector != null)
1412        {
1413          buffer.append(", referralConnectorClass=");
1414          buffer.append(referralConnector.getClass().getName());
1415        }
1416        buffer.append(", useKeepAlive=");
1417        buffer.append(useKeepAlive);
1418        buffer.append(", useLinger=");
1419        if (useLinger)
1420        {
1421          buffer.append("true, lingerTimeoutSeconds=");
1422          buffer.append(lingerTimeout);
1423        }
1424        else
1425        {
1426          buffer.append("false");
1427        }
1428        buffer.append(", useReuseAddress=");
1429        buffer.append(useReuseAddress);
1430        buffer.append(", useSchema=");
1431        buffer.append(useSchema);
1432        buffer.append(", usePooledSchema=");
1433        buffer.append(usePooledSchema);
1434        buffer.append(", pooledSchemaTimeoutMillis=");
1435        buffer.append(pooledSchemaTimeout);
1436        buffer.append(", useSynchronousMode=");
1437        buffer.append(useSynchronousMode);
1438        buffer.append(", useTCPNoDelay=");
1439        buffer.append(useTCPNoDelay);
1440        buffer.append(", captureConnectStackTrace=");
1441        buffer.append(captureConnectStackTrace);
1442        buffer.append(", connectTimeoutMillis=");
1443        buffer.append(connectTimeout);
1444        buffer.append(", responseTimeoutMillis=");
1445        buffer.append(responseTimeout);
1446        buffer.append(", abandonOnTimeout=");
1447        buffer.append(abandonOnTimeout);
1448        buffer.append(", maxMessageSize=");
1449        buffer.append(maxMessageSize);
1450        buffer.append(", receiveBufferSize=");
1451        buffer.append(receiveBufferSize);
1452        buffer.append(", sendBufferSize=");
1453        buffer.append(sendBufferSize);
1454        buffer.append(", allowConcurrentSocketFactoryUse=");
1455        buffer.append(allowConcurrentSocketFactoryUse);
1456        if (disconnectHandler != null)
1457        {
1458          buffer.append(", disconnectHandlerClass=");
1459          buffer.append(disconnectHandler.getClass().getName());
1460        }
1461        if (unsolicitedNotificationHandler != null)
1462        {
1463          buffer.append(", unsolicitedNotificationHandlerClass=");
1464          buffer.append(unsolicitedNotificationHandler.getClass().getName());
1465        }
1466    
1467        buffer.append(", sslSocketVerifierClass='");
1468        buffer.append(sslSocketVerifier.getClass().getName());
1469        buffer.append('\'');
1470    
1471        buffer.append(')');
1472      }
1473    }