forked from quarkusio/quarkus
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathRevapiUpdate.java
159 lines (110 loc) · 5.47 KB
/
RevapiUpdate.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
//usr/bin/env jbang "$0" "$@" ; exit $?
import java.io.ByteArrayInputStream;
import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.InputStream;
import java.io.SequenceInputStream;
import java.nio.file.Path;
import java.util.Arrays;
import java.util.Collections;
import java.util.Enumeration;
import java.io.File;
import java.io.FileReader;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.transform.OutputKeys;
import javax.xml.transform.Transformer;
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;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
/**
* This script applies the suggestions generated by the revapi output into the api-changes.xml file.
* The suggestions are in api-changes-suggestions.xml file. These suggestions are the new changes in the codebase that
* you might want to ignore (or otherwise process).
*
* The api-changes.xml file contains the new changes you want to ignore.
*
* This script record/update the suggestions that are in the api-changes-suggestions.xml into api-changes.xml.
*/
public class RevapiUpdate {
public static void main(String[] args) {
Path currDir = Path.of(System.getProperty("user.dir"));
File apiChangesFile = currDir.resolve("api-changes.xml").toFile();
File apiSuggestionsFile = currDir.resolve("target/api-changes-suggestions.xml").toFile();
if(!apiSuggestionsFile.exists()){
throw new IllegalStateException("Use this command to run revapi: \"mvn -Papi-check -Drevapi.skip=false -DskipTests verify\"");
}
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
try {
DocumentBuilder db = dbf.newDocumentBuilder();
Document targetDoc;
if(!apiChangesFile.exists())
targetDoc = createApiChangesXmlDoc(db,apiChangesFile);
else
targetDoc = loadApiChangesXmlDoc(db,apiChangesFile);
Document sourceDoc = loadApiSuggestionsXmlDoc(db, apiSuggestionsFile);
copyNodes(sourceDoc, targetDoc, apiChangesFile);
} catch (Exception e) {
e.printStackTrace();
}
}
private static Document createApiChangesXmlDoc(DocumentBuilder db, File file) throws Exception{
Document document = db.newDocument();
Element rootElement = document.createElement("versions");
document.appendChild(rootElement);
Element versionNumber = document.createElement("v999.0.0");
rootElement.appendChild(versionNumber);
Element revapiDifferences = document.createElement("revapi.differences");
versionNumber.appendChild(revapiDifferences);
Element criticality = document.createElement("criticality");
criticality.appendChild(document.createTextNode("documented"));
Element justification = document.createElement("justification");
justification.appendChild(document.createTextNode("ADD YOUR EXPLANATION FOR THE NECESSITY OF THIS CHANGE. YOU CAN ALSO MANUALLY ADD ELEMENTS AT INDIVIDUAL ITEMS TO OVERRIDE THIS DEFAULT."));
revapiDifferences.appendChild(criticality);
revapiDifferences.appendChild(justification);
Element differences = document.createElement("differences");
revapiDifferences.appendChild(differences);
writeToXmlFile(document, file);
return document;
}
private static Document loadApiChangesXmlDoc(DocumentBuilder db, File file) throws Exception{
return db.parse(file);
}
private static Document loadApiSuggestionsXmlDoc(DocumentBuilder db, File file) throws Exception{
Enumeration<InputStream> inputStreams = Collections.enumeration(
Arrays.asList(new InputStream[] {
new ByteArrayInputStream("<root>".getBytes()),
new FileInputStream(file),
new ByteArrayInputStream("</root>".getBytes()),
}));
SequenceInputStream sequenceStream = new SequenceInputStream(inputStreams);
return db.parse(sequenceStream);
}
private static void writeToXmlFile(Document document, File file) throws Exception{
TransformerFactory tff = TransformerFactory.newInstance();
Transformer tf = tff.newTransformer();
tf.setOutputProperty(OutputKeys.INDENT, "yes");
DOMSource source = new DOMSource(document);
StreamResult target = new StreamResult(file);
tf.transform(source, target);
}
private static void copyNodes(Document sourceDoc, Document targetDoc, File file) throws Exception{
Node differencesNode = targetDoc.getDocumentElement().getElementsByTagName("differences").item(0);
NodeList items = sourceDoc.getDocumentElement().getElementsByTagName("item");
for(int i=0; i<items.getLength(); i++){
Element node = (Element) items.item(i);
// Findings are to be reported not ignored
node.removeChild(node.getElementsByTagName("ignore").item(0));
// Top level justification has been added
node.removeChild(node.getElementsByTagName("justification").item(0));
// Node copying
Node importNode = targetDoc.importNode(node, true);
differencesNode.appendChild(importNode);
}
writeToXmlFile(targetDoc,file);
}
}