001    /**
002     * Licensed to the Apache Software Foundation (ASF) under one or more
003     * contributor license agreements.  See the NOTICE file distributed with
004     * this work for additional information regarding copyright ownership.
005     * The ASF licenses this file to You under the Apache License, Version 2.0
006     * (the "License"); you may not use this file except in compliance with
007     * the License.  You may obtain a copy of the License at
008     *
009     *      http://www.apache.org/licenses/LICENSE-2.0
010     *
011     * Unless required by applicable law or agreed to in writing, software
012     * distributed under the License is distributed on an "AS IS" BASIS,
013     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014     * See the License for the specific language governing permissions and
015     * limitations under the License.
016     */
017    package org.apache.xbean.terminal.telnet;
018    
019    import java.io.IOException;
020    import java.net.ServerSocket;
021    import java.net.Socket;
022    
023    public class TelnetDaemon implements Runnable {
024    
025        private final TelnetShell shell;
026        private final int port;
027    
028        private ServerSocket serverSocket;
029    
030        /**
031         * We start out in a "stopped" state until someone calls the start method.
032         */
033        private boolean stop = true;
034    
035        public TelnetDaemon(String serverName, int port) {
036            this.port = port;
037            this.shell = new TelnetShell(serverName);
038        }
039    
040        public void start() throws Exception {
041            synchronized (this) {
042                // Don't bother if we are already started/starting
043                if (!stop)
044                    return;
045    
046                stop = false;
047    
048                // Do our stuff
049                try {
050                    serverSocket = new ServerSocket(port, 20);
051                    Thread d = new Thread(this);
052                    d.setName("service.shell@" + d.hashCode());
053                    d.setDaemon(true);
054                    d.start();
055                } catch (Exception e) {
056                    throw new Exception("Service failed to start.", e);
057                }
058            }
059        }
060    
061        public void stop() throws Exception {
062            synchronized (this) {
063                if (stop) {
064                    return;
065                }
066                stop = true;
067                try {
068                    this.notifyAll();
069                } catch (Throwable t) {
070                    t.printStackTrace();
071                }
072            }
073        }
074    
075        public synchronized void service(final Socket socket) throws IOException {
076            Thread d = new Thread(new Runnable() {
077                public void run() {
078                    try {
079                        shell.service(socket);
080                    } catch (SecurityException e) {
081                    } catch (Throwable e) {
082                    } finally {
083                        try {
084                            if (socket != null)
085                                socket.close();
086                        } catch (Throwable t) {
087                        }
088                    }
089                }
090            });
091            d.setDaemon(true);
092            d.start();
093        }
094    
095        public void run() {
096    
097            Socket socket = null;
098    
099            while (!stop) {
100                try {
101                    socket = serverSocket.accept();
102                    socket.setTcpNoDelay(true);
103                    if (!stop) service(socket);
104                } catch (SecurityException e) {
105                } catch (Throwable e) {
106                }
107            }
108        }
109    
110    }