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.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
046 private int totalCoveredLines = 0, totalConditions = 0, totalCoveredConditions = 0;
047 private SortedMap<Integer, Integer> hitsByLine = Maps.newTreeMap();
048 private SortedMap<Integer, Integer> conditionsByLine = Maps.newTreeMap();
049 private SortedMap<Integer, Integer> coveredConditionsByLine = Maps.newTreeMap();
050
051 private CoverageMeasuresBuilder() {
052 // use the factory
053 }
054
055 public CoverageMeasuresBuilder reset() {
056 totalCoveredLines = 0;
057 totalConditions = 0;
058 totalCoveredConditions = 0;
059 hitsByLine.clear();
060 conditionsByLine.clear();
061 coveredConditionsByLine.clear();
062 return this;
063 }
064
065 public CoverageMeasuresBuilder setHits(int lineId, int hits) {
066 if (!hitsByLine.containsKey(lineId)) {
067 hitsByLine.put(lineId, hits);
068 if (hits > 0) {
069 totalCoveredLines += 1;
070 }
071 }
072 return this;
073 }
074
075 public CoverageMeasuresBuilder setConditions(int lineId, int conditions, int coveredConditions) {
076 if (conditions > 0 && !conditionsByLine.containsKey(lineId)) {
077 totalConditions += conditions;
078 totalCoveredConditions += coveredConditions;
079 conditionsByLine.put(lineId, conditions);
080 coveredConditionsByLine.put(lineId, coveredConditions);
081 }
082 return this;
083 }
084
085 public int getCoveredLines() {
086 return totalCoveredLines;
087 }
088
089 public int getLinesToCover() {
090 return hitsByLine.size();
091 }
092
093 public int getConditions() {
094 return totalConditions;
095 }
096
097 public int getCoveredConditions() {
098 return totalCoveredConditions;
099 }
100
101 public SortedMap<Integer, Integer> getHitsByLine() {
102 return Collections.unmodifiableSortedMap(hitsByLine);
103 }
104
105 public SortedMap<Integer, Integer> getConditionsByLine() {
106 return Collections.unmodifiableSortedMap(conditionsByLine);
107 }
108
109 public SortedMap<Integer, Integer> getCoveredConditionsByLine() {
110 return Collections.unmodifiableSortedMap(coveredConditionsByLine);
111 }
112
113 public Collection<Measure> createMeasures() {
114 Collection<Measure> measures = Lists.newArrayList();
115 if (getLinesToCover() > 0) {
116 measures.add(new Measure(CoreMetrics.LINES_TO_COVER, (double) getLinesToCover()));
117 measures.add(new Measure(CoreMetrics.UNCOVERED_LINES, (double) (getLinesToCover() - getCoveredLines())));
118 measures.add(new Measure(CoreMetrics.COVERAGE_LINE_HITS_DATA).setData(KeyValueFormat.format(hitsByLine)).setPersistenceMode(PersistenceMode.DATABASE));
119 }
120 if (getConditions() > 0) {
121 measures.add(new Measure(CoreMetrics.CONDITIONS_TO_COVER, (double) getConditions()));
122 measures.add(new Measure(CoreMetrics.UNCOVERED_CONDITIONS, (double) (getConditions() - getCoveredConditions())));
123 measures.add(createConditionsByLine());
124 measures.add(createCoveredConditionsByLine());
125 }
126 return measures;
127 }
128
129 private Measure createCoveredConditionsByLine() {
130 return new Measure(CoreMetrics.COVERED_CONDITIONS_BY_LINE)
131 .setData(KeyValueFormat.format(coveredConditionsByLine))
132 .setPersistenceMode(PersistenceMode.DATABASE);
133 }
134
135 private Measure createConditionsByLine() {
136 return new Measure(CoreMetrics.CONDITIONS_BY_LINE)
137 .setData(KeyValueFormat.format(conditionsByLine))
138 .setPersistenceMode(PersistenceMode.DATABASE);
139 }
140
141 public static CoverageMeasuresBuilder create() {
142 return new CoverageMeasuresBuilder();
143 }
144 }