]> source.dussan.org Git - sonarqube.git/commitdiff
SONAR-249 save configuration used for measure variations and new violations in the...
authorsimonbrandhof <simon.brandhof@gmail.com>
Wed, 1 Dec 2010 22:09:09 +0000 (22:09 +0000)
committersimonbrandhof <simon.brandhof@gmail.com>
Wed, 1 Dec 2010 22:09:09 +0000 (22:09 +0000)
20 files changed:
plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/CorePlugin.java
plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/timemachine/NewViolationsDecorator.java
plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/timemachine/PastMeasuresLoader.java [new file with mode: 0644]
plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/timemachine/PeriodLocator.java
plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/timemachine/TimeMachineConfiguration.java
plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/timemachine/VariationDecorator.java
plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/timemachine/VariationTarget.java [new file with mode: 0644]
plugins/sonar-core-plugin/src/main/resources/org/sonar/plugins/core/widgets/rules.html.erb
plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/timemachine/NewViolationsDecoratorTest.java
plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/timemachine/PastMeasuresLoaderTest.java [new file with mode: 0644]
plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/timemachine/PeriodLocatorTest.java
plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/timemachine/TimeMachineConfigurationTest.java
plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/timemachine/VariationDecoratorTest.java
plugins/sonar-core-plugin/src/test/resources/org/sonar/plugins/core/timemachine/PastMeasuresLoaderTest/shared.xml [new file with mode: 0644]
plugins/sonar-core-plugin/src/test/resources/org/sonar/plugins/core/timemachine/VariationDecoratorTest/shared.xml [deleted file]
sonar-batch/src/main/java/org/sonar/batch/DefaultTimeMachine.java
sonar-batch/src/main/java/org/sonar/batch/index/MeasurePersister.java
sonar-batch/src/test/java/org/sonar/batch/index/MeasurePersisterTest.java
sonar-plugin-api/src/main/java/org/sonar/api/measures/Measure.java
sonar-plugin-api/src/test/java/org/sonar/api/measures/MeasureTest.java

index f1e767eec96420435e3107f6443b942d6a9935f0..27da9438c3b0cf5139f55467ccb1765718d0d267 100644 (file)
@@ -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;
   }
index d64935cf3a36a3574b32e4318670529e157d733f..1c1eab8638cec56690341dcaa65e8898692bbfbd 100644 (file)
  */
 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<Violation> 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 (file)
index 0000000..be7fcfe
--- /dev/null
@@ -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<Integer, Metric> metricByIds;
+  private DatabaseSession session;
+
+  public PastMeasuresLoader(DatabaseSession session, MetricFinder metricFinder) {
+    this(session, metricFinder.findAll());
+  }
+
+  PastMeasuresLoader(DatabaseSession session, Collection<Metric> metrics) {
+    this.session = session;
+    this.metricByIds = Maps.newHashMap();
+    for (Metric metric : metrics) {
+      if (metric.isNumericType()) {
+        metricByIds.put(metric.getId(), metric);
+      }
+    }
+  }
+
+  public Collection<Metric> getMetrics() {
+    return metricByIds.values();
+  }
+
+  public List<MeasureModel> getPastMeasures(Resource resource, Snapshot projectSnapshot) {
+    // assume that the resource has already been saved
+    return getPastMeasures(resource.getId(), projectSnapshot);
+  }
+
+  public List<MeasureModel> 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();
+  }
+}
index ef1acbcbf2264ccf6cd2045ee1380028a4a5049d..5acf136782f4ec7f3ae37a745ab54c6fd706b0ca 100644 (file)
@@ -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<Snapshot> 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");
-  }
 }
index 4e219294a09202025bb859310a482f0bbdee2553..a940ce514a7831d1ba49f3e7b26ad83d70b9a0a8 100644 (file)
  */
 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<VariationTarget> 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<VariationTarget> 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<VariationTarget> getVariationTargets() {
+    return variationTargets;
   }
 }
index aa656b01db005565af1187c5ecab9cfd5227ff9c..08c5e34837a3c89c9752666dabfbfd34acfcd84a 100644 (file)
 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<Integer, Metric> metricByIds;
