// Copyright (C) 2003-2009 by Object Mentor, Inc. All rights reserved. // Released under the terms of the CPL Common Public License version 1.0. package fitnesse.slim; import fitnesse.socketservice.SocketServer; import util.StreamReader; import java.io.BufferedWriter; import java.io.IOException; import java.io.OutputStreamWriter; import java.net.Socket; import java.util.List; public class SlimServer implements SocketServer { public static final String EXCEPTION_TAG = "__EXCEPTION__:"; public static final String EXCEPTION_STOP_TEST_TAG = "__EXCEPTION__:ABORT_SLIM_TEST:"; private StreamReader reader; private BufferedWriter writer; private ListExecutor executor; private boolean verbose; private SlimFactory slimFactory; public SlimServer(boolean verbose, SlimFactory slimFactory) { this.verbose = verbose; this.slimFactory = slimFactory; } public void serve(Socket s) { try { tryProcessInstructions(s); } catch (Throwable e) { } finally { slimFactory.stop(); close(); closeEnclosingServiceInSeperateThread(); } } private void tryProcessInstructions(Socket s) throws IOException { initialize(s); boolean more = true; while (more) more = processOneSetOfInstructions(); } private void initialize(Socket s) throws IOException { executor = slimFactory.getListExecutor(verbose); reader = new StreamReader(s.getInputStream()); writer = new BufferedWriter(new OutputStreamWriter(s.getOutputStream(), "UTF-8")); writer.write(String.format("Slim -- V%s\n", SlimVersion.VERSION)); writer.flush(); } private boolean processOneSetOfInstructions() throws IOException { String instructions = getInstructionsFromClient(); if (instructions != null) { return processTheInstructions(instructions); } return true; } private String getInstructionsFromClient() throws IOException { int instructionLength = Integer.parseInt(reader.read(6)); reader.read(1); String instructions = reader.read(instructionLength); return instructions; } private boolean processTheInstructions(String instructions) throws IOException { if (instructions.equalsIgnoreCase("bye")) { return false; } else { List<Object> results = executeInstructions(instructions); sendResultsToClient(results); return true; } } private List<Object> executeInstructions(String instructions) { List<Object> statements = ListDeserializer.deserialize(instructions); List<Object> results = executor.execute(statements); return results; } private void sendResultsToClient(List<Object> results) throws IOException { String resultString = ListSerializer.serialize(results); writer.write(String.format("%06d:%s", resultString.getBytes("UTF-8").length, resultString)); writer.flush(); } private void close() { try { reader.close(); writer.close(); } catch (Exception e) { } } private void closeEnclosingServiceInSeperateThread() { new Thread(new Runnable() { public void run() { try { SlimService.instance.close(); } catch (Exception e) { } } } ).start(); } }