From: simonbrandhof Date: Wed, 1 Dec 2010 22:09:09 +0000 (+0000) Subject: SONAR-249 save configuration used for measure variations and new violations in the... X-Git-Tag: 2.6~458 X-Git-Url: https://source.dussan.org/?a=commitdiff_plain;h=473065f87a746470a2d9c431155db0584805b95b;p=sonarqube.git SONAR-249 save configuration used for measure variations and new violations in the table SNAPSHOTS --- diff --git a/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/CorePlugin.java b/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/CorePlugin.java index f1e767eec96..27da9438c3b 100644 --- a/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/CorePlugin.java +++ b/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/CorePlugin.java @@ -19,7 +19,7 @@ */ package org.sonar.plugins.core; -import org.sonar.plugins.core.timemachine.NewViolationsDecorator; +import org.sonar.plugins.core.timemachine.*; import com.google.common.collect.Lists; import org.sonar.api.CoreProperties; @@ -42,10 +42,6 @@ import org.sonar.plugins.core.metrics.UserManagedMetrics; import org.sonar.plugins.core.security.ApplyProjectRolesDecorator; import org.sonar.plugins.core.sensors.*; import org.sonar.plugins.core.testdetailsviewer.TestsViewerDefinition; -import org.sonar.plugins.core.timemachine.VariationDecorator; -import org.sonar.plugins.core.timemachine.PeriodLocator; -import org.sonar.plugins.core.timemachine.TendencyDecorator; -import org.sonar.plugins.core.timemachine.TimeMachineConfiguration; import org.sonar.plugins.core.ui.pageselector.GwtPageSelector; import org.sonar.plugins.core.violationsviewer.ViolationsViewerDefinition; import org.sonar.plugins.core.widgets.*; @@ -117,6 +113,27 @@ import java.util.List; description = "Any new users will automatically join this group.", project = false, global = true + ), + @Property( + key = "sonar.timemachine.variation1", + name = "Variation 1", + description = "To be defined. For the moment the number of days", + project = false, + global = true + ), + @Property( + key = "sonar.timemachine.variation2", + name = "Variation 2", + description = "To be defined. For the moment the number of days", + project = false, + global = true + ), + @Property( + key = "sonar.timemachine.variation3", + name = "Variation 3", + description = "To be defined. For the moment the number of days", + project = false, + global = true ) }) public class CorePlugin implements Plugin { @@ -197,9 +214,10 @@ public class CorePlugin implements Plugin { // time machine extensions.add(TendencyDecorator.class); extensions.add(PeriodLocator.class); + extensions.add(PastMeasuresLoader.class); + extensions.add(TimeMachineConfiguration.class); extensions.add(VariationDecorator.class); extensions.add(NewViolationsDecorator.class); - extensions.add(TimeMachineConfiguration.class); return extensions; } diff --git a/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/timemachine/NewViolationsDecorator.java b/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/timemachine/NewViolationsDecorator.java index d64935cf3a3..1c1eab8638c 100644 --- a/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/timemachine/NewViolationsDecorator.java +++ b/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/timemachine/NewViolationsDecorator.java @@ -19,22 +19,18 @@ */ package org.sonar.plugins.core.timemachine; -import org.apache.commons.lang.time.DateUtils; -import org.sonar.api.batch.Decorator; -import org.sonar.api.batch.DecoratorBarriers; -import org.sonar.api.batch.DecoratorContext; -import org.sonar.api.batch.DependedUpon; +import org.sonar.api.batch.*; import org.sonar.api.measures.CoreMetrics; import org.sonar.api.measures.Measure; import org.sonar.api.measures.Metric; import org.sonar.api.resources.Project; import org.sonar.api.resources.Resource; import org.sonar.api.rules.Violation; -import org.sonar.api.utils.SonarException; import java.util.Date; +import java.util.List; -@DependedUpon(DecoratorBarriers.END_OF_VIOLATIONS_GENERATION) +@DependsUpon(DecoratorBarriers.END_OF_VIOLATIONS_GENERATION) public class NewViolationsDecorator implements Decorator { private TimeMachineConfiguration timeMachineConfiguration; @@ -44,7 +40,7 @@ public class NewViolationsDecorator implements Decorator { } public boolean shouldExecuteOnProject(Project project) { - return true; + return project.isLatestAnalysis(); } @DependedUpon @@ -54,20 +50,17 @@ public class NewViolationsDecorator implements Decorator { public void decorate(Resource resource, DecoratorContext context) { Measure measure = new Measure(CoreMetrics.NEW_VIOLATIONS); - for (int index = 0; index < 3; index++) { - Integer days = timeMachineConfiguration.getDiffPeriodInDays(index); - if (days != null) { - double value = calculate(context, days) + sumChildren(context, index); - setDiffValue(measure, index, value); - } + for (VariationTarget variationTarget : timeMachineConfiguration.getVariationTargets()) { + Date date = variationTarget.getDate(); + double value = countViolationsAfterDate(context.getViolations(), date) + sumChildren(context, variationTarget.getIndex()); + measure.setVariation(variationTarget.getIndex(), value); } context.saveMeasure(measure); } - int calculate(DecoratorContext context, int days) { - Date targetDate = getTargetDate(context.getProject(), days); + int countViolationsAfterDate(List violations, Date targetDate) { int newViolations = 0; - for (Violation violation : context.getViolations()) { + for (Violation violation : violations) { if (!violation.getCreatedAt().before(targetDate)) { newViolations++; } @@ -75,46 +68,17 @@ public class NewViolationsDecorator implements Decorator { return newViolations; } - double sumChildren(DecoratorContext context, int index) { - double sum = 0; + int sumChildren(DecoratorContext context, int index) { + int sum = 0; for (Measure measure : context.getChildrenMeasures(CoreMetrics.NEW_VIOLATIONS)) { - sum = sum + getDiffValue(measure, index); + Double var = measure.getVariation(index); + if (var != null) { + sum = sum + var.intValue(); + } } return sum; } - private Date getTargetDate(Project project, int distanceInDays) { - return DateUtils.addDays(project.getAnalysisDate(), -distanceInDays); - } - - private void setDiffValue(Measure measure, int index, double value) { - switch (index) { - case 0: - measure.setDiffValue1(value); - break; - case 1: - measure.setDiffValue2(value); - break; - case 2: - measure.setDiffValue3(value); - break; - default: - throw new SonarException("Should never happen"); - } - } - - private double getDiffValue(Measure measure, int index) { - switch (index) { - case 0: - return measure.getDiffValue1(); - case 1: - return measure.getDiffValue2(); - case 2: - return measure.getDiffValue3(); - default: - throw new SonarException("Should never happen"); - } - } @Override public String toString() { diff --git a/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/timemachine/PastMeasuresLoader.java b/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/timemachine/PastMeasuresLoader.java new file mode 100644 index 00000000000..be7fcfe30b1 --- /dev/null +++ b/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/timemachine/PastMeasuresLoader.java @@ -0,0 +1,77 @@ +/* + * Sonar, open source software quality management tool. + * Copyright (C) 2009 SonarSource SA + * mailto:contact AT sonarsource DOT com + * + * Sonar is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * Sonar is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with Sonar; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02 + */ +package org.sonar.plugins.core.timemachine; + +import com.google.common.collect.Maps; +import org.apache.commons.lang.ObjectUtils; +import org.sonar.api.BatchExtension; +import org.sonar.api.database.DatabaseSession; +import org.sonar.api.database.model.MeasureModel; +import org.sonar.api.database.model.Snapshot; +import org.sonar.api.measures.Metric; +import org.sonar.api.measures.MetricFinder; +import org.sonar.api.resources.Resource; + +import java.util.Collection; +import java.util.List; +import java.util.Map; + +public class PastMeasuresLoader implements BatchExtension { + + private Map metricByIds; + private DatabaseSession session; + + public PastMeasuresLoader(DatabaseSession session, MetricFinder metricFinder) { + this(session, metricFinder.findAll()); + } + + PastMeasuresLoader(DatabaseSession session, Collection metrics) { + this.session = session; + this.metricByIds = Maps.newHashMap(); + for (Metric metric : metrics) { + if (metric.isNumericType()) { + metricByIds.put(metric.getId(), metric); + } + } + } + + public Collection getMetrics() { + return metricByIds.values(); + } + + public List getPastMeasures(Resource resource, Snapshot projectSnapshot) { + // assume that the resource has already been saved + return getPastMeasures(resource.getId(), projectSnapshot); + } + + public List getPastMeasures(int resourceId, Snapshot projectSnapshot) { + // TODO improvement : select only some columns + // TODO support measure on characteristics + String hql = "select m from " + MeasureModel.class.getSimpleName() + " m, " + Snapshot.class.getSimpleName() + " s " + + "where m.snapshotId=s.id and m.metricId in (:metricIds) and m.ruleId=null and m.rulePriority=null and m.characteristic=null " + + "and (s.rootId=:rootSnapshotId or s.id=:rootSnapshotId) and s.resourceId=:resourceId and s.status=:status"; + return session.createQuery(hql) + .setParameter("metricIds", metricByIds.keySet()) + .setParameter("rootSnapshotId", ObjectUtils.defaultIfNull(projectSnapshot.getRootId(), projectSnapshot.getId())) + .setParameter("resourceId", resourceId) + .setParameter("status", Snapshot.STATUS_PROCESSED) + .getResultList(); + } +} diff --git a/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/timemachine/PeriodLocator.java b/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/timemachine/PeriodLocator.java index ef1acbcbf22..5acf136782f 100644 --- a/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/timemachine/PeriodLocator.java +++ b/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/timemachine/PeriodLocator.java @@ -19,7 +19,6 @@ */ package org.sonar.plugins.core.timemachine; -import org.apache.commons.lang.StringUtils; import org.apache.commons.lang.time.DateUtils; import org.sonar.api.BatchExtension; import org.sonar.api.database.DatabaseSession; @@ -28,7 +27,7 @@ import org.sonar.api.database.model.Snapshot; import java.util.Date; import java.util.List; -public final class PeriodLocator implements BatchExtension { +public class PeriodLocator implements BatchExtension { private Snapshot projectSnapshot; // TODO replace by PersistenceManager private DatabaseSession session; @@ -37,11 +36,6 @@ public final class PeriodLocator implements BatchExtension { this.session = session; } - // currently not used - boolean acceptProperty(String property) { - return doAcceptProperty(property); - } - Snapshot locate(int days) { List snapshots = loadSnapshotsFromDatabase(); return getNearestToTarget(snapshots, projectSnapshot.getCreatedAt(), days); @@ -76,8 +70,4 @@ public final class PeriodLocator implements BatchExtension { static long distance(Date d1, Date d2) { return Math.abs(d1.getTime() - d2.getTime()); } - - static Boolean doAcceptProperty(String property) { - return StringUtils.trimToEmpty(property).matches("[0-9]+d"); - } } diff --git a/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/timemachine/TimeMachineConfiguration.java b/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/timemachine/TimeMachineConfiguration.java index 4e219294a09..a940ce514a7 100644 --- a/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/timemachine/TimeMachineConfiguration.java +++ b/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/timemachine/TimeMachineConfiguration.java @@ -19,36 +19,84 @@ */ package org.sonar.plugins.core.timemachine; +import com.google.common.collect.Lists; import org.apache.commons.configuration.Configuration; +import org.apache.commons.lang.StringUtils; import org.sonar.api.BatchExtension; import org.sonar.api.CoreProperties; +import org.sonar.api.database.DatabaseSession; import org.sonar.api.database.model.Snapshot; +import java.util.List; + public final class TimeMachineConfiguration implements BatchExtension { - private Configuration configuration; - private PeriodLocator periodLocator; + private static final int NUMBER_OF_VARIATION_TARGETS = 3; + + private final Configuration configuration; + private List variationTargets; - public TimeMachineConfiguration(Configuration configuration, PeriodLocator periodLocator) { + public TimeMachineConfiguration(Configuration configuration, DatabaseSession session, PeriodLocator periodLocator) { this.configuration = configuration; - this.periodLocator = periodLocator; + initVariationTargets(periodLocator, session); } - boolean skipTendencies() { - return configuration.getBoolean(CoreProperties.SKIP_TENDENCIES_PROPERTY, CoreProperties.SKIP_TENDENCIES_DEFAULT_VALUE); + /** + * for unit tests + */ + TimeMachineConfiguration(Configuration configuration, List variationTargets) { + this.configuration = configuration; + this.variationTargets = variationTargets; } - int getTendencyPeriodInDays() { - return configuration.getInt(CoreProperties.CORE_TENDENCY_DEPTH_PROPERTY, CoreProperties.CORE_TENDENCY_DEPTH_DEFAULT_VALUE); + private void initVariationTargets(PeriodLocator periodLocator, DatabaseSession session) { + variationTargets = Lists.newLinkedList(); + for (int index = 1; index <= NUMBER_OF_VARIATION_TARGETS; index++) { + VariationTarget target = loadVariationTarget(index, periodLocator); + if (target != null) { + save(target, session); + variationTargets.add(target); + } + } + } + + private void save(VariationTarget target, DatabaseSession session) { + Snapshot projectSnapshot = target.getProjectSnapshot(); + switch (target.getIndex()) { + case 1: + projectSnapshot.setVarMode1("PERIOD_IN_DAYS"); + break; + case 2: + projectSnapshot.setVarMode2("PERIOD_IN_DAYS"); + break; + case 3: + projectSnapshot.setVarMode3("PERIOD_IN_DAYS"); + break; + } + session.save(projectSnapshot); } - Integer getDiffPeriodInDays(int index) { - String property = configuration.getString("sonar.timemachine.diff" + index); - return property == null ? null : Integer.valueOf(property); + private VariationTarget loadVariationTarget(int index, PeriodLocator periodLocator) { + String property = configuration.getString("sonar.timemachine.variation" + index); + if (StringUtils.isNotBlank(property)) { + // todo manage non-integer values + Snapshot projectSnapshot = periodLocator.locate(Integer.parseInt(property)); + if (projectSnapshot != null) { + return new VariationTarget(index, projectSnapshot); + } + } + return null; + } + + public boolean skipTendencies() { + return configuration.getBoolean(CoreProperties.SKIP_TENDENCIES_PROPERTY, CoreProperties.SKIP_TENDENCIES_DEFAULT_VALUE); + } + + public int getTendencyPeriodInDays() { + return configuration.getInt(CoreProperties.CORE_TENDENCY_DEPTH_PROPERTY, CoreProperties.CORE_TENDENCY_DEPTH_DEFAULT_VALUE); } - Snapshot getProjectSnapshotForDiffValues(int index) { - Integer days = getDiffPeriodInDays(index); - return days == null ? null : periodLocator.locate(days); + public List getVariationTargets() { + return variationTargets; } } diff --git a/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/timemachine/VariationDecorator.java b/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/timemachine/VariationDecorator.java index aa656b01db0..08c5e34837a 100644 --- a/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/timemachine/VariationDecorator.java +++ b/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/timemachine/VariationDecorator.java @@ -20,13 +20,12 @@ package org.sonar.plugins.core.timemachine; import com.google.common.collect.Maps; -import org.apache.commons.configuration.Configuration; -import org.apache.commons.lang.ObjectUtils; import org.sonar.api.batch.*; -import org.sonar.api.database.DatabaseSession; import org.sonar.api.database.model.MeasureModel; -import org.sonar.api.database.model.Snapshot; -import org.sonar.api.measures.*; +import org.sonar.api.measures.Measure; +import org.sonar.api.measures.MeasuresFilters; +import org.sonar.api.measures.Metric; +import org.sonar.api.measures.RuleMeasure; import org.sonar.api.qualitymodel.Characteristic; import org.sonar.api.resources.Project; import org.sonar.api.resources.Resource; @@ -40,63 +39,43 @@ import java.util.Map; @DependedUpon(DecoratorBarriers.END_OF_TIME_MACHINE) public class VariationDecorator implements Decorator { - private Snapshot[] projectTargetSnapshots; - private Map metricByIds; - private DatabaseSession session; + private List targets; + private PastMeasuresLoader pastMeasuresLoader; - public VariationDecorator(DatabaseSession session, PeriodLocator periodLocator, Configuration configuration, MetricFinder metricFinder) { - this.session = session; - Snapshot snapshot = periodLocator.locate(5); - projectTargetSnapshots = new Snapshot[]{snapshot}; - initMetrics(metricFinder.findAll()); + public VariationDecorator(PastMeasuresLoader pastMeasuresLoader, TimeMachineConfiguration configuration) { + this(pastMeasuresLoader, configuration.getVariationTargets()); } - /** - * only for unit tests - */ - VariationDecorator(DatabaseSession session, Snapshot[] projectTargetSnapshots, Collection metrics) { - this.session = session; - this.projectTargetSnapshots = projectTargetSnapshots; - initMetrics(metrics); - } - - private void initMetrics(Collection metrics) { - this.metricByIds = Maps.newHashMap(); - for (Metric metric : metrics) { - if (metric.isNumericType()) { - metricByIds.put(metric.getId(), metric); - } - } + VariationDecorator(PastMeasuresLoader pastMeasuresLoader, List targets) { + this.pastMeasuresLoader = pastMeasuresLoader; + this.targets = targets; } public boolean shouldExecuteOnProject(Project project) { - return true; + return project.isLatestAnalysis(); } @DependsUpon public Collection dependsUponMetrics() { - return metricByIds.values(); + return pastMeasuresLoader.getMetrics(); } - static boolean shouldCalculateDiffValues(Resource resource) { - // measures on files are currently purged, so past measures are not available + static boolean shouldCalculateVariations(Resource resource) { + // measures on files are currently purged, so past measures are not available on files return !ResourceUtils.isEntity(resource); } public void decorate(Resource resource, DecoratorContext context) { - if (shouldCalculateDiffValues(resource)) { - for (int index = 0; index < projectTargetSnapshots.length; index++) { - Snapshot projectTargetSnapshot = projectTargetSnapshots[index]; - if (projectTargetSnapshot != null) { - calculateDiffValues(resource, context, index, projectTargetSnapshot); - } + if (shouldCalculateVariations(resource)) { + for (VariationTarget target : targets) { + calculateVariation(resource, context, target); } } } - private void calculateDiffValues(Resource resource, DecoratorContext context, int index, Snapshot projectTargetSnapshot) { - List pastMeasures = selectPastMeasures(resource.getId(), projectTargetSnapshot); - compareWithPastMeasures(context, index, pastMeasures); + private void calculateVariation(Resource resource, DecoratorContext context, VariationTarget target) { + List pastMeasures = pastMeasuresLoader.getPastMeasures(resource, target.getProjectSnapshot()); + compareWithPastMeasures(context, target.getIndex(), pastMeasures); } void compareWithPastMeasures(DecoratorContext context, int index, List pastMeasures) { @@ -109,51 +88,21 @@ public class VariationDecorator implements Decorator { for (Measure measure : context.getMeasures(MeasuresFilters.all())) { // compare with past measure MeasureModel pastMeasure = pastMeasuresByKey.get(new MeasureKey(measure)); - if (updateDiffValue(measure, pastMeasure, index)) { - context.saveMeasure(measure); - } + updateVariation(measure, pastMeasure, index); + context.saveMeasure(measure); } } - boolean updateDiffValue(Measure measure, MeasureModel pastMeasure, int index) { - boolean updated = false; + void updateVariation(Measure measure, MeasureModel pastMeasure, int index) { if (pastMeasure != null && pastMeasure.getValue() != null && measure.getValue() != null) { - double diff = (measure.getValue().doubleValue() - pastMeasure.getValue().doubleValue()); - updated = true; - switch (index) { - case 0: - measure.setDiffValue1(diff); - break; - case 1: - measure.setDiffValue2(diff); - break; - case 2: - measure.setDiffValue3(diff); - break; - default: - updated = false; - } + double variation = (measure.getValue().doubleValue() - pastMeasure.getValue().doubleValue()); + measure.setVariation(index, variation); } - return updated; - } - - List selectPastMeasures(int resourceId, Snapshot projectTargetSnapshot) { - // improvements : keep query in cache ? select only some columns ? - // TODO support measure on rules and characteristics - String hql = "select m from " + MeasureModel.class.getSimpleName() + " m, " + Snapshot.class.getSimpleName() + " s " + - "where m.snapshotId=s.id and m.metricId in (:metricIds) and m.ruleId=null and m.rulePriority=null and m.characteristic=null " - + "and (s.rootId=:rootSnapshotId or s.id=:rootSnapshotId) and s.resourceId=:resourceId and s.status=:status"; - return session.createQuery(hql) - .setParameter("metricIds", metricByIds.keySet()) - .setParameter("rootSnapshotId", ObjectUtils.defaultIfNull(projectTargetSnapshot.getRootId(), projectTargetSnapshot.getId())) - .setParameter("resourceId", resourceId) - .setParameter("status", Snapshot.STATUS_PROCESSED) - .getResultList(); } @Override public String toString() { - return getClass().toString(); + return getClass().getSimpleName(); } static class MeasureKey { @@ -182,17 +131,26 @@ public class VariationDecorator implements Decorator { @Override public boolean equals(Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } MeasureKey that = (MeasureKey) o; - - if (characteristic != null ? !characteristic.equals(that.characteristic) : that.characteristic != null) + if (characteristic != null ? !characteristic.equals(that.characteristic) : that.characteristic != null) { return false; - if (!metricId.equals(that.metricId)) return false; - if (priority != that.priority) return false; - if (ruleId != null ? !ruleId.equals(that.ruleId) : that.ruleId != null) return false; - + } + if (!metricId.equals(that.metricId)) { + return false; + } + if (priority != that.priority) { + return false; + } + if (ruleId != null ? !ruleId.equals(that.ruleId) : that.ruleId != null) { + return false; + } return true; } @@ -205,4 +163,4 @@ public class VariationDecorator implements Decorator { return result; } } -} +} \ No newline at end of file diff --git a/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/timemachine/VariationTarget.java b/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/timemachine/VariationTarget.java new file mode 100644 index 00000000000..185f85c53f4 --- /dev/null +++ b/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/timemachine/VariationTarget.java @@ -0,0 +1,47 @@ +/* + * Sonar, open source software quality management tool. + * Copyright (C) 2009 SonarSource SA + * mailto:contact AT sonarsource DOT com + * + * Sonar is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * Sonar is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with Sonar; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02 + */ +package org.sonar.plugins.core.timemachine; + +import org.sonar.api.database.model.Snapshot; + +import java.util.Date; + +public final class VariationTarget { + + private int index; + private Snapshot projectSnapshot; + + public VariationTarget(int index, Snapshot projectSnapshot) { + this.index = index; + this.projectSnapshot = projectSnapshot; + } + + public int getIndex() { + return index; + } + + public Snapshot getProjectSnapshot() { + return projectSnapshot; + } + + public Date getDate() { + return projectSnapshot.getCreatedAt(); + } +} diff --git a/plugins/sonar-core-plugin/src/main/resources/org/sonar/plugins/core/widgets/rules.html.erb b/plugins/sonar-core-plugin/src/main/resources/org/sonar/plugins/core/widgets/rules.html.erb index 83ff6fed336..c62d9c4c78e 100644 --- a/plugins/sonar-core-plugin/src/main/resources/org/sonar/plugins/core/widgets/rules.html.erb +++ b/plugins/sonar-core-plugin/src/main/resources/org/sonar/plugins/core/widgets/rules.html.erb @@ -3,19 +3,17 @@
+

