package fit; import java.io.*; import java.text.*; import java.net.Socket; import fitnesse.http.StreamReader; public class FitServer { public static final DecimalFormat format = new DecimalFormat("0000000000"); public String input; public Parse tables; public Fixture fixture = new Fixture(); Counts counts = new Counts(); private OutputStream socketOutput; private StreamReader socketReader; private boolean verbose = false; public static void main(String argv[]) throws Exception { new FitServer().run(argv); } public void run(String argv[]) throws Exception { args(argv); establishConnection(); validateConnection(); process(); exit(); } public void process() { fixture.listener = new TablePrintingFixtureListener(); try { int size = 1; while((size = readSize(socketReader)) != 0) { print("processing document of size: " + size); String document = readDocument(socketReader, size); tables = new Parse(document); newFixture().doTables(tables); print("\tresults: " + fixture.counts()); counts.tally(fixture.counts); } print("completion signal recieved"); } catch(Exception e) { exception(e); counts.exceptions += 1; fixture.listener.tablesFinished(counts); } } private Fixture newFixture() { fixture = new Fixture(); fixture.listener = new TablePrintingFixtureListener(); return fixture; } public void args(String[] argv) { for(int i = 0; i < argv.length; i++) { String arg = argv[i]; if("-v".equals(arg)) verbose = true; else { System.out.println("usage: java fit.FitServer [-v]"); System.out.println("\t-v\tverbose"); System.exit(-1); } } } private int readSize(StreamReader input) throws Exception { Number n = format.parse(input.read(10)); return n.intValue(); } private String readDocument(StreamReader input, int size) throws Exception { return input.read(size); } protected void exception(Exception e) { print("Exception occurred!"); print("\t" + e.getMessage()); tables = new Parse("span", "Unable to parse input. Input ignored.", null, null); fixture.exception(tables, e); fixture.listener.tableFinished(tables); } protected void exit() { print("exiting"); print("\tend results: " + counts.toString()); System.exit(counts.wrong + counts.exceptions); } private void establishConnection() throws Exception { StreamReader stdinReader = new StreamReader(System.in); int size = readSize(stdinReader); String hostAndPort = readDocument(stdinReader, size); int colonIndex = hostAndPort.indexOf(':'); String host = hostAndPort.substring(0, colonIndex); int port = Integer.parseInt(hostAndPort.substring(colonIndex + 1)); print("host: " + host + ":" + port); size = readSize(stdinReader); String httpRequest = readDocument(stdinReader, size); print("http: " + httpRequest.trim()); Socket socket = new Socket(host, port); socketOutput = socket.getOutputStream(); socketReader = new StreamReader(socket.getInputStream()); byte[] bytes = httpRequest.getBytes(); socketOutput.write(bytes); print("http request sent"); } private void validateConnection() throws Exception { print("Validating connection..."); int statusSize = readSize(socketReader); if(statusSize == 0) print("\t...ok"); else { String errorMessage = readDocument(socketReader, statusSize); print("\t...failed bacuase: " + errorMessage); System.out.println("An error occured while connecting to client."); System.out.println(errorMessage); System.exit(-1); } } private void print(String message) { if(verbose) System.out.println(message); } class TablePrintingFixtureListener implements FixtureListener { public void tableFinished(Parse table) { try { ByteArrayOutputStream byteBuffer = new ByteArrayOutputStream(); PrintWriter writer = new PrintWriter(byteBuffer); Parse more = table.more; table.more = null; if(table.trailer == null) table.trailer = ""; table.print(writer); table.more = more; writer.close(); byte[] bytes = byteBuffer.toByteArray(); if(bytes.length > 0) { writeSize(bytes.length); socketOutput.write(bytes); socketOutput.flush(); } } catch(IOException e) { e.printStackTrace(); } } public void tablesFinished(Counts count) { try { writeSize(0); writeSize(count.right); writeSize(count.wrong); writeSize(count.ignores); writeSize(count.exceptions); socketOutput.flush(); } catch(IOException e) { e.printStackTrace(); } } private void writeSize(int size) throws IOException { socketOutput.write(format.format(size).getBytes()); } } }