From ad2c860250027451067bf4999c9886adfef01ba1 Mon Sep 17 00:00:00 2001 From: Godin Date: Sun, 17 Oct 2010 00:41:51 +0000 Subject: [PATCH] SONAR-1808: Extract AbstractCoberturaParser from CoberturaSensor. --- .../cobertura/AbstractCoberturaParser.java | 156 ++++++++++++++++++ .../plugins/cobertura/CoberturaSensor.java | 151 +---------------- 2 files changed, 163 insertions(+), 144 deletions(-) create mode 100644 plugins/sonar-cobertura-plugin/src/main/java/org/sonar/plugins/cobertura/AbstractCoberturaParser.java diff --git a/plugins/sonar-cobertura-plugin/src/main/java/org/sonar/plugins/cobertura/AbstractCoberturaParser.java b/plugins/sonar-cobertura-plugin/src/main/java/org/sonar/plugins/cobertura/AbstractCoberturaParser.java new file mode 100644 index 00000000000..a163b0e5cf0 --- /dev/null +++ b/plugins/sonar-cobertura-plugin/src/main/java/org/sonar/plugins/cobertura/AbstractCoberturaParser.java @@ -0,0 +1,156 @@ +package org.sonar.plugins.cobertura; + +import static java.util.Locale.ENGLISH; +import static org.sonar.api.utils.ParsingUtils.parseNumber; +import static org.sonar.api.utils.ParsingUtils.scaleValue; + +import org.apache.commons.io.FilenameUtils; +import org.apache.commons.lang.StringUtils; +import org.codehaus.staxmate.in.SMHierarchicCursor; +import org.codehaus.staxmate.in.SMInputCursor; +import org.sonar.api.batch.SensorContext; +import org.sonar.api.measures.CoreMetrics; +import org.sonar.api.measures.Measure; +import org.sonar.api.measures.PersistenceMode; +import org.sonar.api.measures.PropertiesBuilder; +import org.sonar.api.resources.Resource; +import org.sonar.api.utils.StaxParser; +import org.sonar.api.utils.XmlParserException; + +import java.io.File; +import java.text.ParseException; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import javax.xml.stream.XMLStreamException; + +public abstract class AbstractCoberturaParser { + public void parseReport(File xmlFile, final SensorContext context) { + try { + StaxParser parser = new StaxParser(new StaxParser.XmlStreamHandler() { + + public void stream(SMHierarchicCursor rootCursor) throws XMLStreamException { + try { + rootCursor.advance(); + collectPackageMeasures(rootCursor.descendantElementCursor("package"), context); + } catch (ParseException e) { + throw new XMLStreamException(e); + } + } + }); + parser.parse(xmlFile); + } catch (XMLStreamException e) { + throw new XmlParserException(e); + } + } + + private void collectPackageMeasures(SMInputCursor pack, SensorContext context) throws ParseException, XMLStreamException { + while (pack.getNext() != null) { + Map fileDataPerFilename = new HashMap(); + collectFileMeasures(pack.descendantElementCursor("class"), fileDataPerFilename); + for (FileData cci : fileDataPerFilename.values()) { + if (isFileExist(context, cci.getFile())) { + for (Measure measure : cci.getMeasures()) { + context.saveMeasure(cci.getFile(), measure); + } + } + } + } + } + + private boolean isFileExist(SensorContext context, Resource file) { + return context.getResource(file) != null; + } + + private void collectFileMeasures(SMInputCursor clazz, Map dataPerFilename) throws ParseException, XMLStreamException { + while (clazz.getNext() != null) { + String fileName = FilenameUtils.removeExtension(clazz.getAttrValue("filename")); + fileName = fileName.replace('/', '.').replace('\\', '.'); + FileData data = dataPerFilename.get(fileName); + if (data == null) { + data = new FileData(getResource(fileName)); + dataPerFilename.put(fileName, data); + } + collectFileData(clazz, data); + } + } + + private void collectFileData(SMInputCursor clazz, FileData data) throws ParseException, XMLStreamException { + SMInputCursor line = clazz.childElementCursor("lines").advance().childElementCursor("line"); + while (line.getNext() != null) { + String lineId = line.getAttrValue("number"); + data.addLine(lineId, (int) parseNumber(line.getAttrValue("hits"), ENGLISH)); + + String text = line.getAttrValue("condition-coverage"); + if (StringUtils.isNotBlank(text)) { + String[] conditions = StringUtils.split(StringUtils.substringBetween(text, "(", ")"), "/"); + data.addConditionLine(lineId, Integer.parseInt(conditions[0]), Integer.parseInt(conditions[1]), StringUtils.substringBefore(text, " ")); + } + } + } + + private class FileData { + + private int lines = 0; + private int conditions = 0; + private int coveredLines = 0; + private int coveredConditions = 0; + + private Resource file; + private PropertiesBuilder lineHitsBuilder = new PropertiesBuilder(CoreMetrics.COVERAGE_LINE_HITS_DATA); + private PropertiesBuilder branchHitsBuilder = new PropertiesBuilder(CoreMetrics.BRANCH_COVERAGE_HITS_DATA); + + public void addLine(String lineId, int lineHits) { + lines++; + if (lineHits > 0) { + coveredLines++; + } + lineHitsBuilder.add(lineId, lineHits); + } + + public void addConditionLine(String lineId, int coveredConditions, int conditions, String label) { + this.conditions += conditions; + this.coveredConditions += coveredConditions; + branchHitsBuilder.add(lineId, label); + } + + public FileData(Resource file) { + this.file = file; + } + + public List getMeasures() { + List measures = new ArrayList(); + if (lines > 0) { + measures.add(new Measure(CoreMetrics.COVERAGE, calculateCoverage(coveredLines + coveredConditions, lines + conditions))); + + measures.add(new Measure(CoreMetrics.LINE_COVERAGE, calculateCoverage(coveredLines, lines))); + measures.add(new Measure(CoreMetrics.LINES_TO_COVER, (double) lines)); + measures.add(new Measure(CoreMetrics.UNCOVERED_LINES, (double) lines - coveredLines)); + measures.add(lineHitsBuilder.build().setPersistenceMode(PersistenceMode.DATABASE)); + + if (conditions > 0) { + measures.add(new Measure(CoreMetrics.BRANCH_COVERAGE, calculateCoverage(coveredConditions, conditions))); + measures.add(new Measure(CoreMetrics.CONDITIONS_TO_COVER, (double) conditions)); + measures.add(new Measure(CoreMetrics.UNCOVERED_CONDITIONS, (double) conditions - coveredConditions)); + measures.add(branchHitsBuilder.build().setPersistenceMode(PersistenceMode.DATABASE)); + } + } + return measures; + } + + public Resource getFile() { + return file; + } + } + + private double calculateCoverage(int coveredElements, int elements) { + if (elements > 0) { + return scaleValue(100.0 * ((double) coveredElements / (double) elements)); + } + return 0.0; + } + + protected abstract Resource getResource(String fileName); +} diff --git a/plugins/sonar-cobertura-plugin/src/main/java/org/sonar/plugins/cobertura/CoberturaSensor.java b/plugins/sonar-cobertura-plugin/src/main/java/org/sonar/plugins/cobertura/CoberturaSensor.java index 9443de91b15..73a7caff123 100644 --- a/plugins/sonar-cobertura-plugin/src/main/java/org/sonar/plugins/cobertura/CoberturaSensor.java +++ b/plugins/sonar-cobertura-plugin/src/main/java/org/sonar/plugins/cobertura/CoberturaSensor.java @@ -19,10 +19,6 @@ */ package org.sonar.plugins.cobertura; -import org.apache.commons.io.FilenameUtils; -import org.apache.commons.lang.StringUtils; -import org.codehaus.staxmate.in.SMHierarchicCursor; -import org.codehaus.staxmate.in.SMInputCursor; import org.slf4j.LoggerFactory; import org.sonar.api.CoreProperties; import org.sonar.api.batch.AbstractCoverageExtension; @@ -31,26 +27,11 @@ import org.sonar.api.batch.SensorContext; import org.sonar.api.batch.maven.DependsUponMavenPlugin; import org.sonar.api.batch.maven.MavenPlugin; import org.sonar.api.batch.maven.MavenPluginHandler; -import org.sonar.api.measures.CoreMetrics; -import org.sonar.api.measures.Measure; -import org.sonar.api.measures.PersistenceMode; -import org.sonar.api.measures.PropertiesBuilder; import org.sonar.api.resources.JavaFile; import org.sonar.api.resources.Project; -import org.sonar.api.utils.StaxParser; -import org.sonar.api.utils.XmlParserException; +import org.sonar.api.resources.Resource; -import javax.xml.stream.XMLStreamException; import java.io.File; -import java.text.ParseException; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -import static java.util.Locale.ENGLISH; -import static org.sonar.api.utils.ParsingUtils.parseNumber; -import static org.sonar.api.utils.ParsingUtils.scaleValue; public class CoberturaSensor extends AbstractCoverageExtension implements Sensor, DependsUponMavenPlugin { @@ -120,135 +101,17 @@ public class CoberturaSensor extends AbstractCoverageExtension implements Sensor } protected void parseReport(File xmlFile, final SensorContext context) { - try { - LoggerFactory.getLogger(CoberturaSensor.class).info("parsing {}", xmlFile); - StaxParser parser = new StaxParser(new StaxParser.XmlStreamHandler() { - - public void stream(SMHierarchicCursor rootCursor) throws XMLStreamException { - try { - rootCursor.advance(); - collectPackageMeasures(rootCursor.descendantElementCursor("package"), context); - } catch (ParseException e) { - throw new XMLStreamException(e); - } - } - }); - parser.parse(xmlFile); - } catch (XMLStreamException e) { - throw new XmlParserException(e); - } - } - - private void collectPackageMeasures(SMInputCursor pack, SensorContext context) throws ParseException, XMLStreamException { - while (pack.getNext() != null) { - Map fileDataPerFilename = new HashMap(); - collectFileMeasures(pack.descendantElementCursor("class"), fileDataPerFilename); - for (FileData cci : fileDataPerFilename.values()) { - if (javaFileExist(context, cci.getJavaFile())) { - for (Measure measure : cci.getMeasures()) { - context.saveMeasure(cci.getJavaFile(), measure); - } - } - } - } - } - - private boolean javaFileExist(SensorContext context, JavaFile javaFile) { - return context.getResource(javaFile) != null; - } - - private void collectFileMeasures(SMInputCursor clazz, Map dataPerFilename) throws ParseException, XMLStreamException { - while (clazz.getNext() != null) { - String fileName = FilenameUtils.removeExtension(clazz.getAttrValue("filename")); - fileName = fileName.replace('/', '.').replace('\\', '.'); - FileData data = dataPerFilename.get(fileName); - if (data == null) { - data = new FileData(new JavaFile(fileName)); - dataPerFilename.put(fileName, data); - } - collectFileData(clazz, data); - } - } - - private void collectFileData(SMInputCursor clazz, FileData data) throws ParseException, XMLStreamException { - SMInputCursor line = clazz.childElementCursor("lines").advance().childElementCursor("line"); - while (line.getNext() != null) { - String lineId = line.getAttrValue("number"); - data.addLine(lineId, (int) parseNumber(line.getAttrValue("hits"), ENGLISH)); - - String text = line.getAttrValue("condition-coverage"); - if (StringUtils.isNotBlank(text)) { - String[] conditions = StringUtils.split(StringUtils.substringBetween(text, "(", ")"), "/"); - data.addConditionLine(lineId, Integer.parseInt(conditions[0]), Integer.parseInt(conditions[1]), StringUtils.substringBefore(text, - " ")); - } - } - } - - private class FileData { - - private int lines = 0; - private int conditions = 0; - private int coveredLines = 0; - private int coveredConditions = 0; - - private JavaFile javaFile; - private PropertiesBuilder lineHitsBuilder = new PropertiesBuilder(CoreMetrics.COVERAGE_LINE_HITS_DATA); - private PropertiesBuilder branchHitsBuilder = new PropertiesBuilder( - CoreMetrics.BRANCH_COVERAGE_HITS_DATA); - - public void addLine(String lineId, int lineHits) { - lines++; - if (lineHits > 0) { - coveredLines++; + LoggerFactory.getLogger(CoberturaSensor.class).info("parsing {}", xmlFile); + new AbstractCoberturaParser() { + @Override + protected Resource getResource(String fileName) { + return new JavaFile(fileName); } - lineHitsBuilder.add(lineId, lineHits); - } - - public void addConditionLine(String lineId, int coveredConditions, int conditions, String label) { - this.conditions += conditions; - this.coveredConditions += coveredConditions; - branchHitsBuilder.add(lineId, label); - } - - public FileData(JavaFile javaFile) { - this.javaFile = javaFile; - } - - public List getMeasures() { - List measures = new ArrayList(); - if (lines > 0) { - measures.add(new Measure(CoreMetrics.COVERAGE, calculateCoverage(coveredLines + coveredConditions, lines + conditions))); - - measures.add(new Measure(CoreMetrics.LINE_COVERAGE, calculateCoverage(coveredLines, lines))); - measures.add(new Measure(CoreMetrics.LINES_TO_COVER, (double) lines)); - measures.add(new Measure(CoreMetrics.UNCOVERED_LINES, (double) lines - coveredLines)); - measures.add(lineHitsBuilder.build().setPersistenceMode(PersistenceMode.DATABASE)); - - if (conditions > 0) { - measures.add(new Measure(CoreMetrics.BRANCH_COVERAGE, calculateCoverage(coveredConditions, conditions))); - measures.add(new Measure(CoreMetrics.CONDITIONS_TO_COVER, (double) conditions)); - measures.add(new Measure(CoreMetrics.UNCOVERED_CONDITIONS, (double) conditions - coveredConditions)); - measures.add(branchHitsBuilder.build().setPersistenceMode(PersistenceMode.DATABASE)); - } - } - return measures; - } - - public JavaFile getJavaFile() { - return javaFile; - } + }; } @Override public String toString() { return getClass().getSimpleName(); } - - private double calculateCoverage(int coveredElements, int elements) { - if (elements > 0) { - return scaleValue(100.0 * ((double) coveredElements / (double) elements)); - } - return 0.0; - } } -- 2.39.5