Skip to content

Commit e9975e8

Browse files
committed
[java-source-utils] Transform XML using XSLT
I've seen inconsistent XML output from java-source-utils when running on macOS vs. Windows, or JDK 8 vs. JDK 11. On Windows I've seen extra carriage returns in CDATA blocks, and when using JDK 9+ we've seen additional new lines added between XML elements. An XSL style sheet can be used to improve the formatting consistency of the XML that is produced. This should prevent us from generating inconsistent API docs across macOS and Windows. There is still an outstanding issue concerning CDATA blocks between JDK 8 and JDK 11 that I have not yet been able to sort out. This issue has seemingly been "fixed" in JDK 14.
1 parent 2601146 commit e9975e8

File tree

8 files changed

+74
-17
lines changed

8 files changed

+74
-17
lines changed

build-tools/automation/azure-pipelines.yaml

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -179,6 +179,5 @@ jobs:
179179
- template: templates\core-tests.yaml
180180
parameters:
181181
runNativeTests: true
182-
runJavaTests: true
183182

184183
- template: templates\fail-on-issue.yaml

build-tools/automation/templates/core-tests.yaml

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
parameters:
22
condition: succeeded()
33
runNativeTests: false
4-
runJavaTests: false
54

65
steps:
76
- task: DotNetCoreCLI@2
@@ -110,15 +109,13 @@ steps:
110109

111110
- task: DotNetCoreCLI@2
112111
displayName: 'Tests: java-source-utils'
113-
condition: eq('${{ parameters.runJavaTests }}', 'true')
114112
inputs:
115113
command: build
116114
arguments: -c $(Build.Configuration) tools/java-source-utils/java-source-utils.csproj -t:RunTests
117115
continueOnError: true
118116

119117
- task: PublishTestResults@2
120118
displayName: Publish JUnit Test Results
121-
condition: eq('${{ parameters.runJavaTests }}', 'true')
122119
inputs:
123120
testResultsFormat: JUnit
124121
testResultsFiles: 'tools/java-source-utils/build/test-results/**/TEST-*.xml'

build-tools/automation/templates/publish-test-results.yaml

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@ steps:
99

1010
- task: PublishTestResults@2
1111
displayName: Publish JUnit Test Results
12-
condition: ne('$(Agent.OS)', 'Windows')
1312
inputs:
1413
testResultsFormat: JUnit
1514
testResultsFiles: '**/TEST-*.xml'

build-tools/scripts/RunNUnitTests.targets

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@
3030
ContinueOnError="ErrorAndContinue"
3131
/>
3232
<MSBuild
33-
Condition=" !$([MSBuild]::IsOSPlatform ('windows')) "
33+
Condition=" '$(SkipJSUTests)' != 'true' "
3434
Projects="$(MSBuildThisFileDirectory)..\..\tools\java-source-utils\java-source-utils.csproj"
3535
Targets="RunTests"
3636
/>

tools/java-source-utils/src/main/java/com/microsoft/android/JavadocXmlGenerator.java

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22

33
import java.io.File;
44
import java.io.FileNotFoundException;
5+
import java.io.InputStream;
6+
import java.io.InputStreamReader;
57
import java.io.IOException;
68
import java.io.PrintStream;
79
import java.io.UnsupportedEncodingException;
@@ -17,6 +19,7 @@
1719
import javax.xml.transform.TransformerFactory;
1820
import javax.xml.transform.dom.DOMSource;
1921
import javax.xml.transform.stream.StreamResult;
22+
import javax.xml.transform.stream.StreamSource;
2023

2124
import org.w3c.dom.Document;
2225
import org.w3c.dom.Element;
@@ -65,10 +68,10 @@ private void startApi() throws ParserConfigurationException {
6568
}
6669

6770
public void close() throws TransformerException {
71+
InputStream is = getClass().getClassLoader().getResourceAsStream("transform-style.xsl");
72+
InputStreamReader isr = new InputStreamReader(is);
6873
Transformer transformer = TransformerFactory.newInstance()
69-
.newTransformer();
70-
transformer.setOutputProperty(OutputKeys.INDENT, "yes");
71-
transformer.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "2");
74+
.newTransformer(new StreamSource (isr));
7275
transformer.transform(new DOMSource(document), new StreamResult(output));
7376

