/
codebase/
codebase/area/
codebase/doc/
codebase/etc/
codebase/src/net/sourceforge/pain/data/trigger/
codebase/src/net/sourceforge/pain/logic/
codebase/src/net/sourceforge/pain/logic/affect/
codebase/src/net/sourceforge/pain/logic/event/
codebase/src/net/sourceforge/pain/logic/event/deploy/
codebase/src/net/sourceforge/pain/logic/event/guitool/
codebase/src/net/sourceforge/pain/logic/event/guitool/event/
codebase/src/net/sourceforge/pain/logic/fn/util/
codebase/src/net/sourceforge/pain/logic/trigger/
codebase/src/net/sourceforge/pain/logic/trigger/impl/
codebase/src/net/sourceforge/pain/network/console/
codebase/src/net/sourceforge/pain/network/console/telnet/
codebase/src/net/sourceforge/pain/network/guitool/
codebase/src/net/sourceforge/pain/plugin/
codebase/src/net/sourceforge/pain/plugin/command/
codebase/src/net/sourceforge/pain/plugin/reset/
codebase/src/net/sourceforge/pain/plugin/shutdown/
codebase/src/net/sourceforge/pain/plugin/social/
codebase/src/net/sourceforge/pain/util/
db/doc/javadoc/resources/
db/src/net/sourceforge/pain/util/
gui/
gui/lib/
gui/src/net/sourceforge/pain/tools/guitool/dbbrowse/
gui/src/net/sourceforge/pain/tools/guitool/dialog/
gui/src/net/sourceforge/pain/tools/guitool/menu/
gui/src/net/sourceforge/pain/tools/guitool/resources/
gui/src/net/sourceforge/pain/tools/guitool/resources/images/
gui/src/net/sourceforge/pain/tools/guitool/resources/images/explorer/
tests/
tests/src/
tests/src/net/sourceforge/pain/db/data/
package net.sourceforge.pain.network.console.telnet;


import net.sourceforge.pain.util.*;

import java.net.*;
import java.util.*;


public class TelnetConsoleServer implements Runnable {

    private ServerSocket serverSocket;
    private int port;
    private Set connections = Collections.synchronizedSet(new HashSet());
    private boolean started;

    public TelnetConsoleServer(int port) {
        Log.info("TelnetConsoleServer created");
        this.port = port;
        Thread worker = new Thread(this);
        worker.setDaemon(true);
        worker.start();
    }

    public void run() {
        started = true;
        work();
    }

    public void work() {
        ConnectionChecker checker = new ConnectionChecker();
        Thread checkThread = new Thread(checker);
        checkThread.setDaemon(true);
        checkThread.start();
        try {
            Log.info("TelnetConsoleServer:creating server socket on port:" + port);
            serverSocket = new ServerSocket(port, 50);
            serverSocket.setSoTimeout(0);
            Log.info("Server Initialised. listening...");
            do {
                try {
                    Socket socket = serverSocket.accept();

                    Log.debug("TelnetConsoleServer:connection accepted[" + connections.size() + "]:" + socket.getInetAddress());
                    TelnetConsoleAdapter con = new TelnetConsoleAdapter(this, socket);
                    connections.add(con);
                    Thread worker = new Thread(con);
                    worker.start();
                } catch (Exception e) {
                    e.printStackTrace();
                }
            } while (started);
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            checker.interrupted = true;
            checkThread.interrupt();
        }
    }

    protected void onClose(TelnetConsoleAdapter con) {
        Log.debug("TelnetConsoleServer:closing connection:[" + connections.size() + "]" + con.socket.getInetAddress());
        connections.remove(con);
    }

    public void stop() {
        started = false;
    }

    private class ConnectionChecker implements Runnable {

        public static final int CHECK_TIMEOUT = 5000;
        boolean interrupted = false;

        public void run() {
            while (!interrupted) {
                try {
                    Collection c = new ArrayList(connections);
                    long checkBarrier = System.currentTimeMillis() - CHECK_TIMEOUT;
                    for (Iterator it = c.iterator(); it.hasNext();) {
                        TelnetConsoleAdapter con = (TelnetConsoleAdapter) it.next();
                        if (con.lastFlushTime < checkBarrier) {
                            Log.debug("TelnetConsoleServer:AYT to " + con.socket.getRemoteSocketAddress());
                            con.ping();
                        }
                    }
                    Thread.sleep(CHECK_TIMEOUT);
                } catch (InterruptedException e) {
                    interrupted = true;
                } catch (Exception e) {
                    Log.error(e.getMessage(), e);
                }
            }
        }
    }

}