001: // Copyright (C) 2003,2004,2005 by Object Mentor, Inc. All rights reserved.
002: // Released under the terms of the GNU General Public License version 2 or later.
003: package fitnesse.responders.run;
004:
005: import fitnesse.wiki.*;
006: import fitnesse.components.*;
007: import fitnesse.responders.ErrorResponder;
008: import fitnesse.html.*;
009: import java.util.*;
010: import java.text.SimpleDateFormat;
011:
012: public class ExecutionLog {
013: public static final String ErrorLogName = "ErrorLogs";
014:
015: private PageCrawler crawler;
016:
017: public static SimpleDateFormat makeDateFormat() {
018: // SimpleDateFormat is not thread safe, so we need to create each
019: // instance independently.
020: return new SimpleDateFormat(
021: "h:mm:ss a (z) 'on' EEEE, MMMM d, yyyy");
022: }
023:
024: private String errorLogPageName;
025:
026: private WikiPagePath errorLogPagePath;
027:
028: private WikiPage root;
029:
030: private CommandRunner runner;
031:
032: private List reasons = new LinkedList();
033:
034: private List exceptions = new LinkedList();
035:
036: public ExecutionLog(WikiPage testPage, CommandRunner client)
037: throws Exception {
038: this .runner = client;
039:
040: crawler = testPage.getPageCrawler();
041: crawler.setDeadEndStrategy(new VirtualEnabledPageCrawler());
042: root = crawler.getRoot(testPage);
043: errorLogPagePath = crawler.getFullPath(testPage)
044: .addNameToFront(ErrorLogName);
045: errorLogPageName = PathParser.render(errorLogPagePath);
046: }
047:
048: public void addException(Exception e) {
049: exceptions.add(e);
050: }
051:
052: public void addReason(String reason) {
053: if (!reasons.contains(reason))
054: reasons.add(reason);
055: }
056:
057: public void publish() throws Exception {
058: String content = buildLogContent();
059:
060: WikiPage errorLogPage = crawler.addPage(root, errorLogPagePath);
061: PageData data = errorLogPage.getData();
062: data.setContent(content);
063: errorLogPage.commit(data);
064: }
065:
066: public String buildLogContent() {
067: StringBuffer buffer = new StringBuffer();
068: addEntry(buffer, "Date", makeDateFormat().format(new Date()));
069: addEntry(buffer, "Command", runner.getCommand());
070: addEntry(buffer, "Exit code", String.valueOf(runner
071: .getExitCode()));
072: addEntry(buffer, "Time elapsed", (((double) runner
073: .getExecutionTime()) / 1000.0)
074: + " seconds");
075: if (runner.wroteToOutputStream())
076: addOutputBlock(buffer);
077: if (runner.wroteToErrorStream())
078: addErrorBlock(buffer);
079: if (runner.hasExceptions() || exceptions.size() > 0)
080: addExceptionBlock(buffer);
081: String content = buffer.toString();
082: return content;
083: }
084:
085: private void addEntry(StringBuffer buffer, String key, String value) {
086: buffer.append("|'''").append(key).append(": '''|").append("!-")
087: .append(value).append("-!").append("|\n");
088: }
089:
090: private void addOutputBlock(StringBuffer buffer) {
091: buffer.append("----");
092: buffer.append("'''Standard Output:'''").append("\n");
093: buffer.append("{{{").append(runner.getOutput()).append("}}}");
094: }
095:
096: private void addErrorBlock(StringBuffer buffer) {
097: buffer.append("----");
098: buffer.append("'''Standard Error:'''").append("\n");
099: buffer.append("{{{").append(runner.getError()).append("}}}");
100: }
101:
102: private void addExceptionBlock(StringBuffer buffer) {
103: exceptions.addAll(runner.getExceptions());
104: buffer.append("----");
105: buffer.append("'''Internal Exception");
106: if (exceptions.size() > 1)
107: buffer.append("s");
108: buffer.append(":'''").append("\n");
109: for (Iterator iterator = exceptions.iterator(); iterator
110: .hasNext();) {
111: Exception exception = (Exception) iterator.next();
112: buffer.append("{{{ ").append(
113: ErrorResponder.makeExceptionString(exception))
114: .append("}}}");
115: }
116: }
117:
118: public int exceptionCount() {
119: return exceptions.size();
120: }
121:
122: public String getErrorLogPageName() {
123: return errorLogPageName;
124: }
125:
126: public boolean hasCapturedOutput() {
127: return runner.wroteToErrorStream()
128: || runner.wroteToOutputStream();
129: }
130:
131: public String executionStatusHtml() throws Exception {
132: String linkHref = getErrorLogPageName();
133: return executionStatusHtml(linkHref, "");
134: }
135:
136: public String executionStatusHtml(String linkHref,
137: String imageUrlBase) throws Exception {
138: ExecutionStatus executionStatus;
139:
140: if (exceptionCount() > 0)
141: executionStatus = ExecutionStatus.ERROR;
142: else if (hasCapturedOutput())
143: executionStatus = ExecutionStatus.OUTPUT;
144: else
145: executionStatus = ExecutionStatus.OK;
146:
147: HtmlTag status = new HtmlTag("div");
148: status.addAttribute("id", "execution-status");
149: HtmlTag image = new HtmlTag("img");
150: image.addAttribute("src", imageUrlBase
151: + "/files/images/executionStatus/"
152: + executionStatus.getIconFilename());
153: status.add(HtmlUtil.makeLink(linkHref, image.html()));
154: status.add(HtmlUtil.BR);
155: status.add(HtmlUtil.makeLink(linkHref, executionStatus
156: .getMessage()));
157: return status.html();
158: }
159: }
|