7477
if (output != System.out) {
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
<xsl:stylesheet version="1.0"
2+
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
3+
xmlns:xalan="http://xml.apache.org/xalan">
4+
5+
<xsl:output method="xml"
6+
encoding="UTF-8"
7+
indent="yes"
8+
xalan:indent-amount="2"
9+
standalone="no"
10+
cdata-section-elements="javadoc"/>
11+
12+
<xsl:strip-space elements="*"/>
13+
14+
<xsl:template match="node()|@*">
15+
<xsl:copy>
16+
<xsl:apply-templates select="node()|@*"/>
17+
</xsl:copy>
18+
</xsl:template>
19+
20+
21+
<!-- Remove extra carriage returns from `<javadoc/>` CDATA elements to help standardize output across Unix and Windows -->
22+
<xsl:template match="javadoc/text()">
23+
<xsl:call-template name="removeCarriageReturn"/>
24+
</xsl:template>
25+
26+
<xsl:template name="removeCarriageReturn">
27+
<xsl:param name="pText" select="."/>
28+
29+
<xsl:if test="string-length($pText) >0">
30+
<xsl:choose>
31+
<xsl:when test="not(contains($pText,'&#13;'))">
32+
<xsl:value-of select="$pText"/>
33+
</xsl:when>
34+
35+
<xsl:otherwise>
36+
<xsl:value-of select="substring-before($pText, '&#13;')"/>
37+
<xsl:call-template name="removeCarriageReturn">
38+
<xsl:with-param name="pText" select="substring-after($pText, '&#13;')"/>
39+
</xsl:call-template>
40+
</xsl:otherwise>
41+
</xsl:choose>
42+
</xsl:if>
43+
</xsl:template>
44+
45+
</xsl:stylesheet>

tools/java-source-utils/src/test/java/com/microsoft/android/JavadocXmlGeneratorTest.java

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,12 @@
1919
public final class JavadocXmlGeneratorTest {
2020
@Test(expected = FileNotFoundException.class)
2121
public void init_invalidFileThrows() throws FileNotFoundException, ParserConfigurationException, TransformerException, UnsupportedEncodingException {
22-
try (JavadocXmlGenerator g = new JavadocXmlGenerator("/this/file/does/not/exist")) {
22+
String invalidFilePath = "/this/file/does/not/exist";
23+
String osName = System.getProperty("os.name");
24+
if (osName.startsWith("Windows")) {
25+
invalidFilePath = "C:\\Program Files\\this\\file\\does\\not\\exist";
26+
}
27+
try (JavadocXmlGenerator g = new JavadocXmlGenerator(invalidFilePath)) {
2328
}
2429
}
2530

@@ -40,9 +45,11 @@ public void testWritePackages_noPackages() throws ParserConfigurationException,
4045
generator.writePackages(packages);
4146
generator.close();
4247

43-
final String expected =
48+
final String expected = (
4449
"<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>\n" +
45-
"<api api-source=\"java-source-utils\"/>\n";
50+
"<api api-source=\"java-source-utils\"/>\n"
51+
).replace("\n", System.lineSeparator());
52+
4653
assertEquals("no packages", expected, bytes.toString());
4754
}
4855

@@ -53,7 +60,7 @@ public void testWritePackages_demo() throws ParserConfigurationException, Transf
5360
final JavadocXmlGenerator generator = new JavadocXmlGenerator(new PrintStream(bytes));
5461
final JniPackagesInfo packages = JniPackagesInfoTest.createDemoInfo();
5562

56-
final String expected =
63+
final String expected = (
5764
"<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>\n" +
5865
"<api api-source=\"java-source-utils\">\n" +
5966
" <package jni-name=\"\" name=\"\">\n" +
@@ -94,7 +101,8 @@ public void testWritePackages_demo() throws ParserConfigurationException, Transf
94101
" </method>\n" +
95102
" </interface>\n" +
96103
" </package>\n" +
97-
"</api>\n";
104+
"</api>\n"
105+
).replace("\n", System.lineSeparator());
98106

99107
generator.writePackages(packages);
100108
generator.close();

tools/java-source-utils/src/test/java/com/microsoft/android/ParameterNameGeneratorTest.java

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,12 @@ public class ParameterNameGeneratorTest {
1717

1818
@Test(expected = FileNotFoundException.class)
1919
public void init_invalidFileThrows() throws FileNotFoundException, UnsupportedEncodingException {
20-
new ParameterNameGenerator("/this/file/does/not/exist");
20+
String invalidFilePath = "/this/file/does/not/exist";
21+
String osName = System.getProperty("os.name");
22+
if (osName.startsWith("Windows")) {
23+
invalidFilePath = "C:\\Program Files\\this\\file\\does\\not\\exist";
24+
}
25+
new ParameterNameGenerator(invalidFilePath);
2126
}
2227

2328
@Test(expected = IllegalArgumentException.class)
@@ -45,7 +50,7 @@ public void testWritePackages_demo() {
4550
ParameterNameGenerator generator = new ParameterNameGenerator(new PrintStream(bytes));
4651
JniPackagesInfo packages = JniPackagesInfoTest.createDemoInfo();
4752

48-
final String expected =
53+
final String expected = (
4954
";---------------------------------------\n" +
5055
" class A\n" +
5156
" #ctor(int one, java.lang.String two)\n" +
@@ -60,7 +65,8 @@ public void testWritePackages_demo() {
6065
";---------------------------------------\n" +
6166
" interface Exampleable\n" +
6267
" example(java.lang.String e)\n" +
63-
"";
68+
""
69+
).replace("\n", System.lineSeparator());
6470

6571
generator.writePackages(packages);
6672
assertEquals("global package + example packages", expected, bytes.toString());

0 commit comments

Comments
 (0)