Skip to content

Commit 79c939d

Browse files
committed
Implemented report and config parser
1 parent 9d73475 commit 79c939d

File tree

9 files changed

+262
-2
lines changed

9 files changed

+262
-2
lines changed

config/import-control-test.xml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,5 +8,7 @@
88
<allow pkg="org.openrewrite"/>
99
<allow pkg="org.checkstyle"/>
1010
<allow pkg="java.io"/>
11+
<allow pkg="java.util"/>
1112
<allow pkg="java.nio"/>
13+
<allow pkg="java.lang"/>
1214
</import-control>

config/import-control.xml

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@
88
<allow pkg="org.openrewrite.java"/>
99
<allow pkg="org.openrewrite.java.tree"/>
1010
<allow pkg="java"/>
11+
<allow pkg="javax.xml.stream"/>
12+
<allow pkg="org.thymeleaf.util"/>
1113
<allow pkg="org.checkstyle"/>
1214
<allow pkg="java.util"/>
13-
</import-control>
15+
</import-control>

config/suppressions.xml

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,4 +10,7 @@
1010
<suppress checks="header" files=".*\.java"/>
1111
<suppress checks="multiFileRegexpHeader" files=".*"/>
1212
<suppress checks="JavadocPackage" files=".*"/>
13-
</suppressions>
13+
<suppress checks="MissingJavadocType" files=".*"/>
14+
<suppress checks="JavadocVariable" files=".*"/>
15+
<suppress checks="MissingJavadocMethod" files=".*"/>
16+
</suppressions>

pom.xml

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,14 @@
4444
</dependencyManagement>
4545

