aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGodin <mandrikov@gmail.com>2010-11-30 23:34:59 +0000
committerGodin <mandrikov@gmail.com>2010-11-30 23:34:59 +0000
commit4e10bd0c5beb97e398e80747d26f6b85f8a9f930 (patch)
tree87bee5178c0a93f7f0f474fe12f02f44fa2a4ba1
parentd62af18bac3cce04fe4a50980a49f36fee17408c (diff)
downloadsonarqube-4e10bd0c5beb97e398e80747d26f6b85f8a9f930.tar.gz
sonarqube-4e10bd0c5beb97e398e80747d26f6b85f8a9f930.zip
SONAR-1450: Add first implementation of NewViolationsDecorator
-rw-r--r--plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/CorePlugin.java3
-rw-r--r--plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/timemachine/NewViolationsDecorator.java73
-rw-r--r--plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/timemachine/TimeMachineConfiguration.java13
-rw-r--r--plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/timemachine/NewViolationsDecoratorTest.java42
-rw-r--r--sonar-plugin-api/src/main/java/org/sonar/api/measures/CoreMetrics.java4
-rw-r--r--sonar-plugin-api/src/main/java/org/sonar/api/measures/Measure.java83
-rw-r--r--sonar-plugin-api/src/main/java/org/sonar/api/rules/Violation.java3
7 files changed, 173 insertions, 48 deletions
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 a3495af0c0b..f1e767eec96 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,6 +19,8 @@
*/
package org.sonar.plugins.core;
+import org.sonar.plugins.core.timemachine.NewViolationsDecorator;
+
import com.google.common.collect.Lists;
import org.sonar.api.CoreProperties;
import org.sonar.api.Plugin;
@@ -196,6 +198,7 @@ public class CorePlugin implements Plugin {
extensions.add(TendencyDecorator.class);
extensions.add(PeriodLocator.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
new file mode 100644
index 00000000000..4e6dc6276f7
--- /dev/null
+++ b/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/timemachine/NewViolationsDecorator.java
@@ -0,0 +1,73 @@
+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.measures.CoreMetrics;
+import org.sonar.api.measures.Measure;
+import org.sonar.api.resources.Project;
+import org.sonar.api.resources.Resource;
+import org.sonar.api.rules.Violation;
+
+import java.util.Date;
+
+@DependedUpon(DecoratorBarriers.END_OF_VIOLATIONS_GENERATION)
+public class NewViolationsDecorator implements Decorator {
+
+ private TimeMachineConfiguration timeMachineConfiguration;
+
+ public NewViolationsDecorator(TimeMachineConfiguration timeMachineConfiguration) {
+ this.timeMachineConfiguration = timeMachineConfiguration;
+ }
+
+ public boolean shouldExecuteOnProject(Project project) {
+ return true;
+ }
+
+ public void decorate(Resource resource, DecoratorContext context) {
+ Measure measure = new Measure(CoreMetrics.NEW_VIOLATIONS);
+ for (int index = 0; index < 3; index++) {
+ int days = timeMachineConfiguration.getDiffPeriodInDays(index);
+ setDiffValue(measure, index, calculate(context, days));
+ }
+ context.saveMeasure(measure);
+ }
+
+ int calculate(DecoratorContext context, int days) {
+ Date targetDate = getTargetDate(context.getProject(), days);
+ int newViolations = 0;
+ for (Violation violation : context.getViolations()) {
+ if (!violation.getCreatedAt().before(targetDate)) {
+ newViolations++;
+ }
+ }
+ return newViolations;
+ }
+
+ 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.setDiffValue2(value);
+ break;
+ default:
+ break;
+ }
+ }
+
+ @Override
+ public String toString() {
+ return getClass().toString();
+ }
+}
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 0a4efdff2d1..4e219294a09 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
@@ -42,12 +42,13 @@ public final class TimeMachineConfiguration implements BatchExtension {
return configuration.getInt(CoreProperties.CORE_TENDENCY_DEPTH_PROPERTY, CoreProperties.CORE_TENDENCY_DEPTH_DEFAULT_VALUE);
}
- Snapshot getProjectSnapshotForDiffValues(int index) {
+ Integer getDiffPeriodInDays(int index) {
String property = configuration.getString("sonar.timemachine.diff" + index);
- Snapshot projectSnapshot = null;
- if (property!=null) {
- projectSnapshot = periodLocator.locate(Integer.valueOf(property));
- }
- return projectSnapshot;
+ return property == null ? null : Integer.valueOf(property);
+ }
+
+ Snapshot getProjectSnapshotForDiffValues(int index) {
+ Integer days = getDiffPeriodInDays(index);
+ return days == null ? null : periodLocator.locate(days);
}
}
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
new file mode 100644
index 00000000000..b4c82280518
--- /dev/null
+++ b/plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/timemachine/NewViolationsDecoratorTest.java
@@ -0,0 +1,42 @@
+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;
+import org.sonar.api.batch.DecoratorContext;
+import org.sonar.api.resources.Project;
+import org.sonar.api.rules.Violation;
+
+import java.util.Arrays;
+import java.util.Date;
+
+public class NewViolationsDecoratorTest {
+
+ private NewViolationsDecorator decorator;
+
+ @Before
+ public void setUp() {
+ decorator = new NewViolationsDecorator(null);
+ }
+
+ @Test
+ public void test() {
+ DecoratorContext context = mock(DecoratorContext.class);
+ 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);
+
+ assertThat(decorator.calculate(context, 10), is(1));
+ assertThat(decorator.calculate(context, 30), is(2));
+ }
+}
diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/measures/CoreMetrics.java b/sonar-plugin-api/src/main/java/org/sonar/api/measures/CoreMetrics.java
index 8ddffc1ee22..cf6cacfb657 100644
--- a/sonar-plugin-api/src/main/java/org/sonar/api/measures/CoreMetrics.java
+++ b/sonar-plugin-api/src/main/java/org/sonar/api/measures/CoreMetrics.java
@@ -297,6 +297,10 @@ public final class CoreMetrics {
public static final Metric VIOLATIONS = new Metric(VIOLATIONS_KEY, "Violations", "Violations", Metric.ValueType.INT,
Metric.DIRECTION_WORST, false, DOMAIN_RULES).setBestValue(0.0).setOptimizedBestValue(true);
+ public static final String NEW_VIOLATIONS_KEY = "new_violations";
+ public static final Metric NEW_VIOLATIONS = new Metric(NEW_VIOLATIONS_KEY, "New Violations", "New Violations", Metric.ValueType.INT,
+ Metric.DIRECTION_WORST, false, DOMAIN_RULES);
+
public static final String BLOCKER_VIOLATIONS_KEY = "blocker_violations";
public static final Metric BLOCKER_VIOLATIONS = new Metric(BLOCKER_VIOLATIONS_KEY, "Blocker violations", "Blocker violations",
Metric.ValueType.INT, Metric.DIRECTION_WORST, false, DOMAIN_RULES).setBestValue(0.0).setOptimizedBestValue(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 5ff3e96c5ae..7bd623d98e1 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
@@ -28,8 +28,7 @@ import java.util.Date;
/**
* A class to handle measures.
- * <p/>
- *
+ *
* @since 1.10
*/
public class Measure {
@@ -61,7 +60,7 @@ public class Measure {
/**
* Creates a measure with a metric
- *
+ *
* @param metric the metric
*/
public Measure(Metric metric) {
@@ -71,9 +70,9 @@ public class Measure {
/**
* Creates a measure with a metric and a value
- *
+ *
* @param metric the metric
- * @param value its value
+ * @param value its value
*/
public Measure(Metric metric, Double value) {
this.metric = metric;
@@ -83,9 +82,9 @@ public class Measure {
/**
* Creates a measure with a metric, a value and a precision for the value
- *
- * @param metric the metric
- * @param value its value
+ *
+ * @param metric the metric
+ * @param value its value
* @param precision the value precision
*/
public Measure(Metric metric, Double value, int precision) {
@@ -96,10 +95,10 @@ public class Measure {
/**
* Creates a measure with a metric, a value and a data field
- *
+ *
* @param metric the metric
- * @param value the value
- * @param data the data field
+ * @param value the value
+ * @param data the data field
*/
public Measure(Metric metric, Double value, String data) {
this.metric = metric;
@@ -110,9 +109,9 @@ public class Measure {
/**
* * Creates a measure with a metric and a data field
- *
+ *
* @param metric the metric
- * @param data the data field
+ * @param data the data field
*/
public Measure(Metric metric, String data) {
this.metric = metric;
@@ -122,9 +121,9 @@ public class Measure {
/**
* Creates a measure with a metric and an alert level
- *
+ *
* @param metric the metric
- * @param level the alert level
+ * @param level the alert level
*/
public Measure(Metric metric, Metric.Level level) {
this.metric = metric;
@@ -141,20 +140,23 @@ public class Measure {
}
/**
- * Gets the persistence mode of the measure. Default persistence mode is FULL,
- * except when instantiating the measure with a String parameter.
+ * Gets the persistence mode of the measure. Default persistence mode is FULL, except when instantiating the measure with a String
+ * parameter.
*/
public PersistenceMode getPersistenceMode() {
return persistenceMode;
}
/**
- * <p>Sets the persistence mode of a measure.</p>
- * <p><b>WARNING : </b>Being able to reuse measures saved in memory is only possible within the same tree.
- * In a multi-module project for example, a measure save in memory at the module level will not be accessible by
- * the root project. In that case, database should be used.
+ * <p>
+ * Sets the persistence mode of a measure.
* </p>
- *
+ * <p>
+ * <b>WARNING : </b>Being able to reuse measures saved in memory is only possible within the same tree. In a multi-module project for
+ * example, a measure save in memory at the module level will not be accessible by the root project. In that case, database should be
+ * used.
+ * </p>
+ *
* @param mode the mode
* @return the measure object instance
*/
@@ -176,7 +178,7 @@ public class Measure {
/**
* Set the underlying metric
- *
+ *
* @param metric the metric
* @return the measure object instance
*/
@@ -205,7 +207,7 @@ public class Measure {
/**
* Sets the date of the measure - Used only in TimeMachine queries
- *
+ *
* @param date the date
* @return the measure object instance
*/
@@ -233,7 +235,7 @@ public class Measure {
/**
* Sets the measure value with the default precision of 1
- *
+ *
* @param v the measure value
* @return the measure object instance
*/
@@ -243,7 +245,7 @@ public class Measure {
/**
* Sets the measure value as an int
- *
+ *
* @param i the value
* @return the measure object instance
*/
@@ -258,8 +260,8 @@ public class Measure {
/**
* Sets the measure value with a given precision
- *
- * @param v the measure value
+ *
+ * @param v the measure value
* @param precision the measure value precision
* @return the measure object instance
*/
@@ -289,7 +291,7 @@ public class Measure {
/**
* Sets the data field of the measure.
- *
+ *
* @param s the data
* @return the measure object instance
*/
@@ -303,7 +305,7 @@ public class Measure {
/**
* Sets an alert level as the data field
- *
+ *
* @param level the alert level
* @return the measure object instance
*/
@@ -325,7 +327,7 @@ public class Measure {
/**
* Sets the measure description
- *
+ *
* @param description the description
* @return the measure object instance
*/
@@ -343,7 +345,7 @@ public class Measure {
/**
* Set the alert status of the measure
- *
+ *
* @param status the status
* @return the measure object instance
*/
@@ -361,7 +363,7 @@ public class Measure {
/**
* Sets the text associated to the alert on the measure
- *
+ *
* @param alertText the text
* @return the measure object instance
*/
@@ -372,7 +374,7 @@ public class Measure {
/**
* Gets the measure tendency
- *
+ *
* @return the tendency
*/
public Integer getTendency() {
@@ -381,7 +383,7 @@ public class Measure {
/**
* Sets the tendency for the measure
- *
+ *
* @param tendency the tendency
* @return the measure object instance
*/
@@ -399,7 +401,7 @@ public class Measure {
/**
* Sets the measure id - Internal use only
- *
+ *
* @param id the id
* @return the measure object instance
*/
@@ -417,7 +419,7 @@ public class Measure {
/**
* Sets the first differential value of the measure
- *
+ *
* @param diff1 the diff
* @return the measure object instance
*/
@@ -435,7 +437,7 @@ public class Measure {
/**
* Sets the second differential value of the measure
- *
+ *
* @param diff2 the diff
* @return the measure object instance
*/
@@ -453,7 +455,7 @@ public class Measure {
/**
* Sets the third differential value of the measure
- *
+ *
* @param diff3 the diff
* @return the measure object instance
*/
@@ -471,7 +473,7 @@ public class Measure {
/**
* Sets the URL of the measure
- *
+ *
* @param url the url
* @return the measure object instance
*/
@@ -489,7 +491,6 @@ public class Measure {
return this;
}
-
@Override
public boolean equals(Object o) {
if (this == o) {
diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/rules/Violation.java b/sonar-plugin-api/src/main/java/org/sonar/api/rules/Violation.java
index 8230154d966..6b8eaa7fe3e 100644
--- a/sonar-plugin-api/src/main/java/org/sonar/api/rules/Violation.java
+++ b/sonar-plugin-api/src/main/java/org/sonar/api/rules/Violation.java
@@ -161,8 +161,9 @@ public class Violation {
/**
* @since 2.5
*/
- public void setCreatedAt(Date createdAt) {
+ public Violation setCreatedAt(Date createdAt) {
this.createdAt = createdAt;
+ return this;
}
@Override