@@ -23,7 +23,7 @@
* Alternately, this acknowlegement may appear in the software itself,
* Alternately, this acknowlegement may appear in the software itself,
* if and wherever such third-party acknowlegements normally appear.
* if and wherever such third-party acknowlegements normally appear.
*
*
* 4. The names "The Jakarta Project", "Tomca t", and "Apache Software
* 4. The names "The Jakarta Project", "An t", and "Apache Software
* Foundation" must not be used to endorse or promote products derived
* Foundation" must not be used to endorse or promote products derived
* from this software without prior written permission. For written
* from this software without prior written permission. For written
* permission, please contact apache@apache.org.
* permission, please contact apache@apache.org.
@@ -62,6 +62,7 @@ import java.util.*;
import javax.xml.parsers.*;
import javax.xml.parsers.*;
import org.w3c.dom.*;
import org.w3c.dom.*;
import org.apache.tools.ant.BuildException;
import org.apache.tools.ant.BuildException;
import org.apache.tools.ant.util.DOMElementWriter;
import junit.framework.Test;
import junit.framework.Test;
import junit.framework.TestCase;
import junit.framework.TestCase;
@@ -69,7 +70,7 @@ import junit.framework.TestCase;
/**
/**
* Prints XML output of the test to a specified Writer.
* Prints XML output of the test to a specified Writer.
*
*
* @author <a href="mailto:stefan.bodewig@megabit.net ">Stefan Bodewig</a>
* @author <a href="mailto:stefan.bodewig@epost.de ">Stefan Bodewig</a>
*/
*/
public class XMLJUnitResultFormatter implements JUnitResultFormatter {
public class XMLJUnitResultFormatter implements JUnitResultFormatter {
@@ -120,7 +121,7 @@ public class XMLJUnitResultFormatter implements JUnitResultFormatter {
public void startTestSuite(JUnitTest suite) {
public void startTestSuite(JUnitTest suite) {
doc = getDocumentBuilder().newDocument();
doc = getDocumentBuilder().newDocument();
rootElement = doc.createElement("testsuite");
rootElement = doc.createElement("testsuite");
rootElement.setAttribute("name", xmlEscape( suite.getName() ));
rootElement.setAttribute("name", suite.getName());
}
}
/**
/**
@@ -137,7 +138,7 @@ public class XMLJUnitResultFormatter implements JUnitResultFormatter {
try {
try {
wri = new OutputStreamWriter(out);
wri = new OutputStreamWriter(out);
wri.write("<?xml version=\"1.0\"?>\n");
wri.write("<?xml version=\"1.0\"?>\n");
write(rootElement, wri, 0);
(new DOMElementWriter()). write(rootElement, wri, 0, " " );
wri.flush();
wri.flush();
} catch(IOException exc) {
} catch(IOException exc) {
throw new BuildException("Unable to write log file", exc);
throw new BuildException("Unable to write log file", exc);
@@ -161,7 +162,7 @@ public class XMLJUnitResultFormatter implements JUnitResultFormatter {
public void startTest(Test t) {
public void startTest(Test t) {
lastTestStart = System.currentTimeMillis();
lastTestStart = System.currentTimeMillis();
currentTest = doc.createElement("testcase");
currentTest = doc.createElement("testcase");
currentTest.setAttribute("name", xmlEscape( ((TestCase) t).name() ));
currentTest.setAttribute("name", ((TestCase) t).name());
rootElement.appendChild(currentTest);
rootElement.appendChild(currentTest);
}
}
@@ -208,9 +209,9 @@ public class XMLJUnitResultFormatter implements JUnitResultFormatter {
String message = t.getMessage();
String message = t.getMessage();
if (message != null && message.length() > 0) {
if (message != null && message.length() > 0) {
nested.setAttribute("message", xmlEscape( t.getMessage() ));
nested.setAttribute("message", t.getMessage());
}
}
nested.setAttribute("type", xmlEscape( t.getClass().getName() ));
nested.setAttribute("type", t.getClass().getName());
StringWriter swr = new StringWriter();
StringWriter swr = new StringWriter();
t.printStackTrace(new PrintWriter(swr, true));
t.printStackTrace(new PrintWriter(swr, true));
@@ -218,97 +219,4 @@ public class XMLJUnitResultFormatter implements JUnitResultFormatter {
nested.appendChild(trace);
nested.appendChild(trace);
}
}
/**
* Translates <, & , " and > to corresponding entities.
*/
private String xmlEscape(String orig) {
if (orig == null) return "";
StringBuffer temp = new StringBuffer();
StringCharacterIterator sci = new StringCharacterIterator(orig);
for (char c = sci.first(); c != CharacterIterator.DONE;
c = sci.next()) {
switch (c) {
case '<':
temp.append("<");
break;
case '>':
temp.append(">");
break;
case '\"':
temp.append(""");
break;
case '&':
temp.append("&");
break;
default:
temp.append(c);
break;
}
}
return temp.toString();
}
/**
* Writes a DOM element to a stream.
*/
private static void write(Element element, Writer out, int indent) throws IOException {
// Write indent characters
for (int i = 0; i < indent; i++) {
out.write("\t");
}
// Write element
out.write("<");
out.write(element.getTagName());
// Write attributes
NamedNodeMap attrs = element.getAttributes();
for (int i = 0; i < attrs.getLength(); i++) {
Attr attr = (Attr) attrs.item(i);
out.write(" ");
out.write(attr.getName());
out.write("=\"");
out.write(attr.getValue());
out.write("\"");
}
out.write(">");
// Write child attributes and text
boolean hasChildren = false;
NodeList children = element.getChildNodes();
for (int i = 0; i < children.getLength(); i++) {
Node child = children.item(i);
if (child.getNodeType() == Node.ELEMENT_NODE) {
if (!hasChildren) {
out.write("\n");
hasChildren = true;
}
write((Element)child, out, indent + 1);
}
if (child.getNodeType() == Node.TEXT_NODE) {
out.write("<![CDATA[");
out.write(((Text)child).getData());
out.write("]]>");
}
}
// If we had child elements, we need to indent before we close
// the element, otherwise we're on the same line and don't need
// to indent
if (hasChildren) {
for (int i = 0; i < indent; i++) {
out.write("\t");
}
}
// Write element close
out.write("</");
out.write(element.getTagName());
out.write(">\n");
}
} // XMLJUnitResultFormatter
} // XMLJUnitResultFormatter