package info.fitnesse;
import fit.*;
import util.StreamReader;
import util.CommandLine;
import java.io.*;
import java.net.Socket;
public class TransactionalFitServer {
public class DocumentRunner implements Runnable {
private int size;
public DocumentRunner(int size) {
this.size = size;
}
public void run() {
try {
print("processing document of size: " + size + "\n");
String document = FitProtocol.readDocument(socketReader, size);
Parse tables = new Parse(document);
newFixture().doTables(tables);
print("\tresults: " + fixture.counts() + "\n");
} catch (Exception e) {
exception(e);
}
}
}
public Fixture fixture = new Fixture();
public FixtureListener fixtureListener = new TablePrintingFixtureListener();
private OutputStream socketOutput;
private StreamReader socketReader;
private boolean verbose = false;
private String host;
private int port;
private int socketToken;
private Socket socket;
public static void main(String argv[]) throws Exception {
TransactionalFitServer fitServer = new TransactionalFitServer();
fitServer.run(argv);
System.exit(fitServer.exitCode());
}
public void run(String argv[]) throws Exception {
args(argv);
establishConnection();
validateConnection();
process();
closeConnection();
exit();
}
public void closeConnection() throws IOException {
socket.close();
}
public void process() {
RollbackIntf rollbackProcessingBean = FitnesseSpringContext.getRollbackBean();
fixture.listener = fixtureListener;
try {
int size;
while ((size = FitProtocol.readSize(socketReader)) != 0) {
try {
rollbackProcessingBean.process(new DocumentRunner(size));
} catch (RollbackNow rn) {
print("rolling back now" + "\n");
}
}
print("completion signal received" + "\n");
} catch (Exception e) {
exception(e);
}
}
protected Fixture newFixture() {
fixture = new Fixture();
fixture.listener = fixtureListener;
return fixture;
}
public void args(String[] argv) {
CommandLine commandLine = new CommandLine("[-v] host port socketToken");
if (commandLine.parse(argv)) {
host = commandLine.getArgument("host");
port = Integer.parseInt(commandLine.getArgument("port"));
socketToken = Integer.parseInt(commandLine
.getArgument("socketToken"));
verbose = commandLine.hasOption("v");
} else
usage();
}
private void usage() {
System.out
.println("usage: java test.RollbackServer [-v] host port socketTicket");
System.out.println("\t-v\tverbose");
System.exit(-1);
}
protected void exception(Exception e) {
print("Exception occurred!" + "\n");
print("\t" + e.getMessage() + "\n");
Parse tables = new Parse("span", "Exception occurred: ", null, null);
fixture.exception(tables, e);
fixture.listener.tableFinished(tables);
fixture.listener.tablesFinished(fixture.counts);
}
public void exit() throws Exception {
print("exiting" + "\n");
print("\tend results: " + fixture.counts.toString() + "\n");
}
public int exitCode() {
return fixture.counts.wrong + fixture.counts.exceptions;
}
public void establishConnection() throws Exception {
establishConnection(makeHttpRequest());
}
public void establishConnection(String httpRequest) throws Exception {
socket = new Socket(host, port);
socketOutput = socket.getOutputStream();
socketReader = new StreamReader(socket.getInputStream());
byte[] bytes = httpRequest.getBytes("UTF-8");
socketOutput.write(bytes);
socketOutput.flush();
print("http request sent" + "\n");
}
private String makeHttpRequest() {
return "GET /?responder=socketCatcher&ticket=" + socketToken
+ " HTTP/1.1\r\n\r\n";
}
public void validateConnection() throws Exception {
print("validating connection...");
int statusSize = FitProtocol.readSize(socketReader);
if (statusSize == 0)
print("...ok" + "\n");
else {
String errorMessage = FitProtocol.readDocument(socketReader,
statusSize);
print("...failed because: " + errorMessage + "\n");
System.out.println("An error occurred while connecting to client.");
System.out.println(errorMessage);
System.exit(-1);
}
}
private void print(String message) {
if (verbose)
System.out.print(message);
}
public static byte[] readTable(Parse table) throws Exception {
ByteArrayOutputStream byteBuffer = new ByteArrayOutputStream();
OutputStreamWriter streamWriter = new OutputStreamWriter(byteBuffer,
"UTF-8");
PrintWriter writer = new PrintWriter(streamWriter);
Parse more = table.more;
table.more = null;
if (table.trailer == null)
table.trailer = "";
table.print(writer);
table.more = more;
writer.close();
return byteBuffer.toByteArray();
}
class TablePrintingFixtureListener implements FixtureListener {
public void tableFinished(Parse table) {
try {
byte[] bytes = readTable(table);
if (bytes.length > 0)
FitProtocol.writeData(bytes, socketOutput);
} catch (Exception e) {
e.printStackTrace();
}
}
public void tablesFinished(Counts count) {
try {
FitProtocol.writeCounts(count, socketOutput);
} catch (IOException e) {
e.printStackTrace();
}
}
}
}