001 /*
002 * Copyright 2010-2013 UnboundID Corp.
003 * All Rights Reserved.
004 */
005 /*
006 * Copyright (C) 2010-2013 UnboundID Corp.
007 *
008 * This program is free software; you can redistribute it and/or modify
009 * it under the terms of the GNU General Public License (GPLv2 only)
010 * or the terms of the GNU Lesser General Public License (LGPLv2.1 only)
011 * as published by the Free Software Foundation.
012 *
013 * This program is distributed in the hope that it will be useful,
014 * but WITHOUT ANY WARRANTY; without even the implied warranty of
015 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
016 * GNU General Public License for more details.
017 *
018 * You should have received a copy of the GNU General Public License
019 * along with this program; if not, see <http://www.gnu.org/licenses>.
020 */
021 package com.unboundid.ldap.listener;
022
023
024
025 import java.net.InetAddress;
026 import javax.net.ServerSocketFactory;
027
028 import com.unboundid.util.Mutable;
029 import com.unboundid.util.ThreadSafety;
030 import com.unboundid.util.ThreadSafetyLevel;
031 import com.unboundid.util.Validator;
032
033
034
035 /**
036 * This class provides a mechanism for defining the configuration to use for an
037 * {@link LDAPListener} instance. Note that while instances of this class are
038 * not inherently threadsafe, a private copy of the configuration will be
039 * created whenever a new {@code LDAPListener} is created so that this
040 * configuration may continue to be altered for new instances without impacting
041 * any existing listeners.
042 */
043 @Mutable()
044 @ThreadSafety(level=ThreadSafetyLevel.NOT_THREADSAFE)
045 public final class LDAPListenerConfig
046 {
047 // Indicates whether to use the SO_KEEPALIVE socket option for sockets
048 // accepted by the listener.
049 private boolean useKeepAlive;
050
051 // Indicates whether to use the SO_LINGER socket option for sockets accepted
052 // by the listener.
053 private boolean useLinger;
054
055 // Indicates whether to use the SO_REUSEADDR socket option for sockets
056 // accepted by the listener.
057 private boolean useReuseAddress;
058
059 // Indicates whether to use the TCP_NODELAY for sockets accepted by the
060 // listener.
061 private boolean useTCPNoDelay;
062
063 // The address on which to listen for client connections.
064 private InetAddress listenAddress;
065
066 // The linger timeout in seconds to use for sockets accepted by the listener.
067 private int lingerTimeout;
068
069 // The port on which to listen for client connections.
070 private int listenPort;
071
072 // The receive buffer size to use for sockets accepted by the listener.
073 private int receiveBufferSize;
074
075 // The send buffer size to use for sockets accepted by the listener.
076 private int sendBufferSize;
077
078 // The exception handler to use for the listener and associated connections.
079 private LDAPListenerExceptionHandler exceptionHandler;
080
081 // The request handler that will be used to process requests read from
082 // clients.
083 private LDAPListenerRequestHandler requestHandler;
084
085 // The factory that will be used to create server sockets.
086 private ServerSocketFactory serverSocketFactory;
087
088
089
090 /**
091 * Creates a new listener configuration.
092 *
093 * @param listenPort The port on which to listen for client connections.
094 * It must be an integer between 1 and 65535, or 0 to
095 * indicate that a free port should be chosen by the
096 * JVM.
097 * @param requestHandler The request handler that will be used to process
098 * requests read from clients. It must not be
099 * {@code null}.
100 */
101 public LDAPListenerConfig(final int listenPort,
102 final LDAPListenerRequestHandler requestHandler)
103 {
104 Validator.ensureTrue((listenPort >= 0) && (listenPort <= 65535));
105 Validator.ensureNotNull(requestHandler);
106
107 this.listenPort = listenPort;
108 this.requestHandler = requestHandler;
109
110 useKeepAlive = true;
111 useLinger = true;
112 useReuseAddress = true;
113 useTCPNoDelay = true;
114 lingerTimeout = 5;
115 listenAddress = null;
116 receiveBufferSize = 0;
117 sendBufferSize = 0;
118 exceptionHandler = null;
119 serverSocketFactory = ServerSocketFactory.getDefault();
120 }
121
122
123
124 /**
125 * Retrieves the port number on which to listen for client connections. A
126 * value of zero indicates that the listener should allow the JVM to choose a
127 * free port.
128 *
129 * @return The port number on which to listen for client connections.
130 */
131 public int getListenPort()
132 {
133 return listenPort;
134 }
135
136
137
138 /**
139 * Specifies the port number on which to listen for client connections. The
140 * provided value must be between 1 and 65535, or it may be 0 to indicate that
141 * the JVM should select a free port on the system.
142 *
143 * @param listenPort The port number on which to listen for client
144 * connections.
145 */
146 public void setListenPort(final int listenPort)
147 {
148 Validator.ensureTrue((listenPort >= 0) && (listenPort <= 65535));
149
150 this.listenPort = listenPort;
151 }
152
153
154
155 /**
156 * Retrieves the LDAP listener request handler that should be used to process
157 * requests read from clients.
158 *
159 * @return The LDAP listener request handler that should be used to process
160 * requests read from clients.
161 */
162 public LDAPListenerRequestHandler getRequestHandler()
163 {
164 return requestHandler;
165 }
166
167
168
169 /**
170 * Specifies the LDAP listener request handler that should be used to process
171 * requests read from clients.
172 *
173 * @param requestHandler The LDAP listener request handler that should be
174 * used to process requests read from clients. It
175 * must not be {@code null}.
176 */
177 public void setRequestHandler(final LDAPListenerRequestHandler requestHandler)
178 {
179 Validator.ensureNotNull(requestHandler);
180
181 this.requestHandler = requestHandler;
182 }
183
184
185
186 /**
187 * Indicates whether to use the SO_KEEPALIVE socket option for sockets
188 * accepted by the listener.
189 *
190 * @return {@code true} if the SO_KEEPALIVE socket option should be used for
191 * sockets accepted by the listener, or {@code false} if not.
192 */
193 public boolean useKeepAlive()
194 {
195 return useKeepAlive;
196 }
197
198
199
200 /**
201 * Specifies whether to use the SO_KEEPALIVE socket option for sockets
202 * accepted by the listener.
203 *
204 * @param useKeepAlive Indicates whether to use the SO_KEEPALIVE socket
205 * option for sockets accepted by the listener.
206 */
207 public void setUseKeepAlive(final boolean useKeepAlive)
208 {
209 this.useKeepAlive = useKeepAlive;
210 }
211
212
213
214 /**
215 * Indicates whether to use the SO_LINGER socket option for sockets accepted
216 * by the listener.
217 *
218 * @return {@code true} if the SO_LINGER socket option should be used for
219 * sockets accepted by the listener, or {@code false} if not.
220 */
221 public boolean useLinger()
222 {
223 return useLinger;
224 }
225
226
227
228 /**
229 * Specifies whether to use the SO_LINGER socket option for sockets accepted
230 * by the listener.
231 *
232 * @param useLinger Indicates whether to use the SO_LINGER socket option for
233 * sockets accepted by the listener.
234 */
235 public void setUseLinger(final boolean useLinger)
236 {
237 this.useLinger = useLinger;
238 }
239
240
241
242 /**
243 * Indicates whether to use the SO_REUSEADDR socket option for sockets
244 * accepted by the listener.
245 *
246 * @return {@code true} if the SO_REUSEADDR socket option should be used for
247 * sockets accepted by the listener, or {@code false} if not.
248 */
249 public boolean useReuseAddress()
250 {
251 return useReuseAddress;
252 }
253
254
255
256 /**
257 * Specifies whether to use the SO_REUSEADDR socket option for sockets
258 * accepted by the listener.
259 *
260 * @param useReuseAddress Indicates whether to use the SO_REUSEADDR socket
261 * option for sockets accepted by the listener.
262 */
263 public void setUseReuseAddress(final boolean useReuseAddress)
264 {
265 this.useReuseAddress = useReuseAddress;
266 }
267
268
269
270 /**
271 * Indicates whether to use the TCP_NODELAY socket option for sockets accepted
272 * by the listener.
273 *
274 * @return {@code true} if the TCP_NODELAY socket option should be used for
275 * sockets accepted by the listener, or {@code false} if not.
276 */
277 public boolean useTCPNoDelay()
278 {
279 return useTCPNoDelay;
280 }
281
282
283
284 /**
285 * Specifies whether to use the TCP_NODELAY socket option for sockets accepted
286 * by the listener.
287 *
288 * @param useTCPNoDelay Indicates whether to use the TCP_NODELAY socket
289 * option for sockets accepted by the listener.
290 */
291 public void setUseTCPNoDelay(final boolean useTCPNoDelay)
292 {
293 this.useTCPNoDelay = useTCPNoDelay;
294 }
295
296
297
298 /**
299 * Retrieves the address on which to listen for client connections, if
300 * defined.
301 *
302 * @return The address on which to listen for client connections, or
303 * {@code null} if it should listen on all available addresses on all
304 * interfaces.
305 */
306 public InetAddress getListenAddress()
307 {
308 return listenAddress;
309 }
310
311
312
313 /**
314 * Specifies the address on which to listen for client connections.
315 *
316 * @param listenAddress The address on which to listen for client
317 * connections. It may be {@code null} to indicate
318 * that it should listen on all available addresses on
319 * all interfaces.
320 */
321 public void setListenAddress(final InetAddress listenAddress)
322 {
323 this.listenAddress = listenAddress;
324 }
325
326
327
328 /**
329 * Retrieves the timeout in seconds that should be used if the SO_LINGER
330 * socket option is enabled.
331 *
332 * @return The timeout in seconds that should be used if the SO_LINGER socket
333 * option is enabled.
334 */
335 public int getLingerTimeoutSeconds()
336 {
337 return lingerTimeout;
338 }
339
340
341
342 /**
343 * Specifies the timeout in seconds that should be used if the SO_LINGER
344 * socket option is enabled.
345 *
346 * @param lingerTimeout The timeout in seconds that should be used if the
347 * SO_LINGER socket option is enabled. The value must
348 * be between 0 and 65535, inclusive.
349 */
350 public void setLingerTimeoutSeconds(final int lingerTimeout)
351 {
352 Validator.ensureTrue((lingerTimeout >= 0) && (lingerTimeout <= 65535));
353
354 this.lingerTimeout = lingerTimeout;
355 }
356
357
358
359 /**
360 * Retrieves the receive buffer size that should be used for sockets accepted
361 * by the listener.
362 *
363 * @return The receive buffer size that should be used for sockets accepted
364 * by the listener, or 0 if the default receive buffer size should be
365 * used.
366 */
367 public int getReceiveBufferSize()
368 {
369 return receiveBufferSize;
370 }
371
372
373
374 /**
375 * Specifies the receive buffer size that should be used for sockets accepted
376 * by the listener. A value less than or equal to zero indicates that the
377 * default receive buffer size should be used.
378 *
379 * @param receiveBufferSize The receive buffer size that should be used for
380 * sockets accepted by the listener.
381 */
382 public void setReceiveBufferSize(final int receiveBufferSize)
383 {
384 if (receiveBufferSize > 0)
385 {
386 this.receiveBufferSize = receiveBufferSize;
387 }
388 else
389 {
390 this.receiveBufferSize = 0;
391 }
392 }
393
394
395
396 /**
397 * Retrieves the send buffer size that should be used for sockets accepted
398 * by the listener.
399 *
400 * @return The send buffer size that should be used for sockets accepted by
401 * the listener, or 0 if the default send buffer size should be used.
402 */
403 public int getSendBufferSize()
404 {
405 return sendBufferSize;
406 }
407
408
409
410 /**
411 * Specifies the send buffer size that should be used for sockets accepted by
412 * the listener. A value less than or equal to zero indicates that the
413 * default send buffer size should be used.
414 *
415 * @param sendBufferSize The send buffer size that should be used for
416 * sockets accepted by the listener.
417 */
418 public void setSendBufferSize(final int sendBufferSize)
419 {
420 if (sendBufferSize > 0)
421 {
422 this.sendBufferSize = sendBufferSize;
423 }
424 else
425 {
426 this.sendBufferSize = 0;
427 }
428 }
429
430
431
432 /**
433 * Retrieves the exception handler that should be notified of any exceptions
434 * caught while attempting to accept or interact with a client connection.
435 *
436 * @return The exception handler that should be notified of any exceptions
437 * caught while attempting to accept or interact with a client
438 * connection, or {@code null} if none is defined.
439 */
440 public LDAPListenerExceptionHandler getExceptionHandler()
441 {
442 return exceptionHandler;
443 }
444
445
446
447 /**
448 * Specifies the exception handler that should be notified of any exceptions
449 * caught while attempting to accept or interact with a client connection.
450 *
451 * @param exceptionHandler The exception handler that should be notified of
452 * any exceptions encountered during processing. It
453 * may be {@code null} if no exception handler
454 * should be used.
455 */
456 public void setExceptionHandler(
457 final LDAPListenerExceptionHandler exceptionHandler)
458 {
459 this.exceptionHandler = exceptionHandler;
460 }
461
462
463
464 /**
465 * Retrieves the factory that will be used to create the server socket that
466 * will listen for client connections.
467 *
468 * @return The factory that will be used to create the server socket that
469 * will listen for client connections.
470 */
471 public ServerSocketFactory getServerSocketFactory()
472 {
473 return serverSocketFactory;
474 }
475
476
477
478 /**
479 * Specifies the factory that will be used to create the server socket that
480 * will listen for client connections.
481 *
482 * @param serverSocketFactory The factory that will be used to create the
483 * server socket that will listen for client
484 * connections. It may be {@code null} to use
485 * the JVM-default server socket factory.
486 */
487 public void setServerSocketFactory(
488 final ServerSocketFactory serverSocketFactory)
489 {
490 if (serverSocketFactory == null)
491 {
492 this.serverSocketFactory = ServerSocketFactory.getDefault();
493 }
494 else
495 {
496 this.serverSocketFactory = serverSocketFactory;
497 }
498 }
499
500
501
502 /**
503 * Creates a copy of this configuration that may be altered without impacting
504 * this configuration, and which will not be altered by changes to this
505 * configuration.
506 *
507 * @return A copy of this configuration that may be altered without impacting
508 * this configuration, and which will not be altered by changes to
509 * this configuration.
510 */
511 public LDAPListenerConfig duplicate()
512 {
513 final LDAPListenerConfig copy =
514 new LDAPListenerConfig(listenPort, requestHandler);
515
516 copy.useKeepAlive = useKeepAlive;
517 copy.useLinger = useLinger;
518 copy.useReuseAddress = useReuseAddress;
519 copy.useTCPNoDelay = useTCPNoDelay;
520 copy.listenAddress = listenAddress;
521 copy.lingerTimeout = lingerTimeout;
522 copy.receiveBufferSize = receiveBufferSize;
523 copy.sendBufferSize = sendBufferSize;
524 copy.exceptionHandler = exceptionHandler;
525 copy.serverSocketFactory = serverSocketFactory;
526
527 return copy;
528 }
529 }