-  private DatabaseSession session;
+  private List<VariationTarget> 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<Metric> metrics) {
-    this.session = session;
-    this.projectTargetSnapshots = projectTargetSnapshots;
-    initMetrics(metrics);
-  }
-
-  private void initMetrics(Collection<Metric> metrics) {
-    this.metricByIds = Maps.newHashMap();
-    for (Metric metric : metrics) {
-      if (metric.isNumericType()) {
-        metricByIds.put(metric.getId(), metric);
-      }
-    }
+  VariationDecorator(PastMeasuresLoader pastMeasuresLoader, List<VariationTarget> targets) {
+    this.pastMeasuresLoader = pastMeasuresLoader;
+    this.targets = targets;
   }
 
   public boolean shouldExecuteOnProject(Project project) {
-    return true;
+    return project.isLatestAnalysis();
   }
 
   @DependsUpon
   public Collection<Metric> 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<MeasureModel> pastMeasures = selectPastMeasures(resource.getId(), projectTargetSnapshot);
-    compareWithPastMeasures(context, index, pastMeasures);
+  private void calculateVariation(Resource resource, DecoratorContext context, VariationTarget target) {
+    List<MeasureModel> pastMeasures = pastMeasuresLoader.getPastMeasures(resource, target.getProjectSnapshot());
+    compareWithPastMeasures(context, target.getIndex(), pastMeasures);
   }
 
   void compareWithPastMeasures(DecoratorContext context, int index, List<MeasureModel> 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<MeasureModel> 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 (file)
index 0000000..185f85c
--- /dev/null
@@ -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();
+  }
+}
index 83ff6fed3363d126affb2c9ac7df70877f42ee4e..c62d9c4c78ee53fa0c1819be8e0fd0f7a73946a8 100644 (file)
@@ -3,19 +3,17 @@
   <tr>
     <td valign="top" width="50%">
                  <div class="dashbox">
+                   <h3>Violations</h3>
+                         <div class="big marginbottom10">
+                           <%= format_measure(Metric::VIOLATIONS, :url => url_for(:controller => 'drilldown', :action => 'violations', :id => @project.key)) -%> <%= trend_icon(Metric::VIOLATIONS) -%>
+                         </div>
         <h3>Rules compliance</h3>
         <div class="big">
           <%= format_measure(Metric::VIOLATIONS_DENSITY, :url => url_for_drilldown(Metric::WEIGHTED_VIOLATIONS, {:highlight => Metric::WEIGHTED_VIOLATIONS})) -%> <%= trend_icon(Metric::VIOLATIONS_DENSITY) -%>
         </div>
-                       </div>
+                 </div>
                </td>
                <td valign="top" width="50%" nowrap>
-                         <div class="dashbox">
-                           <h3>Violations</h3>
-                           <div class="big">
-                             <%= format_measure(Metric::VIOLATIONS, :url => url_for(:controller => 'drilldown', :action => 'violations', :id => @project.key)) -%> <%= trend_icon(Metric::VIOLATIONS) -%>
-                           </div>
-                         </div>
                        <%
                        blocker_violations = @snapshot.measure(Metric::BLOCKER_VIOLATIONS)
                        critical_violations = @snapshot.measure(Metric::CRITICAL_VIOLATIONS)
index 6ad62671bb482b84743162dab4b50712288d8701..fc62ae583ef12e2555d5f99e593dd9b3247c2d03 100644 (file)
  */
 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<Violation> 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 (file)
index 0000000..73959db
--- /dev/null
@@ -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<Metric> metrics = selectMetrics();
+    Snapshot projectSnapshot = getSession().getSingleResult(Snapshot.class, "id", PROJECT_SNAPSHOT_ID);
+
+    PastMeasuresLoader loader = new PastMeasuresLoader(getSession(), metrics);
+    List<MeasureModel> 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<Metric> metrics = selectMetrics();
+    Snapshot projectSnapshot = getSession().getSingleResult(Snapshot.class, "id", PROJECT_SNAPSHOT_ID);
+
+    PastMeasuresLoader loader = new PastMeasuresLoader(getSession(), metrics);
+    List<MeasureModel> 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<Metric> 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<Metric> selectMetrics() {
+    return getSession().getResults(Metric.class);
+  }
+}
index 54ceea820437658713501b97501030933d063e68..d0d99fed25f3fda906a4b6e4e8b77c8cc198eaee 100644 (file)
@@ -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");
index 4d42f736373ea78fa2d116b9402c0510539f42f4..755088e2f5b0b33fea10c139a3d46b59f290f102 100644 (file)
  */
 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);
   }
 
 }
