aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/timemachine/VariationDecorator.java14
-rw-r--r--plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/timemachine/VariationDecoratorTest.java14
-rw-r--r--sonar-batch/src/main/java/org/sonar/batch/DefaultTimeMachine.java10
-rw-r--r--sonar-batch/src/main/java/org/sonar/batch/components/PastMeasuresLoader.java13
-rw-r--r--sonar-batch/src/main/java/org/sonar/batch/index/MeasurePersister.java1
-rw-r--r--sonar-batch/src/test/java/org/sonar/batch/components/PastMeasuresLoaderTest.java7
-rw-r--r--sonar-plugin-api/src/main/java/org/sonar/api/database/model/MeasureModel.java17
-rw-r--r--sonar-plugin-api/src/main/java/org/sonar/api/measures/Measure.java25
-rw-r--r--sonar-plugin-api/src/main/java/org/sonar/api/measures/MeasuresFilters.java3
-rw-r--r--sonar-server/src/main/java/org/sonar/server/filters/FilterExecutor.java5
10 files changed, 85 insertions, 24 deletions
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 b3a5d258121..dab6531f557 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
@@ -98,9 +98,10 @@ public class VariationDecorator implements Decorator {
// compare with past measure
Integer metricId = (measure.getMetric().getId() != null ? measure.getMetric().getId() : metricFinder.findByKey(measure.getMetric().getKey()).getId());
Integer characteristicId = (measure.getCharacteristic() != null ? measure.getCharacteristic().getId() : null);
+ String committer = measure.getCommitter();
Integer ruleId = (measure instanceof RuleMeasure ? ((RuleMeasure)measure).getRule().getId() : null);
- Object[] pastMeasure = pastMeasuresByKey.get(new MeasureKey(metricId, characteristicId, ruleId));
+ Object[] pastMeasure = pastMeasuresByKey.get(new MeasureKey(metricId, characteristicId, committer, ruleId));
if (updateVariation(measure, pastMeasure, index)) {
context.saveMeasure(measure);
}
@@ -124,17 +125,20 @@ public class VariationDecorator implements Decorator {
static final class MeasureKey {
int metricId;
Integer characteristicId;
+ String committer;
Integer ruleId;
MeasureKey(Object[] pastFields) {
metricId = PastMeasuresLoader.getMetricId(pastFields);
characteristicId = PastMeasuresLoader.getCharacteristicId(pastFields);
+ committer = PastMeasuresLoader.getCommitter(pastFields);
ruleId = PastMeasuresLoader.getRuleId(pastFields);
}
- MeasureKey(int metricId, Integer characteristicId, Integer ruleId) {
+ MeasureKey(int metricId, Integer characteristicId, String committer, Integer ruleId) {
this.metricId = metricId;
this.characteristicId = characteristicId;
+ this.committer = committer;
this.ruleId = ruleId;
}
@@ -153,6 +157,9 @@ public class VariationDecorator implements Decorator {
if (characteristicId != null ? !characteristicId.equals(that.characteristicId) : that.characteristicId != null) {
return false;
}
+ if (committer != null ? !committer.equals(that.committer) : that.committer != null) {
+ return false;
+ }
if (ruleId != null ? !ruleId.equals(that.ruleId) : that.ruleId != null) {
return false;
}
@@ -163,8 +170,9 @@ public class VariationDecorator implements Decorator {
public int hashCode() {
int result = metricId;
result = 31 * result + (characteristicId != null ? characteristicId.hashCode() : 0);
+ result = 31 * result + (committer != null ? committer.hashCode() : 0);
result = 31 * result + (ruleId != null ? ruleId.hashCode() : 0);
return result;
}
}
-} \ No newline at end of file
+}
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 35d5e524d3c..9ac297f1d28 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
@@ -23,11 +23,9 @@ import org.junit.Test;
import org.mockito.Matchers;
import org.sonar.api.CoreProperties;
import org.sonar.api.batch.DecoratorContext;
-import org.sonar.api.database.model.MeasureModel;
import org.sonar.api.measures.*;
import org.sonar.api.resources.*;
import org.sonar.api.rules.Rule;
-import org.sonar.api.rules.RulePriority;
import org.sonar.batch.components.PastMeasuresLoader;
import org.sonar.batch.components.PastSnapshot;
import org.sonar.batch.components.TimeMachineConfiguration;
@@ -100,12 +98,12 @@ public class VariationDecoratorTest extends AbstractDbUnitTestCase {
// first past analysis
when(pastMeasuresLoader.getPastMeasures(javaPackage, pastSnapshot1)).thenReturn(Arrays.asList(
- new Object[]{NCLOC_ID, null, null, 180.0},
- new Object[]{COVERAGE_ID, null, null, 75.0}));
+ new Object[] {NCLOC_ID, null, null, null, 180.0},
+ new Object[] {COVERAGE_ID, null, null, null, 75.0}));
// second past analysis
when(pastMeasuresLoader.getPastMeasures(javaPackage, pastSnapshot3)).thenReturn(Arrays.<Object[]>asList(
- new Object[]{NCLOC_ID, null, null, 240.0}));
+ new Object[] {NCLOC_ID, null, null, null, 240.0}));
// current analysis
DecoratorContext context = mock(DecoratorContext.class);
@@ -142,9 +140,9 @@ public class VariationDecoratorTest extends AbstractDbUnitTestCase {
// first past analysis
when(pastMeasuresLoader.getPastMeasures(javaPackage, pastSnapshot1)).thenReturn(Arrays.asList(
- new Object[]{VIOLATIONS_ID, null, null, 180.0},//total
- new Object[]{VIOLATIONS_ID, null, rule1.getId(), 100.0},// rule 1
- new Object[]{VIOLATIONS_ID, null, rule2.getId(), 80.0})); // rule 2
+ new Object[] {VIOLATIONS_ID, null, null, null, 180.0},// total
+ new Object[] {VIOLATIONS_ID, null, null, rule1.getId(), 100.0},// rule 1
+ new Object[] {VIOLATIONS_ID, null, null, rule2.getId(), 80.0})); // rule 2
// current analysis
DecoratorContext context = mock(DecoratorContext.class);
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 fce98a19737..326dfbb9b2d 100644
--- a/sonar-batch/src/main/java/org/sonar/batch/DefaultTimeMachine.java
+++ b/sonar-batch/src/main/java/org/sonar/batch/DefaultTimeMachine.java
@@ -34,6 +34,7 @@ import org.sonar.api.resources.Resource;
import org.sonar.batch.index.DefaultIndex;
import javax.persistence.Query;
+
import java.util.*;
public class DefaultTimeMachine implements TimeMachine {
@@ -93,12 +94,14 @@ public class DefaultTimeMachine implements TimeMachine {
.append(MeasureModel.class.getSimpleName())
.append(" m, ")
.append(Snapshot.class.getSimpleName())
- .append(" s WHERE m.snapshotId=s.id AND s.resourceId=:resourceId AND s.status=:status AND m.characteristic IS NULL AND s.qualifier<>:lib");
+ .append(" s WHERE m.snapshotId=s.id AND s.resourceId=:resourceId AND s.status=:status AND s.qualifier<>:lib");
params.put("resourceId", resource.getId());
params.put("status", Snapshot.STATUS_PROCESSED);
params.put("lib", Qualifiers.LIBRARY);
- sb.append(" AND m.ruleId IS NULL AND m.rulePriority IS NULL ");
+ sb.append(" AND m.characteristic IS NULL");
+ sb.append(" AND m.committer IS NULL");
+ sb.append(" AND m.ruleId IS NULL AND m.rulePriority IS NULL");
if (!metricIds.isEmpty()) {
sb.append(" AND m.metricId IN (:metricIds) ");
params.put("metricIds", metricIds);
@@ -159,6 +162,7 @@ public class DefaultTimeMachine implements TimeMachine {
measure.setVariation5(model.getVariationValue5());
measure.setUrl(model.getUrl());
measure.setCharacteristic(model.getCharacteristic());
+ measure.setCommitter(model.getCommitter());
return measure;
}
-} \ No newline at end of file
+}
diff --git a/sonar-batch/src/main/java/org/sonar/batch/components/PastMeasuresLoader.java b/sonar-batch/src/main/java/org/sonar/batch/components/PastMeasuresLoader.java
index a04a0311f0b..7b2560a3e28 100644
--- a/sonar-batch/src/main/java/org/sonar/batch/components/PastMeasuresLoader.java
+++ b/sonar-batch/src/main/java/org/sonar/batch/components/PastMeasuresLoader.java
@@ -65,7 +65,7 @@ public class PastMeasuresLoader implements BatchExtension {
}
public List<Object[]> getPastMeasures(String resourceKey, Snapshot projectPastSnapshot) {
- String sql = "select m.metric_id, m.characteristic_id, m.rule_id, m.value from project_measures m, snapshots s" +
+ String sql = "select m.metric_id, m.characteristic_id, m.committer, m.rule_id, m.value from project_measures m, snapshots s" +
" where m.snapshot_id=s.id and m.metric_id in (:metricIds) " +
" and (s.root_snapshot_id=:rootSnapshotId or s.id=:rootSnapshotId) " +
" and s.status=:status and s.project_id=(select p.id from projects p where p.kee=:resourceKey and p.qualifier<>:lib)";
@@ -89,17 +89,22 @@ public class PastMeasuresLoader implements BatchExtension {
return number != null ? number.intValue() : null;
}
+ public static String getCommitter(Object[] row) {
+ return (String) row[2];
+ }
+
public static Integer getRuleId(Object[] row) {
// can be BigDecimal on Oracle
- Number number = (Number) row[2];
+ Number number = (Number) row[3];
return number != null ? number.intValue() : null;
}
public static boolean hasValue(Object[] row) {
- return row[3] != null;
+ return row[4] != null;
}
public static double getValue(Object[] row) {
- return ((Number) row[3]).doubleValue();
+ return ((Number) row[4]).doubleValue();
}
+
}
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 1f0326c55a1..620519345f0 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
@@ -150,6 +150,7 @@ public final class MeasurePersister {
merge.setVariationValue5(measure.getVariation5());
merge.setUrl(measure.getUrl());
merge.setCharacteristic(measure.getCharacteristic());
+ merge.setCommitter(measure.getCommitter());
if (measure.getValue() != null) {
merge.setValue(measure.getValue().doubleValue());
} else {
diff --git a/sonar-batch/src/test/java/org/sonar/batch/components/PastMeasuresLoaderTest.java b/sonar-batch/src/test/java/org/sonar/batch/components/PastMeasuresLoaderTest.java
index 5d56fde9600..5c4e9638507 100644
--- a/sonar-batch/src/test/java/org/sonar/batch/components/PastMeasuresLoaderTest.java
+++ b/sonar-batch/src/test/java/org/sonar/batch/components/PastMeasuresLoaderTest.java
@@ -27,7 +27,6 @@ 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.hamcrest.Matchers.nullValue;
@@ -53,11 +52,13 @@ public class PastMeasuresLoaderTest extends AbstractDbUnitTestCase {
Object[] pastMeasure = measures.get(0);
assertThat(PastMeasuresLoader.getMetricId(pastMeasure), is(1));
assertThat(PastMeasuresLoader.getCharacteristicId(pastMeasure), nullValue());
+ assertThat(PastMeasuresLoader.getCommitter(pastMeasure), nullValue());
assertThat(PastMeasuresLoader.getValue(pastMeasure), is(5.0));
pastMeasure = measures.get(1);
assertThat(PastMeasuresLoader.getMetricId(pastMeasure), is(2));
assertThat(PastMeasuresLoader.getCharacteristicId(pastMeasure), nullValue());
+ assertThat(PastMeasuresLoader.getCommitter(pastMeasure), nullValue());
assertThat(PastMeasuresLoader.getValue(pastMeasure), is(60.0));
}
@@ -75,11 +76,13 @@ public class PastMeasuresLoaderTest extends AbstractDbUnitTestCase {
Object[] pastMeasure = measures.get(0);
assertThat(PastMeasuresLoader.getMetricId(pastMeasure), is(1));
assertThat(PastMeasuresLoader.getCharacteristicId(pastMeasure), nullValue());
+ assertThat(PastMeasuresLoader.getCommitter(pastMeasure), nullValue());
assertThat(PastMeasuresLoader.getValue(pastMeasure), is(60.0));
pastMeasure = measures.get(1);
assertThat(PastMeasuresLoader.getMetricId(pastMeasure), is(2));
assertThat(PastMeasuresLoader.getCharacteristicId(pastMeasure), nullValue());
+ assertThat(PastMeasuresLoader.getCommitter(pastMeasure), nullValue());
assertThat(PastMeasuresLoader.getValue(pastMeasure), is(80.0));
}
@@ -94,7 +97,7 @@ public class PastMeasuresLoaderTest extends AbstractDbUnitTestCase {
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));
}
diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/database/model/MeasureModel.java b/sonar-plugin-api/src/main/java/org/sonar/api/database/model/MeasureModel.java
index 739c6dfc423..f63e730af76 100644
--- a/sonar-plugin-api/src/main/java/org/sonar/api/database/model/MeasureModel.java
+++ b/sonar-plugin-api/src/main/java/org/sonar/api/database/model/MeasureModel.java
@@ -27,6 +27,7 @@ import org.sonar.api.qualitymodel.Characteristic;
import org.sonar.api.rules.RulePriority;
import javax.persistence.*;
+
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
@@ -115,6 +116,9 @@ public class MeasureModel implements Cloneable {
@JoinColumn(name = "characteristic_id")
private Characteristic characteristic;
+ @Column(name = "committer", updatable = true, nullable = true, length = 100)
+ private String committer;
+
public Long getId() {
return id;
}
@@ -122,7 +126,7 @@ public class MeasureModel implements Cloneable {
public void setId(Long id) {
this.id = id;
}
-
+
/**
* Creates a measure based on a metric and a double value
*/
@@ -518,6 +522,15 @@ public class MeasureModel implements Cloneable {
return this;
}
+ public String getCommitter() {
+ return committer;
+ }
+
+ public MeasureModel setCommitter(String committer) {
+ this.committer = committer;
+ return this;
+ }
+
@Override
public Object clone() {
MeasureModel clone = new MeasureModel();
@@ -539,6 +552,8 @@ public class MeasureModel implements Cloneable {
clone.setMeasureDate(getMeasureDate());
clone.setUrl(getUrl());
clone.setCharacteristic(getCharacteristic());
+ clone.setCommitter(getCommitter());
return clone;
}
+
}
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 1b1c4134ecd..61497f07af3 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
@@ -19,6 +19,7 @@
*/
package org.sonar.api.measures;
+import com.google.common.annotations.Beta;
import org.apache.commons.lang.builder.ReflectionToStringBuilder;
import org.sonar.api.qualitymodel.Characteristic;
@@ -52,6 +53,7 @@ public class Measure {
protected Double variation1, variation2, variation3, variation4, variation5;
protected String url;
protected Characteristic characteristic;
+ protected String committer;
protected PersistenceMode persistenceMode = PersistenceMode.FULL;
public Measure(String metricKey) {
@@ -329,7 +331,7 @@ public class Measure {
this.data=null;
return this;
}
-
+
/**
* @return the description of the measure
*/
@@ -593,6 +595,23 @@ public class Measure {
return this;
}
+ /**
+ * @since 2.14
+ */
+ @Beta
+ public String getCommitter() {
+ return committer;
+ }
+
+ /**
+ * @since 2.14
+ */
+ @Beta
+ public Measure setCommitter(String committer) {
+ this.committer = committer;
+ return this;
+ }
+
@Override
public boolean equals(Object o) {
if (this == o) {
@@ -609,6 +628,9 @@ public class Measure {
if (characteristic != null ? !characteristic.equals(measure.characteristic) : measure.characteristic != null) {
return false;
}
+ if (committer != null ? !committer.equals(measure.committer) : measure.committer != null) {
+ return false;
+ }
return true;
}
@@ -616,6 +638,7 @@ public class Measure {
public int hashCode() {
int result = metricKey != null ? metricKey.hashCode() : 0;
result = 31 * result + (characteristic != null ? characteristic.hashCode() : 0);
+ result = 31 * result + (committer != null ? committer.hashCode() : 0);
return result;
}
diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/measures/MeasuresFilters.java b/sonar-plugin-api/src/main/java/org/sonar/api/measures/MeasuresFilters.java
index 9a975e48cbe..bf4e1964f15 100644
--- a/sonar-plugin-api/src/main/java/org/sonar/api/measures/MeasuresFilters.java
+++ b/sonar-plugin-api/src/main/java/org/sonar/api/measures/MeasuresFilters.java
@@ -57,7 +57,8 @@ public final class MeasuresFilters {
for (Measure measure : measures) {
if (measure.getClass().equals(Measure.class) &&
measure.getMetricKey().equals(metricKey) &&
- measure.getCharacteristic() == null) {
+ measure.getCharacteristic() == null &&
+ measure.getCommitter() == null) {
return measure;
}
}
diff --git a/sonar-server/src/main/java/org/sonar/server/filters/FilterExecutor.java b/sonar-server/src/main/java/org/sonar/server/filters/FilterExecutor.java
index fc820ed90ca..6dba0c4fa01 100644
--- a/sonar-server/src/main/java/org/sonar/server/filters/FilterExecutor.java
+++ b/sonar-server/src/main/java/org/sonar/server/filters/FilterExecutor.java
@@ -147,7 +147,10 @@ public class FilterExecutor implements ServerComponent {
sql.append(" ) AND ");
}
- sql.append(" pm.rule_id is null AND pm.rule_priority is null AND pm.characteristic_id IS NULL AND ");
+ sql.append(" pm.rule_id IS NULL AND pm.rule_priority IS NULL");
+ sql.append(" AND pm.characteristic_id IS NULL");
+ sql.append(" AND pm.committer IS NULL");
+ sql.append(" AND ");
}
sql.append(" s.status=:status AND s.islast=:islast ");
if (filter.getScopes() != null) {