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