001 /*
002 * SonarQube, open source software quality management tool.
003 * Copyright (C) 2008-2014 SonarSource
004 * mailto:contact AT sonarsource DOT com
005 *
006 * SonarQube is free software; you can redistribute it and/or
007 * modify it under the terms of the GNU Lesser General Public
008 * License as published by the Free Software Foundation; either
009 * version 3 of the License, or (at your option) any later version.
010 *
011 * SonarQube is distributed in the hope that it will be useful,
012 * but WITHOUT ANY WARRANTY; without even the implied warranty of
013 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
014 * Lesser General Public License for more details.
015 *
016 * You should have received a copy of the GNU Lesser General Public License
017 * along with this program; if not, write to the Free Software Foundation,
018 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
019 */
020 package org.sonar.api.measures;
021
022 import com.google.common.collect.Lists;
023 import com.google.common.collect.Maps;
024 import org.sonar.api.utils.KeyValueFormat;
025
026 import java.util.Arrays;
027 import java.util.Collection;
028 import java.util.Collections;
029 import java.util.List;
030 import java.util.SortedMap;
031
032 /**
033 * @since 2.7
034 */
035 public final class CoverageMeasuresBuilder {
036
037 /**
038 * Metrics of generated measures
039 */
040 public static final List<Metric> METRICS = Arrays.<Metric>asList(
041 CoreMetrics.LINES_TO_COVER, CoreMetrics.UNCOVERED_LINES, CoreMetrics.COVERAGE_LINE_HITS_DATA,
042 CoreMetrics.CONDITIONS_TO_COVER, CoreMetrics.UNCOVERED_CONDITIONS, CoreMetrics.CONDITIONS_BY_LINE,
043 CoreMetrics.COVERED_CONDITIONS_BY_LINE);
044
045 private int totalCoveredLines = 0, totalConditions = 0, totalCoveredConditions = 0;
046 private SortedMap<Integer, Integer> hitsByLine = Maps.newTreeMap();
047 private SortedMap<Integer, Integer> conditionsByLine = Maps.newTreeMap();
048 private SortedMap<Integer, Integer> coveredConditionsByLine = Maps.newTreeMap();
049
050 private CoverageMeasuresBuilder() {
051 // use the factory
052 }
053
054 public CoverageMeasuresBuilder reset() {
055 totalCoveredLines = 0;
056 totalConditions = 0;
057 totalCoveredConditions = 0;
058 hitsByLine.clear();
059 conditionsByLine.clear();
060 coveredConditionsByLine.clear();
061 return this;
062 }
063
064 public CoverageMeasuresBuilder setHits(int lineId, int hits) {
065 if (!hitsByLine.containsKey(lineId)) {
066 hitsByLine.put(lineId, hits);
067 if (hits > 0) {
068 totalCoveredLines += 1;
069 }
070 }
071 return this;
072 }
073
074 public CoverageMeasuresBuilder setConditions(int lineId, int conditions, int coveredConditions) {
075 if (conditions > 0 && !conditionsByLine.containsKey(lineId)) {
076 totalConditions += conditions;
077 totalCoveredConditions += coveredConditions;
078 conditionsByLine.put(lineId, conditions);
079 coveredConditionsByLine.put(lineId, coveredConditions);
080 }
081 return this;
082 }
083
084 public int getCoveredLines() {
085 return totalCoveredLines;
086 }
087
088 public int getLinesToCover() {
089 return hitsByLine.size();
090 }
091
092 public int getConditions() {
093 return totalConditions;
094 }
095
096 public int getCoveredConditions() {
097 return totalCoveredConditions;
098 }
099
100 public SortedMap<Integer, Integer> getHitsByLine() {
101 return Collections.unmodifiableSortedMap(hitsByLine);
102 }
103
104 public SortedMap<Integer, Integer> getConditionsByLine() {
105 return Collections.unmodifiableSortedMap(conditionsByLine);
106 }
107
108 public SortedMap<Integer, Integer> getCoveredConditionsByLine() {
109 return Collections.unmodifiableSortedMap(coveredConditionsByLine);
110 }
111
112 public Collection<Measure> createMeasures() {
113 Collection<Measure> measures = Lists.newArrayList();
114 if (getLinesToCover() > 0) {
115 measures.add(new Measure(CoreMetrics.LINES_TO_COVER, (double) getLinesToCover()));
116 measures.add(new Measure(CoreMetrics.UNCOVERED_LINES, (double) (getLinesToCover() - getCoveredLines())));
117 measures.add(new Measure(CoreMetrics.COVERAGE_LINE_HITS_DATA).setData(KeyValueFormat.format(hitsByLine)).setPersistenceMode(PersistenceMode.DATABASE));
118 }
119 if (getConditions() > 0) {
120 measures.add(new Measure(CoreMetrics.CONDITIONS_TO_COVER, (double) getConditions()));
121 measures.add(new Measure(CoreMetrics.UNCOVERED_CONDITIONS, (double) (getConditions() - getCoveredConditions())));
122 measures.add(createConditionsByLine());
123 measures.add(createCoveredConditionsByLine());
124 }
125 return measures;
126 }
127
128 private Measure createCoveredConditionsByLine() {
129 return new Measure(CoreMetrics.COVERED_CONDITIONS_BY_LINE)
130 .setData(KeyValueFormat.format(coveredConditionsByLine))
131 .setPersistenceMode(PersistenceMode.DATABASE);
132 }
133
134 private Measure createConditionsByLine() {
135 return new Measure(CoreMetrics.CONDITIONS_BY_LINE)
136 .setData(KeyValueFormat.format(conditionsByLine))
137 .setPersistenceMode(PersistenceMode.DATABASE);
138 }
139
140 public static CoverageMeasuresBuilder create() {
141 return new CoverageMeasuresBuilder();
142 }
143 }