Violations

+
+ <%= format_measure(Metric::VIOLATIONS, :url => url_for(:controller => 'drilldown', :action => 'violations', :id => @project.key)) -%> <%= trend_icon(Metric::VIOLATIONS) -%> +

Rules compliance

<%= format_measure(Metric::VIOLATIONS_DENSITY, :url => url_for_drilldown(Metric::WEIGHTED_VIOLATIONS, {:highlight => Metric::WEIGHTED_VIOLATIONS})) -%> <%= trend_icon(Metric::VIOLATIONS_DENSITY) -%>
-
+ -
-

Violations

-
- <%= format_measure(Metric::VIOLATIONS, :url => url_for(:controller => 'drilldown', :action => 'violations', :id => @project.key)) -%> <%= trend_icon(Metric::VIOLATIONS) -%> -
-
<% blocker_violations = @snapshot.measure(Metric::BLOCKER_VIOLATIONS) critical_violations = @snapshot.measure(Metric::CRITICAL_VIOLATIONS) diff --git a/plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/timemachine/NewViolationsDecoratorTest.java b/plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/timemachine/NewViolationsDecoratorTest.java index 6ad62671bb4..fc62ae583ef 100644 --- a/plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/timemachine/NewViolationsDecoratorTest.java +++ b/plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/timemachine/NewViolationsDecoratorTest.java @@ -19,11 +19,6 @@ */ package org.sonar.plugins.core.timemachine; -import static org.hamcrest.Matchers.is; -import static org.junit.Assert.assertThat; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.when; - import org.apache.commons.lang.time.DateUtils; import org.junit.Before; import org.junit.Test; @@ -35,6 +30,12 @@ import org.sonar.api.rules.Violation; import java.util.Arrays; import java.util.Date; +import java.util.List; + +import static org.hamcrest.Matchers.is; +import static org.junit.Assert.assertThat; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; public class NewViolationsDecoratorTest { @@ -48,35 +49,43 @@ public class NewViolationsDecoratorTest { } @Test - public void decoratorDefinition() { - assertThat(decorator.shouldExecuteOnProject(new Project("project")), is(true)); + public void shouldExecuteIfLastAnalysis() { + Project project = mock(Project.class); + + when(project.isLatestAnalysis()).thenReturn(false); + assertThat(decorator.shouldExecuteOnProject(project), is(false)); + + when(project.isLatestAnalysis()).thenReturn(true); + assertThat(decorator.shouldExecuteOnProject(project), is(true)); + } + + @Test + public void shouldBeDependedUponMetric() { assertThat(decorator.generatesMetric(), is(CoreMetrics.NEW_VIOLATIONS)); - assertThat(decorator.toString(), is(NewViolationsDecorator.class.getSimpleName())); } @Test - public void shouldCalculate() { + public void shouldCountViolationsAfterDate() { Date date1 = new Date(); Date date2 = DateUtils.addDays(date1, -20); Project project = new Project("project"); project.setAnalysisDate(date1); Violation violation1 = new Violation(null).setCreatedAt(date1); Violation violation2 = new Violation(null).setCreatedAt(date2); - when(context.getViolations()).thenReturn(Arrays.asList(violation1, violation2)); - when(context.getProject()).thenReturn(project); + List violations = Arrays.asList(violation1, violation2); - assertThat(decorator.calculate(context, 10), is(1)); - assertThat(decorator.calculate(context, 30), is(2)); + assertThat(decorator.countViolationsAfterDate(violations, DateUtils.addDays(date1, -10)), is(1)); + assertThat(decorator.countViolationsAfterDate(violations, DateUtils.addDays(date1, -30)), is(2)); } @Test public void shouldSumChildren() { - Measure measure1 = new Measure(CoreMetrics.NEW_VIOLATIONS).setDiffValue1(1.0).setDiffValue2(1.0).setDiffValue3(3.0); - Measure measure2 = new Measure(CoreMetrics.NEW_VIOLATIONS).setDiffValue1(1.0).setDiffValue2(2.0).setDiffValue3(3.0); + Measure measure1 = new Measure(CoreMetrics.NEW_VIOLATIONS).setVariation1(1.0).setVariation2(1.0).setVariation3(3.0); + Measure measure2 = new Measure(CoreMetrics.NEW_VIOLATIONS).setVariation1(1.0).setVariation2(2.0).setVariation3(3.0); when(context.getChildrenMeasures(CoreMetrics.NEW_VIOLATIONS)).thenReturn(Arrays.asList(measure1, measure2)); - assertThat(decorator.sumChildren(context, 0), is(2.0)); - assertThat(decorator.sumChildren(context, 1), is(3.0)); - assertThat(decorator.sumChildren(context, 2), is(6.0)); + assertThat(decorator.sumChildren(context, 1), is(2)); + assertThat(decorator.sumChildren(context, 2), is(3)); + assertThat(decorator.sumChildren(context, 3), is(6)); } } diff --git a/plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/timemachine/PastMeasuresLoaderTest.java b/plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/timemachine/PastMeasuresLoaderTest.java new file mode 100644 index 00000000000..73959db7844 --- /dev/null +++ b/plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/timemachine/PastMeasuresLoaderTest.java @@ -0,0 +1,95 @@ +/* + * Sonar, open source software quality management tool. + * Copyright (C) 2009 SonarSource SA + * mailto:contact AT sonarsource DOT com + * + * Sonar is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * Sonar is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with Sonar; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02 + */ +package org.sonar.plugins.core.timemachine; + +import org.junit.Test; +import org.sonar.api.database.model.MeasureModel; +import org.sonar.api.database.model.Snapshot; +import org.sonar.api.measures.Metric; +import org.sonar.jpa.test.AbstractDbUnitTestCase; + +import java.util.Arrays; +import java.util.List; + +import static org.hamcrest.CoreMatchers.anyOf; +import static org.hamcrest.CoreMatchers.is; +import static org.hamcrest.MatcherAssert.assertThat; +import static org.junit.internal.matchers.IsCollectionContaining.hasItems; + +public class PastMeasuresLoaderTest extends AbstractDbUnitTestCase { + + private static final int PROJECT_SNAPSHOT_ID = 1000; + private static final int PROJECT_ID = 1; + private static final int FILE_ID = 3; + + @Test + public void shouldGetPastResourceMeasures() { + setupData("shared"); + + List metrics = selectMetrics(); + Snapshot projectSnapshot = getSession().getSingleResult(Snapshot.class, "id", PROJECT_SNAPSHOT_ID); + + PastMeasuresLoader loader = new PastMeasuresLoader(getSession(), metrics); + List measures = loader.getPastMeasures(FILE_ID, projectSnapshot); + assertThat(measures.size(), is(2)); + + for (MeasureModel measure : measures) { + assertThat(measure.getId(), anyOf(is(5L), is(6L))); + assertThat(measure.getValue(), anyOf(is(5.0), is(60.0))); + } + } + + @Test + public void shouldGetPastProjectMeasures() { + setupData("shared"); + + List metrics = selectMetrics(); + Snapshot projectSnapshot = getSession().getSingleResult(Snapshot.class, "id", PROJECT_SNAPSHOT_ID); + + PastMeasuresLoader loader = new PastMeasuresLoader(getSession(), metrics); + List measures = loader.getPastMeasures(PROJECT_ID, projectSnapshot); + assertThat(measures.size(), is(2)); + + for (MeasureModel measure : measures) { + assertThat(measure.getId(), anyOf(is(1L), is(2L))); + assertThat(measure.getValue(), anyOf(is(60.0), is(80.0))); + } + } + + @Test + public void shouldKeepOnlyNumericalMetrics() { + Metric ncloc = new Metric("ncloc", Metric.ValueType.INT); + ncloc.setId(1); + Metric complexity = new Metric("complexity", Metric.ValueType.INT); + complexity.setId(2); + Metric data = new Metric("data", Metric.ValueType.DATA); + data.setId(3); + List metrics = Arrays.asList(ncloc, complexity, data); + + PastMeasuresLoader loader = new PastMeasuresLoader(getSession(), metrics); + + assertThat(loader.getMetrics().size(), is(2)); + assertThat(loader.getMetrics(), hasItems(ncloc, complexity)); + } + + private List selectMetrics() { + return getSession().getResults(Metric.class); + } +} diff --git a/plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/timemachine/PeriodLocatorTest.java b/plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/timemachine/PeriodLocatorTest.java index 54ceea82043..d0d99fed25f 100644 --- a/plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/timemachine/PeriodLocatorTest.java +++ b/plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/timemachine/PeriodLocatorTest.java @@ -40,22 +40,6 @@ public class PeriodLocatorTest extends AbstractDbUnitTestCase { private static SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd"); - @Test - public void shouldAcceptProperty() { - assertThat(PeriodLocator.doAcceptProperty("1d"), is(true)); - assertThat(PeriodLocator.doAcceptProperty("2d"), is(true)); - assertThat(PeriodLocator.doAcceptProperty("500d"), is(true)); - assertThat(PeriodLocator.doAcceptProperty(" 500d "), is(true)); - } - - @Test - public void shouldNotAcceptProperty() { - assertThat(PeriodLocator.doAcceptProperty(null), is(false)); - assertThat(PeriodLocator.doAcceptProperty(""), is(false)); - assertThat(PeriodLocator.doAcceptProperty("1.2.3"), is(false)); - assertThat(PeriodLocator.doAcceptProperty("2010-05-18"), is(false)); - } - @Test public void shouldLoadSnapshotsFromDatabase() { setupData("shouldLoadSnapshotsFromDatabase"); diff --git a/plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/timemachine/TimeMachineConfigurationTest.java b/plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/timemachine/TimeMachineConfigurationTest.java index 4d42f736373..755088e2f5b 100644 --- a/plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/timemachine/TimeMachineConfigurationTest.java +++ b/plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/timemachine/TimeMachineConfigurationTest.java @@ -19,15 +19,17 @@ */ package org.sonar.plugins.core.timemachine; -import static org.hamcrest.CoreMatchers.is; -import static org.hamcrest.MatcherAssert.assertThat; -import static org.hamcrest.Matchers.nullValue; - import org.apache.commons.configuration.PropertiesConfiguration; import org.junit.Test; import org.sonar.api.CoreProperties; +import org.sonar.jpa.test.AbstractDbUnitTestCase; + +import static org.hamcrest.CoreMatchers.is; +import static org.hamcrest.MatcherAssert.assertThat; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.verify; -public class TimeMachineConfigurationTest { +public class TimeMachineConfigurationTest extends AbstractDbUnitTestCase { @Test public void shouldSkipTendencies() { @@ -43,11 +45,14 @@ public class TimeMachineConfigurationTest { } @Test - public void shouldReturnDiffPeriodInDays() { + public void shouldGetPeriodVariationTargets() { PropertiesConfiguration conf = new PropertiesConfiguration(); - conf.setProperty("sonar.timemachine.diff0", "30"); - assertThat(new TimeMachineConfiguration(conf, null).getDiffPeriodInDays(0), is(30)); - assertThat(new TimeMachineConfiguration(conf, null).getDiffPeriodInDays(1), nullValue()); + conf.setProperty("sonar.timemachine.variation1", "7"); + conf.setProperty("sonar.timemachine.variation2", "30"); + PeriodLocator periodLocator = mock(PeriodLocator.class); + new TimeMachineConfiguration(conf, getSession(), periodLocator).getVariationTargets(); + verify(periodLocator).locate(7); + verify(periodLocator).locate(30); } } diff --git a/plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/timemachine/VariationDecoratorTest.java b/plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/timemachine/VariationDecoratorTest.java index 7e2e86db8fc..b4f93aa97db 100644 --- a/plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/timemachine/VariationDecoratorTest.java +++ b/plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/timemachine/VariationDecoratorTest.java @@ -20,70 +20,23 @@ package org.sonar.plugins.core.timemachine; import org.junit.Test; -import org.sonar.api.database.model.MeasureModel; -import org.sonar.api.database.model.Snapshot; -import org.sonar.api.measures.Metric; import org.sonar.api.resources.*; import org.sonar.jpa.test.AbstractDbUnitTestCase; -import java.util.List; - -import static org.hamcrest.CoreMatchers.anyOf; import static org.hamcrest.CoreMatchers.is; import static org.hamcrest.MatcherAssert.assertThat; public class VariationDecoratorTest extends AbstractDbUnitTestCase { - private static final int PROJECT_SNAPSHOT_ID = 1000; - private static final int PROJECT_ID = 1; - private static final int FILE_ID = 3; - - @Test - public void shouldSelectPastResourceMeasures() { - setupData("shared"); - - List metrics = selectMetrics(); - Snapshot projectSnapshot = getSession().getSingleResult(Snapshot.class, "id", PROJECT_SNAPSHOT_ID); - - VariationDecorator decorator = new VariationDecorator(getSession(), new Snapshot[0], metrics); - List measures = decorator.selectPastMeasures(FILE_ID, projectSnapshot); - assertThat(measures.size(), is(2)); - - for (MeasureModel measure : measures) { - assertThat(measure.getId(), anyOf(is(5L), is(6L))); - assertThat(measure.getValue(), anyOf(is(5.0), is(60.0))); - } - } - @Test - public void shouldSelectPastProjectMeasures() { - setupData("shared"); - - List metrics = selectMetrics(); - Snapshot projectSnapshot = getSession().getSingleResult(Snapshot.class, "id", PROJECT_SNAPSHOT_ID); - - VariationDecorator decorator = new VariationDecorator(getSession(), new Snapshot[0], metrics); - List measures = decorator.selectPastMeasures(PROJECT_ID, projectSnapshot); - assertThat(measures.size(), is(2)); - - for (MeasureModel measure : measures) { - assertThat(measure.getId(), anyOf(is(1L), is(2L))); - assertThat(measure.getValue(), anyOf(is(60.0), is(80.0))); - } - } - - @Test - public void shouldNotCalculateDiffValuesOnFiles() { - assertThat(VariationDecorator.shouldCalculateDiffValues(new Project("foo")), is(true)); - assertThat(VariationDecorator.shouldCalculateDiffValues(new JavaPackage("org.foo")), is(true)); - assertThat(VariationDecorator.shouldCalculateDiffValues(new Directory("org/foo")), is(true)); - - assertThat(VariationDecorator.shouldCalculateDiffValues(new JavaFile("org.foo.Bar")), is(false)); - assertThat(VariationDecorator.shouldCalculateDiffValues(new JavaFile("org.foo.Bar", true)), is(false)); - assertThat(VariationDecorator.shouldCalculateDiffValues(new File("org/foo/Bar.php")), is(false)); + public void shouldNotCalculateVariationsOnFiles() { + assertThat(VariationDecorator.shouldCalculateVariations(new Project("foo")), is(true)); + assertThat(VariationDecorator.shouldCalculateVariations(new JavaPackage("org.foo")), is(true)); + assertThat(VariationDecorator.shouldCalculateVariations(new Directory("org/foo")), is(true)); + + assertThat(VariationDecorator.shouldCalculateVariations(new JavaFile("org.foo.Bar")), is(false)); + assertThat(VariationDecorator.shouldCalculateVariations(new JavaFile("org.foo.Bar", true)), is(false)); + assertThat(VariationDecorator.shouldCalculateVariations(new File("org/foo/Bar.php")), is(false)); } - private List selectMetrics() { - return getSession().getResults(Metric.class); - } } diff --git a/plugins/sonar-core-plugin/src/test/resources/org/sonar/plugins/core/timemachine/PastMeasuresLoaderTest/shared.xml b/plugins/sonar-core-plugin/src/test/resources/org/sonar/plugins/core/timemachine/PastMeasuresLoaderTest/shared.xml new file mode 100644 index 00000000000..69fc7dcba5b --- /dev/null +++ b/plugins/sonar-core-plugin/src/test/resources/org/sonar/plugins/core/timemachine/PastMeasuresLoaderTest/shared.xml @@ -0,0 +1,85 @@ + + + \ No newline at end of file diff --git a/plugins/sonar-core-plugin/src/test/resources/org/sonar/plugins/core/timemachine/VariationDecoratorTest/shared.xml b/plugins/sonar-core-plugin/src/test/resources/org/sonar/plugins/core/timemachine/VariationDecoratorTest/shared.xml deleted file mode 100644 index 69fc7dcba5b..00000000000 --- a/plugins/sonar-core-plugin/src/test/resources/org/sonar/plugins/core/timemachine/VariationDecoratorTest/shared.xml +++ /dev/null @@ -1,85 +0,0 @@ - - - \ No newline at end of file diff --git a/sonar-batch/src/main/java/org/sonar/batch/DefaultTimeMachine.java b/sonar-batch/src/main/java/org/sonar/batch/DefaultTimeMachine.java index 6a2f85bbd89..824cc7d774c 100644 --- a/sonar-batch/src/main/java/org/sonar/batch/DefaultTimeMachine.java +++ b/sonar-batch/src/main/java/org/sonar/batch/DefaultTimeMachine.java @@ -146,9 +146,9 @@ public class DefaultTimeMachine implements TimeMachine { measure.setAlertStatus(model.getAlertStatus()); measure.setAlertText(model.getAlertText()); measure.setTendency(model.getTendency()); - measure.setDiffValue1(model.getDiffValue1()); - measure.setDiffValue2(model.getDiffValue2()); - measure.setDiffValue3(model.getDiffValue3()); + measure.setVariation1(model.getDiffValue1()); + measure.setVariation2(model.getDiffValue2()); + measure.setVariation3(model.getDiffValue3()); measure.setUrl(model.getUrl()); measure.setCharacteristic(model.getCharacteristic()); return measure; diff --git a/sonar-batch/src/main/java/org/sonar/batch/index/MeasurePersister.java b/sonar-batch/src/main/java/org/sonar/batch/index/MeasurePersister.java index ab8375835b2..79eab354dec 100644 --- a/sonar-batch/src/main/java/org/sonar/batch/index/MeasurePersister.java +++ b/sonar-batch/src/main/java/org/sonar/batch/index/MeasurePersister.java @@ -100,9 +100,9 @@ public final class MeasurePersister { measure.getTendency() == null && measure.getUrl() == null && measure.getData() == null && - (measure.getDiffValue1() == null || NumberUtils.compare(measure.getDiffValue1().doubleValue(), 0.0) == 0) && - (measure.getDiffValue2() == null || NumberUtils.compare(measure.getDiffValue2().doubleValue(), 0.0) == 0) && - (measure.getDiffValue3() == null || NumberUtils.compare(measure.getDiffValue3().doubleValue(), 0.0) == 0); + (measure.getVariation1() == null || NumberUtils.compare(measure.getVariation1().doubleValue(), 0.0) == 0) && + (measure.getVariation2() == null || NumberUtils.compare(measure.getVariation2().doubleValue(), 0.0) == 0) && + (measure.getVariation3() == null || NumberUtils.compare(measure.getVariation3().doubleValue(), 0.0) == 0); } public void dump() { @@ -135,9 +135,9 @@ public final class MeasurePersister { merge.setAlertStatus(measure.getAlertStatus()); merge.setAlertText(measure.getAlertText()); merge.setTendency(measure.getTendency()); - merge.setDiffValue1(measure.getDiffValue1()); - merge.setDiffValue2(measure.getDiffValue2()); - merge.setDiffValue3(measure.getDiffValue3()); + merge.setDiffValue1(measure.getVariation1()); + merge.setDiffValue2(measure.getVariation2()); + merge.setDiffValue3(measure.getVariation3()); merge.setUrl(measure.getUrl()); merge.setCharacteristic(measure.getCharacteristic()); if (measure.getValue() != null) { diff --git a/sonar-batch/src/test/java/org/sonar/batch/index/MeasurePersisterTest.java b/sonar-batch/src/test/java/org/sonar/batch/index/MeasurePersisterTest.java index aa7f42a44bb..c14b147d84d 100644 --- a/sonar-batch/src/test/java/org/sonar/batch/index/MeasurePersisterTest.java +++ b/sonar-batch/src/test/java/org/sonar/batch/index/MeasurePersisterTest.java @@ -196,10 +196,10 @@ public class MeasurePersisterTest extends AbstractDbUnitTestCase { Measure duplicatedLines = new Measure(CoreMetrics.DUPLICATED_LINES_DENSITY, 0.0); assertThat(MeasurePersister.shouldPersistMeasure(file, duplicatedLines), is(false)); - duplicatedLines.setDiffValue1(0.0); + duplicatedLines.setVariation1(0.0); assertThat(MeasurePersister.shouldPersistMeasure(file, duplicatedLines), is(false)); - duplicatedLines.setDiffValue1(-3.0); + duplicatedLines.setVariation1(-3.0); assertThat(MeasurePersister.shouldPersistMeasure(file, duplicatedLines), is(true)); } diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/measures/Measure.java b/sonar-plugin-api/src/main/java/org/sonar/api/measures/Measure.java index 7bd623d98e1..385578af39f 100644 --- a/sonar-plugin-api/src/main/java/org/sonar/api/measures/Measure.java +++ b/sonar-plugin-api/src/main/java/org/sonar/api/measures/Measure.java @@ -49,7 +49,7 @@ public class Measure { protected String alertText; protected Integer tendency; protected Date date; - protected Double diff1, diff2, diff3; + protected Double variation1, variation2, variation3; protected String url; protected Characteristic characteristic; protected PersistenceMode persistenceMode = PersistenceMode.FULL; @@ -411,56 +411,56 @@ public class Measure { } /** - * @return the first differential value of the measure + * @return the first variation value */ - public Double getDiffValue1() { - return diff1; + public Double getVariation1() { + return variation1; } - /** - * Sets the first differential value of the measure - * - * @param diff1 the diff - * @return the measure object instance - */ - public Measure setDiffValue1(Double diff1) { - this.diff1 = diff1; + public Measure setVariation1(Double d) { + this.variation1 = d; return this; } /** - * @return the second differential value of the measure + * @return the second variation value */ - public Double getDiffValue2() { - return diff2; + public Double getVariation2() { + return variation2; } - /** - * Sets the second differential value of the measure - * - * @param diff2 the diff - * @return the measure object instance - */ - public Measure setDiffValue2(Double diff2) { - this.diff2 = diff2; + public Measure setVariation2(Double d) { + this.variation2 = d; return this; } /** - * @return the third differential value of the measure + * @return the third variation value */ - public Double getDiffValue3() { - return diff3; + public Double getVariation3() { + return variation3; } - /** - * Sets the third differential value of the measure - * - * @param diff3 the diff - * @return the measure object instance - */ - public Measure setDiffValue3(Double diff3) { - this.diff3 = diff3; + public Measure setVariation3(Double d) { + this.variation3 = d; + return this; + } + + public Double getVariation(int index) { + switch(index) { + case 1: return variation1; + case 2: return variation2; + case 3: return variation3; + } + return null; + } + + public Measure setVariation(int index, Double d) { + switch(index) { + case 1: variation1 = d; break; + case 2: variation2 = d; break; + case 3: variation3 = d; break; + } return this; } @@ -529,9 +529,9 @@ public class Measure { append("alertText", alertText). append("tendency", tendency). append("characteristic", characteristic). - append("diff1", diff1). - append("diff2", diff2). - append("diff3", diff3). + append("variation1", variation1). + append("variation2", variation2). + append("variation3", variation3). toString(); } } diff --git a/sonar-plugin-api/src/test/java/org/sonar/api/measures/MeasureTest.java b/sonar-plugin-api/src/test/java/org/sonar/api/measures/MeasureTest.java index 4fe07d41236..430e2131e98 100644 --- a/sonar-plugin-api/src/test/java/org/sonar/api/measures/MeasureTest.java +++ b/sonar-plugin-api/src/test/java/org/sonar/api/measures/MeasureTest.java @@ -92,11 +92,19 @@ public class MeasureTest { } @Test - public void diffValues() { - Measure measure = new Measure(CoreMetrics.LINES).setDiffValue1(1d).setDiffValue2(2d).setDiffValue3(3d); - assertThat(measure.getDiffValue1(), is(1d)); - assertThat(measure.getDiffValue2(), is(2d)); - assertThat(measure.getDiffValue3(), is(3d)); + public void shouldGetAndSetVariations() { + Measure measure = new Measure(CoreMetrics.LINES).setVariation1(1d).setVariation2(2d).setVariation3(3d); + assertThat(measure.getVariation1(), is(1d)); + assertThat(measure.getVariation2(), is(2d)); + assertThat(measure.getVariation3(), is(3d)); + } + + @Test + public void shouldSetVariationsWithIndex() { + Measure measure = new Measure(CoreMetrics.LINES).setVariation(2, 3.3); + assertThat(measure.getVariation1(), nullValue()); + assertThat(measure.getVariation2(), is(3.3)); + assertThat(measure.getVariation3(), nullValue()); } @Test