Skip to content

Commit f12c6de

Browse files
author
Thibault Falque
committed
1 parent 5b1a4b2 commit f12c6de

File tree

2 files changed

+168
-170
lines changed

2 files changed

+168
-170
lines changed

src/main/java/fr/univartois/sonargo/coverage/CoverageParser.java

+95-90
Original file line numberDiff line numberDiff line change
@@ -48,105 +48,110 @@
4848

4949
public class CoverageParser implements Parser {
5050

51-
private final Map<String, List<LineCoverage>> coverageByFile = new HashMap<>();
52-
private static final String FILE_NAME_ATTR = "filename";
53-
private static final String LINE_NUMBER_ATTR = "number";
54-
private static final String HITS_ATTR = "hits";
55-
private static final String METHOD_TAG = "method";
56-
private static final String CLASS_TAG = "class";
57-
private static final String LINE_TAG = "line";
58-
private static final Logger LOGGER = Loggers.get(CoverageParser.class);
59-
60-
private final boolean checkDtd;
61-
62-
public CoverageParser(SensorContext context) {
63-
checkDtd = context.settings().getBoolean(GoProperties.DTD_VERIFICATION_KEY);
64-
}
65-
66-
private DocumentBuilder constructDocumentBuilder() throws ParserConfigurationException {
67-
final DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
68-
69-
final DocumentBuilder db = dbf.newDocumentBuilder();
70-
71-
if (!checkDtd) {
72-
db.setEntityResolver((publicId, systemId) -> {
73-
if (systemId.contains("http://cobertura.sourceforge.net/xml/coverage-03.dtd")) {
74-
return new InputSource(new StringReader(""));
75-
} else {
76-
return null;
77-
}
78-
});
51+
private final Map<String, List<LineCoverage>> coverageByFile = new HashMap<>();
52+
private static final String FILE_NAME_ATTR = "filename";
53+
private static final String LINE_NUMBER_ATTR = "number";
54+
private static final String HITS_ATTR = "hits";
55+
private static final String METHOD_TAG = "method";
56+
private static final String CLASS_TAG = "class";
57+
private static final String LINE_TAG = "line";
58+
private static final Logger LOGGER = Loggers.get(CoverageParser.class);
59+
60+
private final boolean checkDtd;
61+
62+
public CoverageParser(SensorContext context) {
63+
checkDtd = context.settings().getBoolean(GoProperties.DTD_VERIFICATION_KEY);
64+
}
65+
66+
private DocumentBuilder constructDocumentBuilder() throws ParserConfigurationException {
67+
final DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
68+
69+
final DocumentBuilder db = dbf.newDocumentBuilder();
70+
71+
if (!checkDtd) {
72+
db.setEntityResolver((publicId, systemId) -> {
73+
if (systemId.contains("http://cobertura.sourceforge.net/xml/coverage-03.dtd")) {
74+
return new InputSource(new StringReader(""));
75+
} else {
76+
return null;
7977
}
80-
81-
return db;
78+
});
8279
}
8380

84-
/**
85-
* {@link http://stackoverflow.com/questions/13786607/normalization-in-dom-parsing-with-java-how-does-it-work}
86-
*
87-
* @param reportPath
88-
* @throws ParserConfigurationException
89-
* @throws SAXException
90-
* @throws IOException
91-
*/
92-
@Override
93-
public void parse(String reportPath) throws ParserConfigurationException, SAXException, IOException {
94-
final DocumentBuilder db = constructDocumentBuilder();
95-
final Document doc = db.parse(new File(reportPath));
96-
97-
doc.getDocumentElement().normalize();
98-
99-
final NodeList classList = doc.getElementsByTagName(CLASS_TAG);
100-
101-
for (int i = 0; i < classList.getLength(); i++) {
102-
final Node nNode = classList.item(i);
103-
if (nNode.getNodeType() == Node.ELEMENT_NODE) {
104-
105-
final Element eElement = (Element) nNode;
106-
final String filepath = eElement.getAttribute(FILE_NAME_ATTR);
107-
LOGGER.debug("filepath from coverage file " + filepath);
108-
parseMethodTag(eElement.getElementsByTagName(METHOD_TAG), getListForFile(filepath));
109-
}
81+
return db;
82+
}
83+
84+
/**
85+
* {@link http://stackoverflow.com/questions/13786607/normalization-in-dom-parsing-with-java-how-does-it-work}
86+
*
87+
* @param reportPath
88+
* @throws ParserConfigurationException
89+
* @throws SAXException
90+
* @throws IOException
91+
*/
92+
@Override
93+
public void parse(String reportPath) throws IOException, ParserConfigurationException {
94+
final DocumentBuilder db = constructDocumentBuilder();
95+
Document doc;
96+
try {
97+
doc = db.parse(new File(reportPath));
98+
doc.getDocumentElement().normalize();
99+
100+
final NodeList classList = doc.getElementsByTagName(CLASS_TAG);
101+
102+
for (int i = 0; i < classList.getLength(); i++) {
103+
final Node nNode = classList.item(i);
104+
if (nNode.getNodeType() == Node.ELEMENT_NODE) {
105+
106+
final Element eElement = (Element) nNode;
107+
final String filepath = eElement.getAttribute(FILE_NAME_ATTR);
108+
LOGGER.debug("filepath from coverage file " + filepath);
109+
parseMethodTag(eElement.getElementsByTagName(METHOD_TAG), getListForFile(filepath));
110110
}
111+
}
111112

113+
} catch (SAXException e) {
114+
LOGGER.error("A SAX error on file " + reportPath, e);
112115
}
113116

114-
public Map<String, List<LineCoverage>> getCoveragePerFile() {
115-
for (Map.Entry<String, List<LineCoverage>> entry : coverageByFile.entrySet()) {
116-
String fileName = entry.getKey();
117-
List<LineCoverage> list = entry.getValue();
118-
LOGGER.debug(list.size() + "line coverage for file " + fileName);
119-
}
120-
return coverageByFile;
121-
}
117+
}
122118

123-
private List<LineCoverage> getListForFile(String filepath) {
124-
List<LineCoverage> list = coverageByFile.get(filepath);
125-
if (list == null) {
126-
list = new ArrayList<>();
127-
coverageByFile.put(filepath, list);
128-
}
129-
return list;
119+
public Map<String, List<LineCoverage>> getCoveragePerFile() {
120+
for (Map.Entry<String, List<LineCoverage>> entry : coverageByFile.entrySet()) {
121+
String fileName = entry.getKey();
122+
List<LineCoverage> list = entry.getValue();
123+
LOGGER.debug(list.size() + "line coverage for file " + fileName);
130124
}
131-
132-
private void parseMethodTag(NodeList methodsList, List<LineCoverage> listOfCoverage) {
133-
for (int j = 0; j < methodsList.getLength(); j++) {
134-
final Node nNode = methodsList.item(j);
135-
if (nNode.getNodeType() == Node.ELEMENT_NODE) {
136-
final Element eElement = (Element) nNode;
137-
parseLineTag(eElement.getElementsByTagName(LINE_TAG), listOfCoverage);
138-
}
139-
}
125+
return coverageByFile;
126+
}
127+
128+
private List<LineCoverage> getListForFile(String filepath) {
129+
List<LineCoverage> list = coverageByFile.get(filepath);
130+
if (list == null) {
131+
list = new ArrayList<>();
132+
coverageByFile.put(filepath, list);
140133
}
141-
142-
private void parseLineTag(NodeList lineList, List<LineCoverage> listOfCoverage) {
143-
for (int j = 0; j < lineList.getLength(); j++) {
144-
final Node nNode = lineList.item(j);
145-
if (nNode.getNodeType() == Node.ELEMENT_NODE) {
146-
final Element eElement = (Element) nNode;
147-
listOfCoverage.add(new LineCoverage(Integer.parseInt(eElement.getAttribute(LINE_NUMBER_ATTR)),
148-
Integer.parseInt(eElement.getAttribute(HITS_ATTR))));
149-
}
150-
}
134+
return list;
135+
}
136+
137+
private void parseMethodTag(NodeList methodsList, List<LineCoverage> listOfCoverage) {
138+
for (int j = 0; j < methodsList.getLength(); j++) {
139+
final Node nNode = methodsList.item(j);
140+
if (nNode.getNodeType() == Node.ELEMENT_NODE) {
141+
final Element eElement = (Element) nNode;
142+
parseLineTag(eElement.getElementsByTagName(LINE_TAG), listOfCoverage);
143+
}
144+
}
145+
}
146+
147+
private void parseLineTag(NodeList lineList, List<LineCoverage> listOfCoverage) {
148+
for (int j = 0; j < lineList.getLength(); j++) {
149+
final Node nNode = lineList.item(j);
150+
if (nNode.getNodeType() == Node.ELEMENT_NODE) {
151+
final Element eElement = (Element) nNode;
152+
listOfCoverage.add(new LineCoverage(Integer.parseInt(eElement.getAttribute(LINE_NUMBER_ATTR)),
153+
Integer.parseInt(eElement.getAttribute(HITS_ATTR))));
154+
}
151155
}
156+
}
152157
}

src/main/java/fr/univartois/sonargo/coverage/CoverageSensor.java

+73-80
Original file line numberDiff line numberDiff line change
@@ -29,10 +29,13 @@
2929
import java.util.Arrays;
3030
import java.util.List;
3131
import java.util.Map;
32+
import java.util.Set;
33+
import java.util.TreeSet;
3234
import java.util.stream.Stream;
3335

3436
import javax.xml.parsers.ParserConfigurationException;
3537

38+
import org.apache.commons.lang3.StringUtils;
3639
import org.sonar.api.CoreProperties;
3740
import org.sonar.api.batch.fs.FilePredicates;
3841
import org.sonar.api.batch.fs.FileSystem;
@@ -42,110 +45,100 @@
4245
import org.sonar.api.batch.sensor.SensorDescriptor;
4346
import org.sonar.api.batch.sensor.coverage.CoverageType;
4447
import org.sonar.api.batch.sensor.coverage.NewCoverage;
45-
import org.sonar.api.internal.apachecommons.lang.StringUtils;
4648
import org.sonar.api.utils.log.Logger;
4749
import org.sonar.api.utils.log.Loggers;
48-
import org.xml.sax.SAXException;
4950

5051
import fr.univartois.sonargo.core.language.GoLanguage;
5152
import fr.univartois.sonargo.core.settings.GoProperties;
5253

5354
public class CoverageSensor implements Sensor {
5455

55-
private static final Logger LOGGER = Loggers.get(CoverageSensor.class);
56+
private static final Logger LOGGER = Loggers.get(CoverageSensor.class);
5657

57-
@Override
58-
public void describe(SensorDescriptor descriptor) {
59-
descriptor.name("Go Coverage").onlyOnFileType(InputFile.Type.MAIN).onlyOnLanguage(GoLanguage.KEY);
60-
}
58+
@Override
59+
public void describe(SensorDescriptor descriptor) {
60+
descriptor.name("Go Coverage").onlyOnFileType(InputFile.Type.MAIN).onlyOnLanguage(GoLanguage.KEY);
61+
}
6162

62-
private List<String> getExcludedPath(SensorContext context) {
63+
private Set<String> getExcludedPath(SensorContext context) {
6364

64-
String globalExcludedPath = context.settings().getString(CoreProperties.GLOBAL_EXCLUSIONS_PROPERTY);
65+
String globalExcludedPath = context.settings().getString(CoreProperties.GLOBAL_EXCLUSIONS_PROPERTY);
6566

66-
List<String> listExcludedPath = Arrays.asList(StringUtils.split(globalExcludedPath, ","));
67+
Set<String> listExcludedPath = new TreeSet<>(Arrays.asList(StringUtils.split(globalExcludedPath, ",")));
6768

68-
return listExcludedPath;
69-
}
69+
return listExcludedPath;
70+
}
7071

71-
private boolean isNotAnExcludedPath(Path p, SensorContext context) {
72-
List<String> listExcludedPath = getExcludedPath(context);
72+
private boolean isNotAnExcludedPath(Path p, SensorContext context) {
73+
return !getExcludedPath(context).contains(p.toFile().getPath());
74+
}
7375

74-
for (String s : listExcludedPath) {
75-
if (s.equals(p.toFile().getPath())) {
76-
return false;
77-
}
78-
}
79-
return true;
76+
public Stream<Path> createStream(SensorContext context) throws IOException {
77+
final String fullPath = context.fileSystem().baseDir().getPath();
8078

81-
}
79+
return Files.walk(Paths.get(fullPath))
80+
.filter(p -> !p.getParent().toString().contains(".git") && !p.getParent().toString().contains(".sonar")
81+
&& !p.getParent().toString().contains(".scannerwork")
82+
&& !p.getFileName().toString().startsWith(".") && isNotAnExcludedPath(p, context));
8283

83-
public Stream<Path> createStream(SensorContext context) throws IOException {
84-
final String fullPath = context.fileSystem().baseDir().getPath();
84+
}
8585

86-
return Files.walk(Paths.get(fullPath))
87-
.filter(p -> !p.getParent().toString().contains(".git") && !p.getParent().toString().contains(".sonar")
88-
&& !p.getParent().toString().contains(".scannerwork")
89-
&& !p.getFileName().toString().startsWith(".") && isNotAnExcludedPath(p, context));
86+
@Override
87+
public void execute(SensorContext context) {
9088

91-
}
89+
try (Stream<Path> paths = createStream(context)) {
90+
paths.forEach(filePath -> {
91+
if (Files.isDirectory(filePath)) {
92+
final String reportPath = context.settings().getString(GoProperties.COVERAGE_REPORT_PATH_KEY);
93+
final File f = new File(filePath + File.separator + reportPath);
94+
if (f.exists()) {
95+
LOGGER.info("Analyse for " + f.getPath());
9296

93-
@Override
94-
public void execute(SensorContext context) {
95-
96-
try (Stream<Path> paths = createStream(context)) {
97-
paths.forEach(filePath -> {
98-
if (Files.isDirectory(filePath)) {
99-
final String reportPath = context.settings().getString(GoProperties.COVERAGE_REPORT_PATH_KEY);
100-
final File f = new File(filePath + File.separator + reportPath);
101-
if (f.exists()) {
102-
LOGGER.info("Analyse for " + f.getPath());
103-
104-
final CoverageParser coverParser = new CoverageParser(context);
105-
106-
try {
107-
coverParser.parse(f.getPath());
108-
save(context, coverParser.getCoveragePerFile());
109-
} catch (ParserConfigurationException | SAXException | IOException e) {
110-
LOGGER.error("Exception: ", e);
111-
}
112-
113-
} else {
114-
LOGGER.info("no coverage file in package " + f.getPath());
115-
}
116-
}
117-
});
118-
} catch (final IOException e) {
119-
LOGGER.error("IO Exception " + context.fileSystem().baseDir().getPath());
120-
}
121-
}
97+
final CoverageParser coverParser = new CoverageParser(context);
12298

123-
public static void save(SensorContext context, Map<String, List<LineCoverage>> coveragePerFile) {
124-
for (Map.Entry<String, List<LineCoverage>> entry : coveragePerFile.entrySet()) {
125-
final String filePath = entry.getKey();
126-
final List<LineCoverage> lines = entry.getValue();
127-
final FileSystem fileSystem = context.fileSystem();
128-
final FilePredicates predicates = fileSystem.predicates();
129-
final InputFile inputFile = fileSystem.inputFile(
130-
predicates.or(predicates.hasRelativePath(filePath), predicates.hasAbsolutePath(filePath)));
131-
132-
if (inputFile == null) {
133-
LOGGER.warn("unable to create InputFile object: " + filePath);
134-
return;
99+
try {
100+
coverParser.parse(f.getPath());
101+
save(context, coverParser.getCoveragePerFile());
102+
} catch (ParserConfigurationException | IOException e) {
103+
LOGGER.error("Exception: ", e);
135104
}
136105

137-
final NewCoverage coverage = context.newCoverage().onFile(inputFile);
138-
139-
for (final LineCoverage line : lines) {
140-
try {
141-
coverage.lineHits(line.getLineNumber(), line.getHits());
142-
} catch (final Exception ex) {
143-
LOGGER.error(ex.getMessage() + line);
144-
}
145-
}
146-
coverage.ofType(CoverageType.UNIT);
147-
coverage.save();
106+
} else {
107+
LOGGER.info("no coverage file in package " + f.getPath());
108+
}
109+
}
110+
});
111+
} catch (final IOException e) {
112+
LOGGER.error("IO Exception " + context.fileSystem().baseDir().getPath());
113+
}
114+
}
115+
116+
public static void save(SensorContext context, Map<String, List<LineCoverage>> coveragePerFile) {
117+
for (Map.Entry<String, List<LineCoverage>> entry : coveragePerFile.entrySet()) {
118+
final String filePath = entry.getKey();
119+
final List<LineCoverage> lines = entry.getValue();
120+
final FileSystem fileSystem = context.fileSystem();
121+
final FilePredicates predicates = fileSystem.predicates();
122+
final InputFile inputFile = fileSystem.inputFile(
123+
predicates.or(predicates.hasRelativePath(filePath), predicates.hasAbsolutePath(filePath)));
124+
125+
if (inputFile == null) {
126+
LOGGER.warn("unable to create InputFile object: " + filePath);
127+
return;
128+
}
129+
130+
final NewCoverage coverage = context.newCoverage().onFile(inputFile);
131+
132+
for (final LineCoverage line : lines) {
133+
try {
134+
coverage.lineHits(line.getLineNumber(), line.getHits());
135+
} catch (final Exception ex) {
136+
LOGGER.error(ex.getMessage() + line);
148137
}
138+
}
139+
coverage.ofType(CoverageType.UNIT);
140+
coverage.save();
149141
}
142+
}
150143

151144
}

0 commit comments

Comments
 (0)