This is an automated email from the ASF dual-hosted git repository.

rgoers pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/logging-log4j-server.git

commit e0ad276429f07f8fe1565f8ace91ef214aab526a
Author: ggregory <[email protected]>
AuthorDate: Fri Aug 4 08:00:29 2017 -0700

    Better Javadoc and minor clean up.
---
 .../logging/log4j/server/TcpSocketServer.java      | 789 ++++++++++-----------
 1 file changed, 393 insertions(+), 396 deletions(-)

diff --git 
a/log4j-server/src/main/java/org/apache/logging/log4j/server/TcpSocketServer.java
 
b/log4j-server/src/main/java/org/apache/logging/log4j/server/TcpSocketServer.java
index ae1c592..51c071c 100644
--- 
a/log4j-server/src/main/java/org/apache/logging/log4j/server/TcpSocketServer.java
+++ 
b/log4j-server/src/main/java/org/apache/logging/log4j/server/TcpSocketServer.java
@@ -1,396 +1,393 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache license, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the license for the specific language governing permissions and
- * limitations under the license.
- */
-package org.apache.logging.log4j.server;
-
-import java.io.EOFException;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.ObjectInputStream;
-import java.io.OptionalDataException;
-import java.net.InetAddress;
-import java.net.ServerSocket;
-import java.net.Socket;
-import java.util.Collections;
-import java.util.List;
-import java.util.Map;
-import java.util.concurrent.ConcurrentHashMap;
-import java.util.concurrent.ConcurrentMap;
-
-import com.beust.jcommander.Parameter;
-import com.beust.jcommander.validators.PositiveInteger;
-import org.apache.logging.log4j.core.config.ConfigurationFactory;
-import org.apache.logging.log4j.core.parser.ParseException;
-import org.apache.logging.log4j.core.util.BasicCommandLineArguments;
-import org.apache.logging.log4j.core.util.Closer;
-import org.apache.logging.log4j.core.util.Log4jThread;
-import org.apache.logging.log4j.message.EntryMessage;
-
-/**
- * Listens for Log4j events on a TCP server socket and passes them on to Log4j.
- * 
- * @param <T>
- *        The kind of input stream read
- * @see #main(String[])
- */
-public class TcpSocketServer<T extends InputStream> extends 
AbstractSocketServer<T> {
-
-    protected static class CommandLineArguments extends 
AbstractSocketServer.CommandLineArguments {
-        
-        @Parameter(names = { "--backlog",
-                "-b" }, validateWith = PositiveInteger.class, description = 
"Server socket backlog.")
-        // Same default as ServerSocket
-        private int backlog = 50;
-
-        int getBacklog() {
-            return backlog;
-        }
-
-        void setBacklog(final int backlog) {
-            this.backlog = backlog;
-        }        
-
-    }
-
-    /**
-     * Thread that processes the events.
-     */
-    private class SocketHandler extends Log4jThread {
-
-        private final T inputStream;
-        private final Socket socket;
-
-        private volatile boolean shutdown = false;
-
-        public SocketHandler(final Socket socket) throws IOException {
-            this.socket = socket;
-            this.inputStream = 
logEventInput.wrapStream(socket.getInputStream());
-        }
-
-        @Override
-        public void run() {
-            final EntryMessage entry = logger.traceEntry();
-            boolean closed = false;
-            try {
-                try {
-                    while (!shutdown) {
-                        logEventInput.logEvents(inputStream, 
TcpSocketServer.this);
-                    }
-                } catch (final EOFException e) {
-                    closed = true;
-                } catch (final OptionalDataException e) {
-                    logger.error("OptionalDataException eof=" + e.eof + " 
length=" + e.length, e);
-                } catch (final IOException e) {
-                    logger.error("IOException encountered while reading from 
socket", e);
-                } catch (ParseException e) {
-                    logger.error("ParseException encountered while reading 
from socket", e);
-                }
-                if (!closed) {
-                    Closer.closeSilently(inputStream);
-                }
-            } finally {
-                handlers.remove(Long.valueOf(getId()));
-            }
-            logger.traceExit(entry);
-        }
-
-        public void shutdown() {
-            this.shutdown = true;
-            if (socket != null) {
-                Closer.closeSilently(socket);
-            }
-            interrupt();
-        }
-    }
-
-    /**
-     * Creates a socket server that reads JSON log events.
-     * 
-     * @param port
-     *        The server socket port.
-     * @return a new a socket server
-     * @throws IOException
-     *         if an I/O error occurs when opening the socket.
-     */
-    public static TcpSocketServer<InputStream> createJsonSocketServer(final 
int port) throws IOException {
-        LOGGER.entry("createJsonSocketServer", port);
-        final TcpSocketServer<InputStream> socketServer = new 
TcpSocketServer<>(port, new JsonInputStreamLogEventBridge());
-        return LOGGER.exit(socketServer);
-    }
-
-    /**
-     * Creates a socket server that reads JSON log events.
-     *
-     * @param port
-     *        The server socket port.
-     * @param backlog
-     *        The server socket backlog.
-     * @param localBindAddress
-     *        The local InetAddress the server will bind to
-     * @return a new a socket server
-     * @throws IOException
-     *         if an I/O error occurs when opening the socket.
-     * @since 2.9
-     */
-    public static TcpSocketServer<InputStream> createJsonSocketServer(final 
int port, final int backlog,
-            final InetAddress localBindAddress) throws IOException {
-        LOGGER.entry("createJsonSocketServer", port, backlog, 
localBindAddress);
-        final TcpSocketServer<InputStream> socketServer = new 
TcpSocketServer<>(port, backlog, localBindAddress,
-                new JsonInputStreamLogEventBridge());
-        return LOGGER.exit(socketServer);
-    }
-
-    /**
-     * Creates a socket server that reads serialized log events.
-     * 
-     * @param port
-     *        The server socket port.
-     * @return a new a socket server
-     * @throws IOException
-     *         if an I/O error occurs when opening the socket.
-     */
-    public static TcpSocketServer<ObjectInputStream> 
createSerializedSocketServer(final int port) throws IOException {
-        LOGGER.entry(port);
-        final TcpSocketServer<ObjectInputStream> socketServer = new 
TcpSocketServer<>(port, new ObjectInputStreamLogEventBridge());
-        return LOGGER.exit(socketServer);
-    }
-
-    /**
-     * Creates a socket server that reads serialized log events.
-     * 
-     * @param port
-     *        The server socket port.
-     * @param backlog
-     *        The server socket backlog.
-     * @param localBindAddress
-     *        The local InetAddress the server will bind to
-     * @return a new a socket server
-     * @throws IOException
-     *         if an I/O error occurs when opening the socket.
-     * @since 2.7
-     */
-    public static TcpSocketServer<ObjectInputStream> 
createSerializedSocketServer(final int port, final int backlog,
-            final InetAddress localBindAddress) throws IOException {
-        return createSerializedSocketServer(port, backlog, localBindAddress, 
Collections.<String>emptyList());
-    }
-
-    /**
-     * Creates a socket server that reads serialized log events.
-     *
-     * @param port
-     *        The server socket port.
-     * @param backlog
-     *        The server socket backlog.
-     * @param localBindAddress
-     *        The local InetAddress the server will bind to
-     * @param allowedClasses additional class names to allow for 
deserialization
-     * @return a new a socket server
-     * @throws IOException
-     *         if an I/O error occurs when opening the socket.
-     * @since 2.8.2
-     */
-    public static TcpSocketServer<ObjectInputStream> 
createSerializedSocketServer(
-        final int port, final int backlog, final InetAddress localBindAddress, 
final List<String> allowedClasses
-    ) throws IOException {
-        LOGGER.entry(port);
-        final TcpSocketServer<ObjectInputStream> socketServer = new 
TcpSocketServer<>(port, backlog, localBindAddress,
-                new ObjectInputStreamLogEventBridge(allowedClasses));
-        return LOGGER.exit(socketServer);
-    }
-
-    /**
-     * Creates a socket server that reads XML log events.
-     * 
-     * @param port
-     *        The server socket port.
-     * @return a new a socket server
-     * @throws IOException
-     *         if an I/O error occurs when opening the socket.
-     */
-    public static TcpSocketServer<InputStream> createXmlSocketServer(final int 
port) throws IOException {
-        LOGGER.entry(port);
-        final TcpSocketServer<InputStream> socketServer = new 
TcpSocketServer<>(port, new XmlInputStreamLogEventBridge());
-        return LOGGER.exit(socketServer);
-    }
-
-    /**
-     * Creates a socket server that reads XML log events.
-     *
-     * @param port
-     *        The server socket port.
-     * @param backlog
-     *        The server socket backlog.
-     * @param localBindAddress
-     *        The local InetAddress the server will bind to
-     * @return a new a socket server
-     * @throws IOException
-     *         if an I/O error occurs when opening the socket.
-     * @since 2.9
-     */
-    public static TcpSocketServer<InputStream> createXmlSocketServer(final int 
port,
-        final int backlog, final InetAddress localBindAddress
-    ) throws IOException {
-        LOGGER.entry(port);
-        final TcpSocketServer<InputStream> socketServer = new 
TcpSocketServer<>(port, backlog, localBindAddress,
-                new XmlInputStreamLogEventBridge());
-        return LOGGER.exit(socketServer);
-    }
-
-    /**
-     * Main startup for the server. Run with "--help" for to print command 
line help on the console.
-     * 
-     * @param args
-     *        The command line arguments.
-     * @throws Exception
-     *         if an error occurs.
-     */
-    public static void main(final String[] args) throws Exception {
-        final CommandLineArguments cla = 
BasicCommandLineArguments.parseCommandLine(args, TcpSocketServer.class, new 
CommandLineArguments());
-        if (cla.isHelp()) {
-            return;
-        }
-        if (cla.getConfigLocation() != null) {
-            ConfigurationFactory.setConfigurationFactory(new 
ServerConfigurationFactory(cla.getConfigLocation()));
-        }
-        final TcpSocketServer<InputStream> socketServer = 
TcpSocketServer.createJsonSocketServer(
-            cla.getPort(), cla.getBacklog(), cla.getLocalBindAddress());
-        final Thread serverThread = socketServer.startNewThread();
-        if (cla.isInteractive()) {
-            socketServer.awaitTermination(serverThread);
-        }
-    }
-
-    private final ConcurrentMap<Long, SocketHandler> handlers = new 
ConcurrentHashMap<>();
-
-    private final ServerSocket serverSocket;
-
-    /**
-     * Constructor.
-     * 
-     * @param port
-     *        The server socket port.
-     * @param backlog
-     *        The server socket backlog.
-     * @param localBindAddress
-     *        The local InetAddress the server will bind to
-     * @param logEventInput
-     *        the log even input
-     * @throws IOException
-     *         if an I/O error occurs when opening the socket.
-     * @since 2.7
-     */
-    @SuppressWarnings("resource")
-    public TcpSocketServer(final int port, final int backlog, final 
InetAddress localBindAddress, final LogEventBridge<T> logEventInput) throws 
IOException {
-        this(port, logEventInput, new ServerSocket(port, backlog, 
localBindAddress));
-    }
-
-    /**
-     * Constructor.
-     * 
-     * @param port
-     *        The server socket port
-     * @param logEventInput
-     *        the log even input
-     * @throws IOException
-     *         if an I/O error occurs when opening the socket.
-     */
-    public TcpSocketServer(final int port, final LogEventBridge<T> 
logEventInput) throws IOException {
-        this(port, logEventInput, extracted(port));
-    }
-
-    private static ServerSocket extracted(final int port) throws IOException {
-        return new ServerSocket(port);
-    }
-
-    /**
-     * Constructor.
-     * 
-     * @param port
-     *        to listen.
-     * @param logEventInput
-     *        the log even input
-     * @param serverSocket
-     *        the socket server
-     * @throws IOException
-     *         if an I/O error occurs when opening the socket.
-     */
-    public TcpSocketServer(final int port, final LogEventBridge<T> 
logEventInput, final ServerSocket serverSocket)
-            throws IOException {
-        super(port, logEventInput);
-        this.serverSocket = serverSocket;
-    }
-
-    /**
-     * Accept incoming events and processes them.
-     */
-    @Override
-    public void run() {
-        final EntryMessage entry = logger.traceEntry();
-        while (isActive()) {
-            if (serverSocket.isClosed()) {
-                return;
-            }
-            try {
-                // Accept incoming connections.
-                logger.debug("Listening for a connection {}...", serverSocket);
-                @SuppressWarnings("resource") // clientSocket is closed during 
SocketHandler shutdown
-                final Socket clientSocket = serverSocket.accept();
-                logger.debug("Acepted connection on {}...", serverSocket);
-                logger.debug("Socket accepted: {}", clientSocket);
-                clientSocket.setSoLinger(true, 0);
-
-                // accept() will block until a client connects to the server.
-                // If execution reaches this point, then it means that a client
-                // socket has been accepted.
-
-                final SocketHandler handler = new SocketHandler(clientSocket);
-                handlers.put(Long.valueOf(handler.getId()), handler);
-                handler.start();
-            } catch (final IOException e) {
-                if (serverSocket.isClosed()) {
-                    // OK we're done.
-                    logger.traceExit(entry);
-                    return;
-                }
-                logger.error("Exception encountered on accept. Ignoring. Stack 
trace :", e);
-            }
-        }
-        for (final Map.Entry<Long, SocketHandler> handlerEntry : 
handlers.entrySet()) {
-            final SocketHandler handler = handlerEntry.getValue();
-            handler.shutdown();
-            try {
-                handler.join();
-            } catch (final InterruptedException ignored) {
-                // Ignore the exception
-            }
-        }
-        logger.traceExit(entry);
-    }
-
-    /**
-     * Shutdown the server.
-     * 
-     * @throws IOException if the server socket could not be closed
-     */
-    @Override
-    public void shutdown() throws IOException {
-        final EntryMessage entry = logger.traceEntry();
-        setActive(false);
-        //Thread.currentThread().interrupt();
-        serverSocket.close();
-        logger.traceExit(entry);
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache license, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the license for the specific language governing permissions and
+ * limitations under the license.
+ */
+package org.apache.logging.log4j.server;
+
+import java.io.EOFException;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.ObjectInputStream;
+import java.io.OptionalDataException;
+import java.net.InetAddress;
+import java.net.ServerSocket;
+import java.net.Socket;
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentMap;
+
+import com.beust.jcommander.Parameter;
+import com.beust.jcommander.validators.PositiveInteger;
+import org.apache.logging.log4j.core.config.ConfigurationFactory;
+import org.apache.logging.log4j.core.parser.ParseException;
+import org.apache.logging.log4j.core.util.BasicCommandLineArguments;
+import org.apache.logging.log4j.core.util.Closer;
+import org.apache.logging.log4j.core.util.Log4jThread;
+import org.apache.logging.log4j.message.EntryMessage;
+
+/**
+ * Listens for Log4j events on a TCP server socket and passes them on to Log4j.
+ * 
+ * @param <T>
+ *        The kind of input stream read
+ * @see #main(String[])
+ */
+public class TcpSocketServer<T extends InputStream> extends 
AbstractSocketServer<T> {
+
+    protected static class CommandLineArguments extends 
AbstractSocketServer.CommandLineArguments {
+        
+        @Parameter(names = { "--backlog",
+                "-b" }, validateWith = PositiveInteger.class, description = 
"Server socket backlog.")
+        // Same default as ServerSocket
+        private int backlog = 50;
+
+        int getBacklog() {
+            return backlog;
+        }
+
+        void setBacklog(final int backlog) {
+            this.backlog = backlog;
+        }        
+
+    }
+
+    /**
+     * Thread that processes the events.
+     */
+    private class SocketHandler extends Log4jThread {
+
+        private final T inputStream;
+        private final Socket socket;
+
+        private volatile boolean shutdown = false;
+
+        public SocketHandler(final Socket socket) throws IOException {
+            this.socket = socket;
+            this.inputStream = 
logEventInput.wrapStream(socket.getInputStream());
+        }
+
+        @Override
+        public void run() {
+            final EntryMessage entry = logger.traceEntry();
+            boolean closed = false;
+            try {
+                try {
+                    while (!shutdown) {
+                        logEventInput.logEvents(inputStream, 
TcpSocketServer.this);
+                    }
+                } catch (final EOFException e) {
+                    closed = true;
+                } catch (final OptionalDataException e) {
+                    logger.error("OptionalDataException eof=" + e.eof + " 
length=" + e.length, e);
+                } catch (final IOException e) {
+                    logger.error("IOException encountered while reading from 
socket", e);
+                } catch (ParseException e) {
+                    logger.error("ParseException encountered while reading 
from socket", e);
+                }
+                if (!closed) {
+                    Closer.closeSilently(inputStream);
+                }
+            } finally {
+                handlers.remove(Long.valueOf(getId()));
+            }
+            logger.traceExit(entry);
+        }
+
+        public void shutdown() {
+            this.shutdown = true;
+            if (socket != null) {
+                Closer.closeSilently(socket);
+            }
+            interrupt();
+        }
+    }
+
+    /**
+     * Creates a socket server that reads JSON log events.
+     * 
+     * @param port
+     *        The port number, or 0 to automatically allocate a port number.
+     * @return a new a socket server
+     * @throws IOException
+     *         if an I/O error occurs when opening the socket.
+     */
+    public static TcpSocketServer<InputStream> createJsonSocketServer(final 
int port) throws IOException {
+        LOGGER.entry("createJsonSocketServer", port);
+        final TcpSocketServer<InputStream> socketServer = new 
TcpSocketServer<>(port, new JsonInputStreamLogEventBridge());
+        return LOGGER.exit(socketServer);
+    }
+
+    /**
+     * Creates a socket server that reads JSON log events.
+     *
+     * @param port
+     *        The port number, or 0 to automatically allocate a port number.
+     * @param backlog
+     *        The server socket backlog.
+     * @param localBindAddress
+     *        The local InetAddress the server will bind to
+     * @return a new a socket server
+     * @throws IOException
+     *         if an I/O error occurs when opening the socket.
+     * @since 2.9
+     */
+    public static TcpSocketServer<InputStream> createJsonSocketServer(final 
int port, final int backlog,
+            final InetAddress localBindAddress) throws IOException {
+        LOGGER.entry("createJsonSocketServer", port, backlog, 
localBindAddress);
+        final TcpSocketServer<InputStream> socketServer = new 
TcpSocketServer<>(port, backlog, localBindAddress,
+                new JsonInputStreamLogEventBridge());
+        return LOGGER.exit(socketServer);
+    }
+
+    /**
+     * Creates a socket server that reads serialized log events.
+     * 
+     * @param port
+     *        The port number, or 0 to automatically allocate a port number.
+     * @return a new a socket server
+     * @throws IOException
+     *         if an I/O error occurs when opening the socket.
+     */
+    public static TcpSocketServer<ObjectInputStream> 
createSerializedSocketServer(final int port) throws IOException {
+        LOGGER.entry(port);
+        final TcpSocketServer<ObjectInputStream> socketServer = new 
TcpSocketServer<>(port, new ObjectInputStreamLogEventBridge());
+        return LOGGER.exit(socketServer);
+    }
+
+    /**
+     * Creates a socket server that reads serialized log events.
+     * 
+     * @param port
+     *        The port number, or 0 to automatically allocate a port number.
+     * @param backlog
+     *        The server socket backlog.
+     * @param localBindAddress
+     *        The local InetAddress the server will bind to
+     * @return a new a socket server
+     * @throws IOException
+     *         if an I/O error occurs when opening the socket.
+     * @since 2.7
+     */
+    public static TcpSocketServer<ObjectInputStream> 
createSerializedSocketServer(final int port, final int backlog,
+            final InetAddress localBindAddress) throws IOException {
+        return createSerializedSocketServer(port, backlog, localBindAddress, 
Collections.<String>emptyList());
+    }
+
+    /**
+     * Creates a socket server that reads serialized log events.
+     *
+     * @param port
+     *        The port number, or 0 to automatically allocate a port number.
+     * @param backlog
+     *        The server socket backlog.
+     * @param localBindAddress
+     *        The local InetAddress the server will bind to
+     * @param allowedClasses additional class names to allow for 
deserialization
+     * @return a new a socket server
+     * @throws IOException
+     *         if an I/O error occurs when opening the socket.
+     * @since 2.8.2
+     */
+    public static TcpSocketServer<ObjectInputStream> 
createSerializedSocketServer(
+        final int port, final int backlog, final InetAddress localBindAddress, 
final List<String> allowedClasses
+    ) throws IOException {
+        LOGGER.entry(port);
+        final TcpSocketServer<ObjectInputStream> socketServer = new 
TcpSocketServer<>(port, backlog, localBindAddress,
+                new ObjectInputStreamLogEventBridge(allowedClasses));
+        return LOGGER.exit(socketServer);
+    }
+
+    /**
+     * Creates a socket server that reads XML log events.
+     * 
+     * @param port
+     *        The port number, or 0 to automatically allocate a port number.
+     * @return a new a socket server
+     * @throws IOException
+     *         if an I/O error occurs when opening the socket.
+     */
+    public static TcpSocketServer<InputStream> createXmlSocketServer(final int 
port) throws IOException {
+        LOGGER.entry(port);
+        final TcpSocketServer<InputStream> socketServer = new 
TcpSocketServer<>(port, new XmlInputStreamLogEventBridge());
+        return LOGGER.exit(socketServer);
+    }
+
+    /**
+     * Creates a socket server that reads XML log events.
+     *
+     * @param port
+     *        The port number, or 0 to automatically allocate a port number.
+     * @param backlog
+     *        The server socket backlog.
+     * @param localBindAddress
+     *        The local InetAddress the server will bind to
+     * @return a new a socket server
+     * @throws IOException
+     *         if an I/O error occurs when opening the socket.
+     * @since 2.9
+     */
+    public static TcpSocketServer<InputStream> createXmlSocketServer(final int 
port,
+        final int backlog, final InetAddress localBindAddress
+    ) throws IOException {
+        LOGGER.entry(port);
+        final TcpSocketServer<InputStream> socketServer = new 
TcpSocketServer<>(port, backlog, localBindAddress,
+                new XmlInputStreamLogEventBridge());
+        return LOGGER.exit(socketServer);
+    }
+
+    /**
+     * Main startup for the server. Run with "--help" for to print command 
line help on the console.
+     * 
+     * @param args
+     *        The command line arguments.
+     * @throws Exception
+     *         if an error occurs.
+     */
+    public static void main(final String[] args) throws Exception {
+        final CommandLineArguments cla = 
BasicCommandLineArguments.parseCommandLine(args, TcpSocketServer.class, new 
CommandLineArguments());
+        if (cla.isHelp()) {
+            return;
+        }
+        if (cla.getConfigLocation() != null) {
+            ConfigurationFactory.setConfigurationFactory(new 
ServerConfigurationFactory(cla.getConfigLocation()));
+        }
+        final TcpSocketServer<InputStream> socketServer = 
TcpSocketServer.createJsonSocketServer(
+            cla.getPort(), cla.getBacklog(), cla.getLocalBindAddress());
+        final Thread serverThread = socketServer.startNewThread();
+        if (cla.isInteractive()) {
+            socketServer.awaitTermination(serverThread);
+        }
+    }
+
+    private final ConcurrentMap<Long, SocketHandler> handlers = new 
ConcurrentHashMap<>();
+
+    private final ServerSocket serverSocket;
+
+    /**
+     * Constructor.
+     * 
+     * @param port
+     *        The port number, or 0 to automatically allocate a port number.
+     * @param backlog
+     *        The server socket backlog.
+     * @param localBindAddress
+     *        The local InetAddress the server will bind to
+     * @param logEventInput
+     *        the log even input
+     * @throws IOException
+     *         if an I/O error occurs when opening the socket.
+     * @since 2.7
+     */
+    @SuppressWarnings("resource")
+    public TcpSocketServer(final int port, final int backlog, final 
InetAddress localBindAddress, final LogEventBridge<T> logEventInput) throws 
IOException {
+        this(port, logEventInput, new ServerSocket(port, backlog, 
localBindAddress));
+    }
+
+    /**
+     * Constructor.
+     * 
+     * @param port
+     *         The port number, or 0 to automatically allocate a port number. 
+     * @param logEventInput
+     *        the log even input
+     * @throws IOException
+     *         if an I/O error occurs when opening the socket.
+     */
+    @SuppressWarnings("resource")
+    public TcpSocketServer(final int port, final LogEventBridge<T> 
logEventInput) throws IOException {
+        this(port, logEventInput, new ServerSocket(port));
+    }
+
+    /**
+     * Constructor.
+     * 
+     * @param port
+     *        to listen.
+     * @param logEventInput
+     *        the log even input
+     * @param serverSocket
+     *        the socket server
+     * @throws IOException
+     *         if an I/O error occurs when opening the socket.
+     */
+    public TcpSocketServer(final int port, final LogEventBridge<T> 
logEventInput, final ServerSocket serverSocket)
+            throws IOException {
+        super(port, logEventInput);
+        this.serverSocket = serverSocket;
+    }
+
+    /**
+     * Accept incoming events and processes them.
+     */
+    @Override
+    public void run() {
+        final EntryMessage entry = logger.traceEntry();
+        while (isActive()) {
+            if (serverSocket.isClosed()) {
+                return;
+            }
+            try {
+                // Accept incoming connections.
+                logger.debug("Listening for a connection {}...", serverSocket);
+                @SuppressWarnings("resource") // clientSocket is closed during 
SocketHandler shutdown
+                final Socket clientSocket = serverSocket.accept();
+                logger.debug("Acepted connection on {}...", serverSocket);
+                logger.debug("Socket accepted: {}", clientSocket);
+                clientSocket.setSoLinger(true, 0);
+
+                // accept() will block until a client connects to the server.
+                // If execution reaches this point, then it means that a client
+                // socket has been accepted.
+
+                final SocketHandler handler = new SocketHandler(clientSocket);
+                handlers.put(Long.valueOf(handler.getId()), handler);
+                handler.start();
+            } catch (final IOException e) {
+                if (serverSocket.isClosed()) {
+                    // OK we're done.
+                    logger.traceExit(entry);
+                    return;
+                }
+                logger.error("Exception encountered on accept. Ignoring. Stack 
trace :", e);
+            }
+        }
+        for (final Map.Entry<Long, SocketHandler> handlerEntry : 
handlers.entrySet()) {
+            final SocketHandler handler = handlerEntry.getValue();
+            handler.shutdown();
+            try {
+                handler.join();
+            } catch (final InterruptedException ignored) {
+                // Ignore the exception
+            }
+        }
+        logger.traceExit(entry);
+    }
+
+    /**
+     * Shutdown the server.
+     * 
+     * @throws IOException if the server socket could not be closed
+     */
+    @Override
+    public void shutdown() throws IOException {
+        final EntryMessage entry = logger.traceEntry();
+        setActive(false);
+        //Thread.currentThread().interrupt();
+        serverSocket.close();
+        logger.traceExit(entry);
+    }
+}

Reply via email to