1 /******************************************************************************* 2 * Copyright (c) 2009, 2018 Mountainminds GmbH & Co. KG and Contributors 3 * All rights reserved. This program and the accompanying materials 4 * are made available under the terms of the Eclipse Public License v1.0 5 * which accompanies this distribution, and is available at 6 * http://www.eclipse.org/legal/epl-v10.html 7 * 8 * Contributors: 9 * Brock Janiczak -initial API and implementation 10 * 11 *******************************************************************************/ 12 package org.jacoco.report.xml; 13 14 import java.io.IOException; 15 import java.io.OutputStream; 16 import java.util.Collection; 17 import java.util.List; 18 19 import org.jacoco.core.analysis.IBundleCoverage; 20 import org.jacoco.core.data.ExecutionData; 21 import org.jacoco.core.data.SessionInfo; 22 import org.jacoco.report.IReportVisitor; 23 import org.jacoco.report.ISourceFileLocator; 24 import org.jacoco.report.internal.AbstractGroupVisitor; 25 import org.jacoco.report.internal.xml.XMLCoverageWriter; 26 import org.jacoco.report.internal.xml.XMLDocument; 27 import org.jacoco.report.internal.xml.XMLElement; 28 import org.jacoco.report.internal.xml.XMLGroupVisitor; 29 30 /** 31 * Report formatter that creates a single XML file for a coverage session 32 */ 33 public class XMLFormatter { 34 35 private static final String PUBID = "-//JACOCO//DTD Report 1.0//EN"; 36 37 private static final String SYSTEM = "report.dtd"; 38 39 private String outputEncoding = "UTF-8"; 40 41 /** 42 * Sets the encoding used for generated XML document. Default is UTF-8. 43 * 44 * @param outputEncoding 45 * XML output encoding 46 */ setOutputEncoding(final String outputEncoding)47 public void setOutputEncoding(final String outputEncoding) { 48 this.outputEncoding = outputEncoding; 49 } 50 51 /** 52 * Creates a new visitor to write a report to the given stream. 53 * 54 * @param output 55 * output stream to write the report to 56 * @return visitor to emit the report data to 57 * @throws IOException 58 * in case of problems with the output stream 59 */ createVisitor(final OutputStream output)60 public IReportVisitor createVisitor(final OutputStream output) 61 throws IOException { 62 final XMLElement root = new XMLDocument("report", PUBID, SYSTEM, 63 outputEncoding, true, output); 64 class RootVisitor extends XMLGroupVisitor implements IReportVisitor { 65 66 RootVisitor(final XMLElement element) throws IOException { 67 super(element, null); 68 } 69 70 private List<SessionInfo> sessionInfos; 71 72 public void visitInfo(final List<SessionInfo> sessionInfos, 73 final Collection<ExecutionData> executionData) 74 throws IOException { 75 this.sessionInfos = sessionInfos; 76 } 77 78 @Override 79 protected void handleBundle(final IBundleCoverage bundle, 80 final ISourceFileLocator locator) throws IOException { 81 writeHeader(bundle.getName()); 82 XMLCoverageWriter.writeBundle(bundle, element); 83 } 84 85 @Override 86 protected AbstractGroupVisitor handleGroup(final String name) 87 throws IOException { 88 writeHeader(name); 89 return new XMLGroupVisitor(element, name); 90 } 91 92 private void writeHeader(final String name) throws IOException { 93 element.attr("name", name); 94 for (final SessionInfo i : sessionInfos) { 95 final XMLElement sessioninfo = root.element("sessioninfo"); 96 sessioninfo.attr("id", i.getId()); 97 sessioninfo.attr("start", i.getStartTimeStamp()); 98 sessioninfo.attr("dump", i.getDumpTimeStamp()); 99 } 100 } 101 102 @Override 103 protected void handleEnd() throws IOException { 104 element.close(); 105 } 106 } 107 return new RootVisitor(root); 108 } 109 110 } 111