Coverage Report - org.paneris.bibliomania.CommandServer
 
Classes in this File Line Coverage Branch Coverage Complexity
CommandServer
0%
0/18
0%
0/6
2.636
CommandServer$1
N/A
N/A
2.636
CommandServer$CarConWriter
0%
0/34
0%
0/10
2.636
CommandServer$DelegatingInterpreter
0%
0/4
N/A
2.636
CommandServer$Interpreter
N/A
N/A
2.636
CommandServer$Loop
0%
0/43
0%
0/3
2.636
 
 1  
 package org.paneris.bibliomania;
 2  
 
 3  
 import java.io.BufferedReader;
 4  
 import java.io.CharArrayWriter;
 5  
 import java.io.FilterWriter;
 6  
 import java.io.IOException;
 7  
 import java.io.InputStreamReader;
 8  
 import java.io.OutputStreamWriter;
 9  
 import java.io.StreamTokenizer;
 10  
 import java.io.Writer;
 11  
 import java.net.InetAddress;
 12  
 import java.net.ServerSocket;
 13  
 import java.net.Socket;
 14  
 import java.util.Hashtable;
 15  
 import java.util.Vector;
 16  
 
 17  
 import org.melati.poem.util.ArrayUtils;
 18  
 
 19  0
 public class CommandServer extends Thread {
 20  
 
 21  
   private ServerSocket serverSocket;
 22  
   private Hashtable interpreters;
 23  
   private int maxInterpreterThreads;
 24  
 
 25  0
   public CommandServer(int port, int maxInterpreterThreads) throws IOException {
 26  0
     this.maxInterpreterThreads = maxInterpreterThreads;
 27  0
     interpreters = new Hashtable();
 28  0
     serverSocket = new ServerSocket(port);
 29  0
   }
 30  
 
 31  
   public void run() {
 32  
     for (;;) {
 33  
       try {
 34  0
         while (interpreters.size() >= maxInterpreterThreads)
 35  0
           synchronized (interpreters) {
 36  0
             interpreters.wait();
 37  0
           }
 38  
 
 39  0
         Socket socket = serverSocket.accept();
 40  0
         if (socket.getInetAddress().equals(InetAddress.getLocalHost()) ||
 41  
             socket.getInetAddress().getHostAddress().equals("127.0.0.1"))
 42  0
           new Loop(DelegatingInterpreter.it, socket).start();
 43  
         else {
 44  0
           socket.getOutputStream().write(
 45  
               ("You are " + socket.getInetAddress() + " not " +
 46  
                InetAddress.getLocalHost() + "\n").getBytes());
 47  0
           socket.close();
 48  
         }
 49  
       }
 50  0
       catch (Exception e) {
 51  0
         System.err.println("CommandServer: " + e);
 52  0
       }
 53  
     }
 54  
   }
 55  
 
 56  
   public static interface Interpreter {
 57  
     void interpret(String[] args, Writer output, Writer errors)
 58  
         throws Exception;
 59  
   }
 60  
 
 61  0
   public static class DelegatingInterpreter implements Interpreter {
 62  0
     public static final DelegatingInterpreter it = new DelegatingInterpreter();
 63  
 
 64  
     public void interpret(String[] args, Writer output, Writer errors)
 65  
         throws Exception {
 66  0
       ((Interpreter)Class.forName(args[0]).newInstance()).
 67  
           interpret((String[])ArrayUtils.section(args, 1, args.length),
 68  
                     output, errors);
 69  0
     }
 70  
   }
 71  
 
 72  
   public static class CarConWriter extends FilterWriter {
 73  
 
 74  
     private String prefix;
 75  
 
 76  0
     private CharArrayWriter buffer = new CharArrayWriter();
 77  
 
 78  
     public CarConWriter(Writer w, String prefix) {
 79  0
       super(w);
 80  0
       this.prefix = prefix;
 81  0
     }
 82  
 
 83  
     private void shift() throws IOException {
 84  0
       synchronized (out) {
 85  0
         out.write(prefix);
 86  0
         buffer.writeTo(out);
 87  0
       }
 88  
 
 89  0
       out.flush();
 90  0
       buffer.reset();
 91  0
     }
 92  
 
 93  
     public void write(int c) throws IOException {
 94  0
       buffer.write(c);
 95  0
       if (c == '\n')
 96  0
         shift();
 97  0
     }
 98  
 
 99  
     public void write(char cbuf[], int off, int len)
 100  
         throws IOException {
 101  0
       int end = off + len;
 102  
 
 103  0
       for (int i = off; i < end; ++i) {
 104  0
         if (cbuf[i] == '\n') {
 105  0
           buffer.write(cbuf, off, i + 1 - off);
 106  0
           shift();
 107  0
           off = i + 1;
 108  
         }
 109  
       }
 110  
 
 111  0
       if (off < end)
 112  0
         buffer.write(cbuf, off, end - off);
 113  0
     }
 114  
 
 115  
     public synchronized void write(String str, int off, int len)
 116  
         throws IOException {
 117  0
       int end = off + len;
 118  
 
 119  
       for (;;) {
 120  0
         int i = str.indexOf('\n', off);
 121  0
         if (i == -1) {
 122  0
           buffer.write(str, off, end - off);
 123  0
           break;
 124  
         }
 125  
         else {
 126  0
           buffer.write(str, off, i + 1 - off);
 127  0
           shift();
 128  0
           off = i + 1;
 129  
         }
 130  0
       }
 131  0
     }
 132  
   }
 133  
 
 134  0
   public class Loop extends Thread {
 135  
 
 136  
     private Interpreter interpreter;
 137  
     private Socket socket;
 138  
     private StreamTokenizer in;
 139  
     private Writer out;
 140  
     private Writer outputs;
 141  
     private Writer errors;
 142  
 
 143  0
     private Loop(Interpreter interpreter, Socket socket) throws IOException {
 144  0
       this.interpreter = interpreter;
 145  0
       this.socket = socket;
 146  0
       in = new StreamTokenizer(new BufferedReader(
 147  
                                new InputStreamReader(socket.getInputStream())));
 148  0
       in.ordinaryChars(33, 127);
 149  0
       in.wordChars(33, 127);
 150  0
       in.quoteChar('"');
 151  0
       in.quoteChar('\'');
 152  0
       in.slashSlashComments(false);
 153  0
       in.slashStarComments(false);
 154  0
       in.eolIsSignificant(true);
 155  
       
 156  0
       out = new OutputStreamWriter(socket.getOutputStream());
 157  0
       outputs = new CarConWriter(out, ".");
 158  0
       errors = new CarConWriter(out, "!");
 159  0
     }
 160  
 
 161  
     public void run() {
 162  0
       interpreters.put(this, Boolean.TRUE);
 163  
       try {
 164  0
         Vector args = new Vector();
 165  
         
 166  0
         out.write(">\n");
 167  0
         out.flush();
 168  
 
 169  
         handle: for (;;) {
 170  0
           switch (in.nextToken()) {
 171  
             case StreamTokenizer.TT_EOL:
 172  0
               String[] theArgs = new String[args.size()];
 173  0
               args.copyInto(theArgs);
 174  0
               args.removeAllElements();
 175  
               try {
 176  0
                 interpreter.interpret(theArgs, outputs, errors);
 177  
               }
 178  0
               catch (Exception e) {
 179  0
                 errors.write(e + "\n");
 180  0
               }
 181  
 
 182  0
               out.write(">\n");
 183  0
               out.flush();
 184  
 
 185  0
               break;
 186  
 
 187  
             case StreamTokenizer.TT_EOF:
 188  0
               break handle;
 189  
 
 190  
             default:
 191  0
               args.addElement(in.sval);
 192  
           }
 193  
         }
 194  
       }
 195  0
       catch (Exception e) {
 196  0
         System.err.println("CommandServer.Loop.run: " + e);
 197  
       }
 198  
       finally {
 199  0
         try { out.close(); } catch (Exception e) {}
 200  0
         try { socket.close(); } catch (Exception e) {}
 201  
 
 202  0
         interpreters.remove(this);
 203  0
         synchronized (interpreters) {
 204  0
           interpreters.notifyAll();
 205  0
         }
 206  0
       }
 207  0
     }
 208  
   }
 209  
 }