index 7e2e86db8fc666389e7c7b9be2bdccfdb8c58b20..b4f93aa97dbc52bf4b7a05432ed6e80eba050a3a 100644 (file)
 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<Metric> metrics = selectMetrics();
-    Snapshot projectSnapshot = getSession().getSingleResult(Snapshot.class, "id", PROJECT_SNAPSHOT_ID);
-
-    VariationDecorator decorator = new VariationDecorator(getSession(), new Snapshot[0], metrics);
-    List<MeasureModel> 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<Metric> metrics = selectMetrics();
-    Snapshot projectSnapshot = getSession().getSingleResult(Snapshot.class, "id", PROJECT_SNAPSHOT_ID);
-
-    VariationDecorator decorator = new VariationDecorator(getSession(), new Snapshot[0], metrics);
-    List<MeasureModel> 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<Metric> 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 (file)
index 0000000..69fc7dc
--- /dev/null
@@ -0,0 +1,85 @@
+<dataset>
+
+  <metrics id="1" name="ncloc" VAL_TYPE="INT" DESCRIPTION="[null]"  domain="[null]" short_name=""
+           enabled="true" worst_value="[null]" optimized_best_value="[null]" best_value="[null]" direction="0" hidden="false"/>
+  <metrics id="2" name="coverage" VAL_TYPE="INT" DESCRIPTION="[null]"  domain="[null]" short_name=""
+           enabled="true" worst_value="0" optimized_best_value="true" best_value="100" direction="1" hidden="false"/>
+
+
+  <rules_categories id="1" name="Efficiency" description="[null]"/>
+  <rules_categories id="6" name="Usability" description="[null]"/>
+
+  <rules id="30" name="Check Header" plugin_rule_key="com.puppycrawl.tools.checkstyle.checks.header.HeaderCheck"
+         plugin_config_key="Checker/Treewalker/HeaderCheck" plugin_name="checkstyle" description="[null]" priority="4" enabled="true"
+         cardinality="SINGLE" parent_id="[null]"/>
+
+  <rules id="31" name="Equals Avoid Null" plugin_rule_key="com.puppycrawl.tools.checkstyle.checks.coding.EqualsAvoidNullCheck"
+         plugin_config_key="Checker/TreeWalker/EqualsAvoidNull" plugin_name="checkstyle" description="[null]" priority="4" enabled="true"
+         cardinality="SINGLE" parent_id="[null]"/>
+
+  <!-- project -->
+  <projects long_name="[null]" id="1" scope="PRJ" qualifier="TRK" kee="project" name="project"
+            root_id="[null]"
+            description="[null]"
+            enabled="true" language="java" copy_resource_id="[null]"/>
+
+  <!-- package -->
+  <projects long_name="[null]" id="2" scope="DIR" qualifier="PAC" kee="project:org.foo" name="org.foo"
+            root_id="1"
+            description="[null]"
+            enabled="true" language="java" copy_resource_id="[null]"/>
+
+  <!-- file -->
+  <projects long_name="org.foo.Bar" id="3" scope="FIL" qualifier="CLA" kee="project:org.foo.Bar"
+            name="Bar" root_id="[null]"
+            description="[null]"
+            enabled="true" language="java" copy_resource_id="[null]"/>
+
+
+  <!-- snapshots -->
+  <snapshots var_mode_1="[null]" var_label_1="[null]" var_mode_2="[null]" var_label_2="[null]" var_mode_3="[null]" var_label_3="[null]" id="1000" project_id="1" parent_snapshot_id="[null]" root_project_id="1" root_snapshot_id="[null]"
+             scope="PRJ" qualifier="TRK" created_at="2008-11-01 13:58:00.00" version="[null]" path=""
+             status="P" islast="false" depth="0" />
+
+  <snapshots var_mode_1="[null]" var_label_1="[null]" var_mode_2="[null]" var_label_2="[null]" var_mode_3="[null]" var_label_3="[null]" id="1001" project_id="2" parent_snapshot_id="1000" root_project_id="1" root_snapshot_id="1000"
+             scope="DIR" qualifier="PAC" created_at="2008-11-01 13:58:00.00" version="[null]" path="1000."
+             status="P" islast="false" depth="1" />
+
+  <snapshots var_mode_1="[null]" var_label_1="[null]" var_mode_2="[null]" var_label_2="[null]" var_mode_3="[null]" var_label_3="[null]" id="1002" project_id="3" parent_snapshot_id="1001" root_project_id="1" root_snapshot_id="1000"
+             scope="FIL" qualifier="CLA" created_at="2008-11-01 13:58:00.00" version="[null]" path="1000.1001."
+             status="P" islast="false" depth="2" />
+
+
+  <!-- project measures -->
+  <project_measures id="1" VALUE="60" METRIC_ID="1" SNAPSHOT_ID="1000" alert_text="[null]" RULES_CATEGORY_ID="[null]"
+                    RULE_ID="[null]" text_value="[null]" tendency="[null]" measure_date="[null]" project_id="[null]"
+                    alert_status="[null]" description="[null]" rule_priority="[null]" characteristic_id="[null]" url="[null]"
+                    diff_value_1="[null]" diff_value_2="[null]" diff_value_3="[null]"/>
+
+  <project_measures id="2" VALUE="80" METRIC_ID="2" SNAPSHOT_ID="1000" alert_text="[null]" RULES_CATEGORY_ID="[null]"
+                    RULE_ID="[null]" text_value="[null]" tendency="[null]" measure_date="[null]" project_id="[null]"
+                    alert_status="[null]" description="[null]" rule_priority="[null]" characteristic_id="[null]" url="[null]"
+                    diff_value_1="[null]" diff_value_2="[null]" diff_value_3="[null]"/>
+
+  <!-- package measures -->
+  <project_measures id="3" VALUE="20" METRIC_ID="1" SNAPSHOT_ID="1001" alert_text="[null]" RULES_CATEGORY_ID="[null]"
+                    RULE_ID="[null]" text_value="[null]" tendency="[null]" measure_date="[null]" project_id="[null]"
+                    alert_status="[null]" description="[null]" rule_priority="[null]" characteristic_id="[null]" url="[null]"
+                    diff_value_1="[null]" diff_value_2="[null]" diff_value_3="[null]"/>
+
+  <project_measures id="4" VALUE="70" METRIC_ID="2" SNAPSHOT_ID="1001" alert_text="[null]" RULES_CATEGORY_ID="[null]"
+                    RULE_ID="[null]" text_value="[null]" tendency="[null]" measure_date="[null]" project_id="[null]"
+                    alert_status="[null]" description="[null]" rule_priority="[null]" characteristic_id="[null]" url="[null]"
+                    diff_value_1="[null]" diff_value_2="[null]" diff_value_3="[null]"/>
+
+  <!-- file measures -->
+  <project_measures id="5" VALUE="5" METRIC_ID="1" SNAPSHOT_ID="1002" alert_text="[null]" RULES_CATEGORY_ID="[null]"
+                    RULE_ID="[null]" text_value="[null]" tendency="[null]" measure_date="[null]" project_id="[null]"
+                    alert_status="[null]" description="[null]" rule_priority="[null]" characteristic_id="[null]" url="[null]"
+                    diff_value_1="[null]" diff_value_2="[null]" diff_value_3="[null]"/>
+
+  <project_measures id="6" VALUE="60" METRIC_ID="2" SNAPSHOT_ID="1002" alert_text="[null]" RULES_CATEGORY_ID="[null]"
+                    RULE_ID="[null]" text_value="[null]" tendency="[null]" measure_date="[null]" project_id="[null]"
+                    alert_status="[null]" description="[null]" rule_priority="[null]" characteristic_id="[null]" url="[null]"
+                    diff_value_1="[null]" diff_value_2="[null]" diff_value_3="[null]"/>
+</dataset>
\ 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 (file)
index 69fc7dc..0000000
+++ /dev/null
@@ -1,85 +0,0 @@
-<dataset>
-
-  <metrics id="1" name="ncloc" VAL_TYPE="INT" DESCRIPTION="[null]"  domain="[null]" short_name=""
-           enabled="true" worst_value="[null]" optimized_best_value="[null]" best_value="[null]" direction="0" hidden="false"/>
-  <metrics id="2" name="coverage" VAL_TYPE="INT" DESCRIPTION="[null]"  domain="[null]" short_name=""
-           enabled="true" worst_value="0" optimized_best_value="true" best_value="100" direction="1" hidden="false"/>
-
-
-  <rules_categories id="1" name="Efficiency" description="[null]"/>
-  <rules_categories id="6" name="Usability" description="[null]"/>
-
-  <rules id="30" name="Check Header" plugin_rule_key="com.puppycrawl.tools.checkstyle.checks.header.HeaderCheck"
-         plugin_config_key="Checker/Treewalker/HeaderCheck" plugin_name="checkstyle" description="[null]" priority="4" enabled="true"
-         cardinality="SINGLE" parent_id="[null]"/>
-
-  <rules id="31" name="Equals Avoid Null" plugin_rule_key="com.puppycrawl.tools.checkstyle.checks.coding.EqualsAvoidNullCheck"
-         plugin_config_key="Checker/TreeWalker/EqualsAvoidNull" plugin_name="checkstyle" description="[null]" priority="4" enabled="true"
-         cardinality="SINGLE" parent_id="[null]"/>
-
-  <!-- project -->
-  <projects long_name="[null]" id="1" scope="PRJ" qualifier="TRK" kee="project" name="project"
-            root_id="[null]"
-            description="[null]"
-            enabled="true" language="java" copy_resource_id="[null]"/>
-
-  <!-- package -->
-  <projects long_name="[null]" id="2" scope="DIR" qualifier="PAC" kee="project:org.foo" name="org.foo"
-            root_id="1"
-            description="[null]"
-            enabled="true" language="java" copy_resource_id="[null]"/>
-
-  <!-- file -->
-  <projects long_name="org.foo.Bar" id="3" scope="FIL" qualifier="CLA" kee="project:org.foo.Bar"
-            name="Bar" root_id="[null]"
-            description="[null]"
-            enabled="true" language="java" copy_resource_id="[null]"/>
-
-
-  <!-- snapshots -->
-  <snapshots var_mode_1="[null]" var_label_1="[null]" var_mode_2="[null]" var_label_2="[null]" var_mode_3="[null]" var_label_3="[null]" id="1000" project_id="1" parent_snapshot_id="[null]" root_project_id="1" root_snapshot_id="[null]"
-             scope="PRJ" qualifier="TRK" created_at="2008-11-01 13:58:00.00" version="[null]" path=""
-             status="P" islast="false" depth="0" />
-
-  <snapshots var_mode_1="[null]" var_label_1="[null]" var_mode_2="[null]" var_label_2="[null]" var_mode_3="[null]" var_label_3="[null]" id="1001" project_id="2" parent_snapshot_id="1000" root_project_id="1" root_snapshot_id="1000"
-             scope="DIR" qualifier="PAC" created_at="2008-11-01 13:58:00.00" version="[null]" path="1000."
-             status="P" islast="false" depth="1" />
-
-  <snapshots var_mode_1="[null]" var_label_1="[null]" var_mode_2="[null]" var_label_2="[null]" var_mode_3="[null]" var_label_3="[null]" id="1002" project_id="3" parent_snapshot_id="1001" root_project_id="1" root_snapshot_id="1000"
-             scope="FIL" qualifier="CLA" created_at="2008-11-01 13:58:00.00" version="[null]" path="1000.1001."
-             status="P" islast="false" depth="2" />
-
-
-  <!-- project measures -->
-  <project_measures id="1" VALUE="60" METRIC_ID="1" SNAPSHOT_ID="1000" alert_text="[null]" RULES_CATEGORY_ID="[null]"
-                    RULE_ID="[null]" text_value="[null]" tendency="[null]" measure_date="[null]" project_id="[null]"
-                    alert_status="[null]" description="[null]" rule_priority="[null]" characteristic_id="[null]" url="[null]"
-                    diff_value_1="[null]" diff_value_2="[null]" diff_value_3="[null]"/>
-
-  <project_measures id="2" VALUE="80" METRIC_ID="2" SNAPSHOT_ID="1000" alert_text="[null]" RULES_CATEGORY_ID="[null]"
-                    RULE_ID="[null]" text_value="[null]" tendency="[null]" measure_date="[null]" project_id="[null]"
-                    alert_status="[null]" description="[null]" rule_priority="[null]" characteristic_id="[null]" url="[null]"
-                    diff_value_1="[null]" diff_value_2="[null]" diff_value_3="[null]"/>
-
-  <!-- package measures -->
-  <project_measures id="3" VALUE="20" METRIC_ID="1" SNAPSHOT_ID="1001" alert_text="[null]" RULES_CATEGORY_ID="[null]"
-                    RULE_ID="[null]" text_value="[null]" tendency="[null]" measure_date="[null]" project_id="[null]"
-                    alert_status="[null]" description="[null]" rule_priority="[null]" characteristic_id="[null]" url="[null]"
-                    diff_value_1="[null]" diff_value_2="[null]" diff_value_3="[null]"/>
-
-  <project_measures id="4" VALUE="70" METRIC_ID="2" SNAPSHOT_ID="1001" alert_text="[null]" RULES_CATEGORY_ID="[null]"
-                    RULE_ID="[null]" text_value="[null]" tendency="[null]" measure_date="[null]" project_id="[null]"
-                    alert_status="[null]" description="[null]" rule_priority="[null]" characteristic_id="[null]" url="[null]"
-                    diff_value_1="[null]" diff_value_2="[null]" diff_value_3="[null]"/>
-
-  <!-- file measures -->
-  <project_measures id="5" VALUE="5" METRIC_ID="1" SNAPSHOT_ID="1002" alert_text="[null]" RULES_CATEGORY_ID="[null]"
-                    RULE_ID="[null]" text_value="[null]" tendency="[null]" measure_date="[null]" project_id="[null]"
-                    alert_status="[null]" description="[null]" rule_priority="[null]" characteristic_id="[null]" url="[null]"
-                    diff_value_1="[null]" diff_value_2="[null]" diff_value_3="[null]"/>
-
-  <project_measures id="6" VALUE="60" METRIC_ID="2" SNAPSHOT_ID="1002" alert_text="[null]" RULES_CATEGORY_ID="[null]"
-                    RULE_ID="[null]" text_value="[null]" tendency="[null]" measure_date="[null]" project_id="[null]"
-                    alert_status="[null]" description="[null]" rule_priority="[null]" characteristic_id="[null]" url="[null]"
-                    diff_value_1="[null]" diff_value_2="[null]" diff_value_3="[null]"/>
-</dataset>
\ No newline at end of file
index 6a2f85bbd8986bed26ae342fbd38c5d0ed88782a..824cc7d774cae9a589e1e62047a3be339d340926 100644 (file)
@@ -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;
index ab8375835b29ce7b936ed35bd32afed9bcab59fd..79eab354dec30d9f77a0fc1951b32a3de8282f29 100644 (file)
@@ -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) {
index aa7f42a44bb9582d3803092d1ff2ad28bed1b1c7..c14b147d84dadb1e930dd3e31a63fcd90d510e2f 100644 (file)
@@ -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));
 
   }
index 7bd623d98e15c570e514e4acdc8b8d600124fc06..385578af39ff73b82fdf30807a9ae37a769accc8 100644 (file)
@@ -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();
   }
 }
index 4fe07d41236b56d61e3b871985d59fa86647fb50..430e2131e988eec11173b0d0919bfb62abda6b6d 100644 (file)
@@ -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