Add new attribute "sourcefilename" to "class" element in XML report (#702)

This allows to unambiguously relate classes to source files in case of
multiple top level classes.
diff --git a/org.jacoco.doc/docroot/doc/changes.html b/org.jacoco.doc/docroot/doc/changes.html
index 5299b4e..bed7d9d 100644
--- a/org.jacoco.doc/docroot/doc/changes.html
+++ b/org.jacoco.doc/docroot/doc/changes.html
@@ -45,6 +45,14 @@
       (GitHub <a href="https://github.com/jacoco/jacoco/issues/703">#703</a>).</li>
 </ul>
 
+<h3>API Changes</h3>
+<ul>
+  <li>The XML report now has an optional attribute <code>sourcefilename</code>
+      on the <code>class</code> element to allow unambiguously relate classes
+      to source files. The JaCoCo DTD version has been updated to 1.1
+      (GitHub <a href="https://github.com/jacoco/jacoco/issues/702">#702</a>).</li>
+</ul>
+
 <h2>Release 0.8.1 (2018/03/21)</h2>
 
 <h3>New Features</h3>
diff --git a/org.jacoco.report.test/src/org/jacoco/report/internal/xml/XMLGroupVisitorTest.java b/org.jacoco.report.test/src/org/jacoco/report/internal/xml/XMLGroupVisitorTest.java
index fb8771e..e7eb78e 100644
--- a/org.jacoco.report.test/src/org/jacoco/report/internal/xml/XMLGroupVisitorTest.java
+++ b/org.jacoco.report.test/src/org/jacoco/report/internal/xml/XMLGroupVisitorTest.java
@@ -44,7 +44,7 @@
 	public void setup() throws Exception {
 		buffer = new StringWriter();
 		support = new XMLSupport(XMLFormatter.class);
-		root = new XMLDocument("report", "-//JACOCO//DTD Report 1.0//EN",
+		root = new XMLDocument("report", "-//JACOCO//DTD Report 1.1//EN",
 				"report.dtd", "UTF-8", true, buffer);
 		root.attr("name", "Report");
 		handler = new XMLGroupVisitor(root, null);
@@ -77,8 +77,8 @@
 				"//report/counter[@type='BRANCH']/@covered"));
 	}
 
-	private Document getDocument() throws SAXException, IOException,
-			ParserConfigurationException {
+	private Document getDocument()
+			throws SAXException, IOException, ParserConfigurationException {
 		return support.parse(buffer.toString());
 	}
 
diff --git a/org.jacoco.report.test/src/org/jacoco/report/xml/XMLFormatterTest.java b/org.jacoco.report.test/src/org/jacoco/report/xml/XMLFormatterTest.java
index c79078e..c409589 100644
--- a/org.jacoco.report.test/src/org/jacoco/report/xml/XMLFormatterTest.java
+++ b/org.jacoco.report.test/src/org/jacoco/report/xml/XMLFormatterTest.java
@@ -98,6 +98,8 @@
 		assertPathMatches("org/jacoco/example", "/report/group/package/@name");
 		assertPathMatches("org/jacoco/example/FooClass",
 				"/report/group/package/class/@name");
+		assertPathMatches("FooClass.java",
+				"/report/group/package/class/@sourcefilename");
 		assertPathMatches("fooMethod",
 				"/report/group/package/class/method/@name");
 
@@ -167,8 +169,8 @@
 		final IReportVisitor visitor = formatter.createVisitor(output);
 		visitor.visitInfo(infos, data);
 		driver.sendBundle(visitor);
-		final BufferedReader reader = new BufferedReader(new InputStreamReader(
-				output.getContentsAsStream(), "UTF-8"));
+		final BufferedReader reader = new BufferedReader(
+				new InputStreamReader(output.getContentsAsStream(), "UTF-8"));
 		final String line = reader.readLine();
 		assertTrue(line,
 				line.startsWith("<?xml version=\"1.0\" encoding=\"UTF-8\""));
@@ -180,8 +182,8 @@
 		final IReportVisitor visitor = formatter.createVisitor(output);
 		visitor.visitInfo(infos, data);
 		driver.sendBundle(visitor);
-		final BufferedReader reader = new BufferedReader(new InputStreamReader(
-				output.getContentsAsStream(), "UTF-16"));
+		final BufferedReader reader = new BufferedReader(
+				new InputStreamReader(output.getContentsAsStream(), "UTF-16"));
 		final String line = reader.readLine();
 		assertTrue(line,
 				line.startsWith("<?xml version=\"1.0\" encoding=\"UTF-16\""));
diff --git a/org.jacoco.report/src/org/jacoco/report/internal/xml/XMLCoverageWriter.java b/org.jacoco.report/src/org/jacoco/report/internal/xml/XMLCoverageWriter.java
index be326ec..14add6f 100644
--- a/org.jacoco.report/src/org/jacoco/report/internal/xml/XMLCoverageWriter.java
+++ b/org.jacoco.report/src/org/jacoco/report/internal/xml/XMLCoverageWriter.java
@@ -83,6 +83,7 @@
 	private static void writeClass(final IClassCoverage c,
 			final XMLElement parent) throws IOException {
 		final XMLElement element = createChild(parent, "class", c.getName());
+		element.attr("sourcefilename", c.getSourceFileName());
 		for (final IMethodCoverage m : c.getMethods()) {
 			writeMethod(m, element);
 		}
diff --git a/org.jacoco.report/src/org/jacoco/report/xml/XMLFormatter.java b/org.jacoco.report/src/org/jacoco/report/xml/XMLFormatter.java
index baeba88..0f2bd1b 100644
--- a/org.jacoco.report/src/org/jacoco/report/xml/XMLFormatter.java
+++ b/org.jacoco.report/src/org/jacoco/report/xml/XMLFormatter.java
@@ -32,7 +32,7 @@
  */
 public class XMLFormatter {
 
-	private static final String PUBID = "-//JACOCO//DTD Report 1.0//EN";
+	private static final String PUBID = "-//JACOCO//DTD Report 1.1//EN";
 
 	private static final String SYSTEM = "report.dtd";
 
diff --git a/org.jacoco.report/src/org/jacoco/report/xml/report.dtd b/org.jacoco.report/src/org/jacoco/report/xml/report.dtd
index 6ceab8b..291a467 100644
--- a/org.jacoco.report/src/org/jacoco/report/xml/report.dtd
+++ b/org.jacoco.report/src/org/jacoco/report/xml/report.dtd
@@ -13,7 +13,7 @@
 <!-- This DTD describes the JaCoCo XML report format. It is identified by the
      following identifiers:
 
-        PUBID  = "-//JACOCO//DTD Report 1.0//EN"
+        PUBID  = "-//JACOCO//DTD Report 1.1//EN"
         SYSTEM = "report.dtd"
 -->
 
@@ -44,6 +44,8 @@
 <!ELEMENT class (method*, counter*)>
   <!-- fully qualified VM name -->
   <!ATTLIST class name CDATA #REQUIRED>
+  <!-- name of the corresponding source file -->
+  <!ATTLIST class sourcefilename CDATA #IMPLIED>
 
 <!-- representation of a method -->
 <!ELEMENT method (counter*)>