package coverage; import java.io.BufferedReader; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.io.StringReader; import java.io.StringWriter; import java.nio.charset.Charset; import java.util.Collection; import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; import javax.xml.parsers.ParserConfigurationException; import javax.xml.transform.OutputKeys; import javax.xml.transform.Transformer; import javax.xml.transform.TransformerException; import javax.xml.transform.TransformerFactory; import javax.xml.transform.dom.DOMSource; import javax.xml.transform.stream.StreamResult; import org.w3c.dom.Document; import org.w3c.dom.Element; public class XMLWriter implements XMLCoverage { private final Coverage coverage; public XMLWriter(Coverage coverage) { this.coverage = coverage; } public String write() throws ParserConfigurationException, TransformerException { DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); dbf.setNamespaceAware(true); dbf.setIgnoringComments(true); dbf.setIgnoringElementContentWhitespace(false); dbf.setCoalescing(true); dbf.setExpandEntityReferences(true); DocumentBuilder db = dbf.newDocumentBuilder(); Document doc = db.newDocument(); // Create the Xml Representation return createXMLDocument(doc); } private String createXMLDocument(Document doc) throws TransformerException { Element root = doc.createElement(ROOT); root.setAttribute(TYPE, coverage.getType()); root.setAttribute(BASE, Integer.toString(coverage.getBaseValue())); for (String fileName : coverage.getFiles()) { Element file = doc.createElement(FILE); file.setAttribute(FILE_NAME, fileName); Element coverageElement = doc.createElement(COVERAGE_KEY); Collection<Interaction> coveredLines = coverage.getCoverage(fileName); // int from = Integer.MIN_VALUE; // int current = Integer.MIN_VALUE; for (Interaction interaction : coveredLines) { int line = interaction.getLine(); // if (from == Integer.MIN_VALUE) { // from = line; // current = line; // continue; // } // if (line <= current + 1) { // current = line; // continue; // } // Element lineElement = doc.createElement(COVERED_LINE); // if (from == current) { lineElement.setAttribute(THIS, Integer.toString(line)); // } else { // lineElement.setAttribute(FROM, Integer.toString(from)); // lineElement.setAttribute(TO, Integer.toString(current)); // } lineElement.setAttribute(INTERACTION, Integer.toString(interaction.getInteraction())); lineElement.setAttribute(TEXT, interaction.getText()); coverageElement.appendChild(lineElement); // // from = line; // current = line; } // Element lineElement = doc.createElement(COVERED_LINE); // if (from == current) { // lineElement.setAttribute(THIS, Integer.toString(from)); // } else { // lineElement.setAttribute(FROM, Integer.toString(from)); // lineElement.setAttribute(TO, Integer.toString(current)); // } // coverageElement.appendChild(lineElement); file.appendChild(coverageElement); root.appendChild(file); } doc.appendChild(root); // Transform the Xml Representation into a String Transformer transfo = TransformerFactory.newInstance().newTransformer(); transfo.setOutputProperty(OutputKeys.METHOD, "xml"); transfo.setOutputProperty(OutputKeys.INDENT, "yes"); StreamResult result = new StreamResult(new StringWriter()); DOMSource source = new DOMSource(doc); transfo.transform(source, result); return prettyPrint(result.getWriter().toString()); } public void writeToFile(File file) throws ParserConfigurationException, TransformerException { try (FileOutputStream output = new FileOutputStream(file)) { if (!file.exists()) { file.createNewFile(); } output.write(write().getBytes(Charset.availableCharsets().get("UTF-8"))); output.flush(); } catch (IOException e) { e.printStackTrace(); } } /** * Inserts indentations into the text * @param text * @return */ private String prettyPrint (String text) { StringBuilder result = new StringBuilder(); String line; int indentLevel = 0; BufferedReader reader = new BufferedReader(new StringReader(text)); try { line = reader.readLine(); while (line != null) { if (line.startsWith("</") ) { indentLevel--; for (int i=0; i < indentLevel; i++) { result.append("\t"); } } else if (line.startsWith("<")) { for (int i=0; i < indentLevel; i++) { result.append("\t"); } if (!line.contains("</") ) { indentLevel++; } } else { for (int i=0; i < indentLevel; i++) { result.append("\t"); } } result.append(line + "\n"); if (line.contains("/>")) { indentLevel--; } line = reader.readLine(); } } catch (IOException e) { e.printStackTrace(); } return result.toString(); } }