4646
<dependencies>
47+
48+
<!-- Checkstyle dependency for parsing Checkstyle configs -->
49+
<dependency>
50+
<groupId>com.puppycrawl.tools</groupId>
51+
<artifactId>checkstyle</artifactId>
52+
<version>${checkstyle.version}</version>
53+
</dependency>
54+
4755
<!-- OpenRewrite core dependencies - using consistent versions -->
4856
<dependency>
4957
<groupId>org.openrewrite</groupId>
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
package org.checkstyle.autofix.data;
2+
3+
public final class CheckstyleRecord {
4+
5+
private final int line;
6+
7+
private final int column;
8+
9+
private final String severity;
10+
11+
private final String source;
12+
13+
private final String message;
14+
15+
private String fileName;
16+
17+
public CheckstyleRecord(int line, int column,
18+
String severity, String source, String message, String xref) {
19+
this.line = line;
20+
this.column = column;
21+
this.severity = severity;
22+
this.source = source;
23+
this.message = message;
24+
this.fileName = xref;
25+
}
26+
27+
public int getLine() {
28+
return line;
29+
}
30+
31+
public int getColumn() {
32+
return column;
33+
}
34+
35+
public String getSource() {
36+
return source;
37+
}
38+
39+
public String getMessage() {
40+
return message;
41+
}
42+
43+
public String getFileName() {
44+
return fileName;
45+
}
46+
47+
public String getSeverity() {
48+
return severity;
49+
}
50+
51+
}
Lines changed: 118 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,118 @@
1+
package org.checkstyle.autofix.parser;
2+
3+
import java.io.FileInputStream;
4+
import java.io.FileNotFoundException;
5+
import java.io.InputStream;
6+
import java.nio.file.Path;
7+
import java.util.ArrayList;
8+
import java.util.Iterator;
9+
import java.util.List;
10+
11+
import javax.xml.stream.XMLEventReader;
12+
import javax.xml.stream.XMLInputFactory;
13+
import javax.xml.stream.XMLStreamException;
14+
import javax.xml.stream.events.Attribute;
15+
import javax.xml.stream.events.StartElement;
16+
import javax.xml.stream.events.XMLEvent;
17+
18+
import org.checkstyle.autofix.data.CheckstyleRecord;
19+
20+
public final class CheckstyleReportsParser {
21+
22+
private static final String FILE_TAG = "file";
23+
24+
private static final String ERROR_TAG = "error";
25+
26+
private static final String FILENAME_ATTR = "name";
27+
28+
private static final String LINE_ATTR = "line";
29+
30+
private static final String COLUMN_ATTR = "column";
31+
32+
private static final String SEVERITY_ATTR = "severity";
33+
34+
private static final String MESSAGE_ATTR = "message";
35+
36+
private static final String SOURCE_ATTR = "source";
37+
38+
private CheckstyleReportsParser() {
39+
40+
}
41+
42+
public static List<CheckstyleRecord> parse(Path xmlPath)
43+
throws FileNotFoundException, XMLStreamException {
44+
45+
final List<CheckstyleRecord> result = new ArrayList<>();
46+
47+
final XMLEventReader reader = createReader(xmlPath);
48+
String filename = null;
49+
50+
while (reader.hasNext()) {
51+
final XMLEvent event = reader.nextEvent();
52+
if (event.isStartElement()) {
53+
final StartElement startElement = event.asStartElement();
54+
final String startElementName = startElement.getName().getLocalPart();
55+
56+
if (FILE_TAG.equals(startElementName)) {
57+
final Iterator<Attribute> attributes = startElement.getAttributes();
58+
while (attributes.hasNext()) {
59+
final Attribute attribute = attributes.next();
60+
if (FILENAME_ATTR.equals(attribute.getName().toString())) {
61+
filename = attribute.getValue();
62+
}
63+
}
64+
}
65+
else if (ERROR_TAG.equals(startElementName)) {
66+
result.add(parseErrorTag(startElement, filename));
67+
}
68+
}
69+
}
70+
71+
return result;
72+
}
73+
74+
private static CheckstyleRecord parseErrorTag(StartElement startElement, String filename) {
75+
int line = -1;
76+
int column = -1;
77+
String source = null;
78+
String message = null;
79+
String severity = null;
80+
final Iterator<Attribute> attributes = startElement
81+
.getAttributes();
82+
while (attributes.hasNext()) {
83+
final Attribute attribute = attributes.next();
84+
final String attrName = attribute.getName().toString();
85+
switch (attrName) {
86+
case LINE_ATTR:
87+
line = Integer.parseInt(attribute.getValue());
88+
break;
89+
case COLUMN_ATTR:
90+
column = Integer.parseInt(attribute.getValue());
91+
break;
92+
case SEVERITY_ATTR:
93+
severity = attribute.getValue();
94+
break;
95+
case MESSAGE_ATTR:
96+
message = attribute.getValue();
97+
break;
98+
case SOURCE_ATTR:
99+
source = attribute.getValue();
100+
break;
101+
default:
102+
break;
103+
}
104+
}
105+
return new CheckstyleRecord(
106+
line, column, severity, source, message, filename);
107+
108+
}
109+
110+
private static XMLEventReader createReader(Path xmlFilename)
111+
throws FileNotFoundException, XMLStreamException {
112+
113+
final XMLInputFactory inputFactory = XMLInputFactory.newInstance();
114+
final InputStream inputStream = new FileInputStream(xmlFilename.toFile());
115+
return inputFactory.createXMLEventReader(inputStream);
116+
}
117+
118+
}
Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
package org.checkstyle.autofix.parser;
2+
3+
import static org.junit.jupiter.api.Assertions.assertEquals;
4+
import static org.junit.jupiter.api.Assertions.assertNotNull;
5+
6+
import java.nio.file.Path;
7+
import java.util.List;
8+
import java.util.Map;
9+
import java.util.stream.Collectors;
10+
11+
import org.checkstyle.autofix.data.CheckstyleRecord;
12+
import org.junit.jupiter.api.Test;
13+
14+
public class CheckstyleReportsParserTest {
15+
16+
private static String getPath(String path) {
17+
return "src/test/resources/org/checkstyle/autofix/parser/" + path;
18+
}
19+
20+
@Test
21+
public void testParseFromResource() throws Exception {
22+
final Path xmlPath = Path.of(getPath("checkstyle-report.xml"));
23+
final List<CheckstyleRecord> records = CheckstyleReportsParser.parse(xmlPath);
24+
25+
assertNotNull(records);
26+
assertEquals(1, records.size());
27+
28+
final CheckstyleRecord record = records.get(0);
29+
assertEquals(42, record.getLine());
30+
assertEquals(13, record.getColumn());
31+
assertEquals("error", record.getSeverity());
32+
assertEquals("Example message", record.getMessage());
33+
assertEquals("com.puppycrawl.example.Check", record.getSource());
34+
assertEquals("Example.java", record.getFileName());
35+
}
36+
37+
@Test
38+
public void testParseMultipleFilesReport() throws Exception {
39+
final Path xmlPath = Path.of(getPath("checkstyle-multiple-files.xml"));
40+
final List<CheckstyleRecord> records = CheckstyleReportsParser.parse(xmlPath);
41+
42+
assertNotNull(records);
43+
assertEquals(3, records.size());
44+
45+
final Map<String, List<CheckstyleRecord>> grouped = records.stream()
46+
.collect(Collectors.groupingBy(CheckstyleRecord::getFileName));
47+
48+
assertEquals(2, grouped.size());
49+
50+
assertEquals(2, grouped.get("Main.java").size());
51+
assertEquals(1, grouped.get("Utils.java").size());
52+
53+
CheckstyleRecord record = grouped.get("Main.java").get(0);
54+
assertEquals("error", record.getSeverity());
55+
56+
record = grouped.get("Utils.java").get(0);
57+
assertEquals("warning", record.getSeverity());
58+
}
59+
}
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
<checkstyle>
2+
<file name="Main.java">
3+
<error line="10" column="5" severity="error" message="Missing javadoc" source="com.puppycrawl.Check"/>
4+
<error line="20" column="2" severity="error" message="Indentation" source="com.puppycrawl.Indent"/>
5+
</file>
6+
<file name="Utils.java">
7+
<error line="15" column="1" severity="warning" message="Unused import" source="com.puppycrawl.Import"/>
8+
</file>
9+
</checkstyle>
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<checkstyle version="8.0">
3+
<file name="Example.java">
4+
<error line="42" column="13" severity="error"
5+
message="Example message"
6+
source="com.puppycrawl.example.Check"/>
7+
</file>
8+
</checkstyle>

0 commit comments

Comments
 (0)