// 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.responders.run; import java.io.IOException; import java.net.Socket; import java.util.List; import fit.FitProtocol; import fitnesse.FitNesseContext; import fitnesse.Responder; import fitnesse.components.ClassPathBuilder; import fitnesse.components.FitClient; import fitnesse.html.SetupTeardownAndLibraryIncluder; import fitnesse.http.Request; import fitnesse.http.Response; import fitnesse.http.ResponseSender; import fitnesse.wiki.PageCrawler; import fitnesse.wiki.PageData; import fitnesse.wiki.PathParser; import fitnesse.wiki.VirtualEnabledPageCrawler; import fitnesse.wiki.WikiPage; import fitnesse.wiki.WikiPagePath; public class FitClientResponder implements Responder, ResponsePuppeteer, TestSystemListener { private FitNesseContext context; private PageCrawler crawler; private String resource; private WikiPage page; private boolean shouldIncludePaths; private String suiteFilter; public Response makeResponse(FitNesseContext context, Request request) { this.context = context; crawler = context.root.getPageCrawler(); crawler.setDeadEndStrategy(new VirtualEnabledPageCrawler()); resource = request.getResource(); shouldIncludePaths = request.hasInput("includePaths"); suiteFilter = (String) request.getInput("suiteFilter"); return new PuppetResponse(this); } public void readyToSend(ResponseSender sender) { Socket socket = sender.getSocket(); WikiPagePath pagePath = PathParser.parse(resource); try { if (!crawler.pageExists(context.root, pagePath)) FitProtocol.writeData(notFoundMessage(), socket.getOutputStream()); else { page = crawler.getPage(context.root, pagePath); PageData data = page.getData(); if (data.hasAttribute("Suite")) handleSuitePage(socket, page, context.root); else if (data.hasAttribute("Test")) handleTestPage(socket, data); else FitProtocol.writeData(notATestMessage(), socket.getOutputStream()); } } catch (Exception e) { throw new RuntimeException(e); } sender.close(); } private void handleTestPage(Socket socket, PageData data) throws IOException, InterruptedException { FitClient client = startClient(socket); if (shouldIncludePaths) { String classpath = new ClassPathBuilder().getClasspath(page); client.send(classpath); } sendPage(data, client, true); closeClient(client); } private void handleSuitePage(Socket socket, WikiPage page, WikiPage root) throws IOException, InterruptedException { FitClient client = startClient(socket); SuiteFilter filter = new SuiteFilter(suiteFilter, null, null); SuiteContentsFinder suiteTestFinder = new SuiteContentsFinder(page, filter, root); List<WikiPage> testPages = suiteTestFinder.makePageList(); if (shouldIncludePaths) { MultipleTestsRunner runner = new MultipleTestsRunner(testPages, context, page, null); String classpath = runner.buildClassPath(); client.send(classpath); } for (WikiPage testPage : testPages) { PageData testPageData = testPage.getData(); sendPage(testPageData, client, false); } closeClient(client); } private void sendPage(PageData data, FitClient client, boolean includeSuiteSetup) throws IOException, InterruptedException { String pageName = crawler.getRelativeName(page, data.getWikiPage()); SetupTeardownAndLibraryIncluder.includeInto(data, includeSuiteSetup); String testableHtml = data.getHtml(); String sendableHtml = pageName + "\n" + testableHtml; client.send(sendableHtml); } private void closeClient(FitClient client) throws IOException, InterruptedException { client.done(); client.join(); } private FitClient startClient(Socket socket) throws IOException, InterruptedException { FitClient client = new FitClient(this); client.acceptSocket(socket); return client; } private String notATestMessage() { return resource + " is neither a Test page nor a Suite page."; } private String notFoundMessage() { return "The page " + resource + " was not found."; } public void acceptOutputFirst(String output) { } public void testComplete(TestSummary testSummary) { } public void exceptionOccurred(Throwable e) { } }