]> source.dussan.org Git - sonarqube.git/commitdiff
Rework new measure API 457/head
authorJulien HENRY <julien.henry@sonarsource.com>
Tue, 4 Aug 2015 08:23:52 +0000 (10:23 +0200)
committerJulien HENRY <julien.henry@sonarsource.com>
Tue, 4 Aug 2015 13:53:02 +0000 (15:53 +0200)
16 files changed:
plugins/sonar-xoo-plugin/src/main/java/org/sonar/xoo/lang/MeasureSensor.java
sonar-batch/src/main/java/org/sonar/batch/cpd/JavaCpdEngine.java
sonar-batch/src/main/java/org/sonar/batch/index/BatchComponentCache.java
sonar-batch/src/main/java/org/sonar/batch/sensor/DefaultSensorStorage.java
sonar-batch/src/main/java/org/sonar/batch/source/LinesSensor.java
sonar-batch/src/test/java/org/sonar/batch/cpd/JavaCpdEngineTest.java
sonar-batch/src/test/java/org/sonar/batch/sensor/DefaultSensorStorageTest.java
sonar-plugin-api/src/main/java/org/sonar/api/batch/fs/InputComponent.java
sonar-plugin-api/src/main/java/org/sonar/api/batch/fs/internal/DefaultInputComponent.java
sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/internal/SensorContextTester.java
sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/issue/internal/DefaultIssueLocation.java
sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/measure/Measure.java
sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/measure/NewMeasure.java
sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/measure/internal/DefaultMeasure.java
sonar-plugin-api/src/test/java/org/sonar/api/batch/sensor/internal/SensorContextTesterTest.java
sonar-plugin-api/src/test/java/org/sonar/api/batch/sensor/measure/internal/DefaultMeasureTest.java

index ca06e245d68a097a1a729a6bdd02a89999387504..7b6506cb334aa8a5a9eb0a79141fc7931356da4e 100644 (file)
  */
 package org.sonar.xoo.lang;
 
+import java.io.File;
+import java.io.IOException;
+import java.io.Serializable;
+import java.util.List;
 import org.apache.commons.io.FileUtils;
 import org.apache.commons.lang3.StringUtils;
 import org.sonar.api.batch.fs.InputFile;
@@ -31,11 +35,6 @@ import org.sonar.api.utils.log.Logger;
 import org.sonar.api.utils.log.Loggers;
 import org.sonar.xoo.Xoo;
 
-import java.io.File;
-import java.io.IOException;
-import java.io.Serializable;
-import java.util.List;
-
 /**
  * Parse files *.xoo.measures
  */
@@ -89,7 +88,7 @@ public class MeasureSensor implements Sensor {
     }
     NewMeasure<Serializable> newMeasure = context.newMeasure()
       .forMetric(metric)
-      .onFile(xooFile);
+      .on(xooFile);
     if (Boolean.class.equals(metric.valueType())) {
       newMeasure.withValue(Boolean.parseBoolean(value));
     } else if (Integer.class.equals(metric.valueType())) {
index f705f249e6ed983aae45794643f73ee921b5afcb..97059241af5d5427531472182620a743e65c221a 100644 (file)
@@ -207,19 +207,19 @@ public class JavaCpdEngine extends CpdEngine {
     // Save
     ((DefaultMeasure<Integer>) context.<Integer>newMeasure()
       .forMetric(CoreMetrics.DUPLICATED_FILES)
-      .onFile(inputFile)
+      .on(inputFile)
       .withValue(1))
       .setFromCore()
       .save();
     ((DefaultMeasure<Integer>) context.<Integer>newMeasure()
       .forMetric(CoreMetrics.DUPLICATED_LINES)
-      .onFile(inputFile)
+      .on(inputFile)
       .withValue(duplicatedLines))
       .setFromCore()
       .save();
     ((DefaultMeasure<Integer>) context.<Integer>newMeasure()
       .forMetric(CoreMetrics.DUPLICATED_BLOCKS)
-      .onFile(inputFile)
+      .on(inputFile)
       .withValue(duplicatedBlocks))
       .setFromCore()
       .save();
index 67c7b28c38e4120ac051ef4fcf4ebb38764b0789..f1370167fbb77a1ac9bdf04cf8d1e17e8d5e9264 100644 (file)
@@ -27,9 +27,7 @@ import java.util.Map;
 import javax.annotation.CheckForNull;
 import javax.annotation.Nullable;
 import org.sonar.api.batch.BatchSide;
-import org.sonar.api.batch.fs.InputPath;
-import org.sonar.api.batch.fs.internal.DefaultInputDir;
-import org.sonar.api.batch.fs.internal.DefaultInputFile;
+import org.sonar.api.batch.fs.InputComponent;
 import org.sonar.api.resources.Resource;
 
 @BatchSide
@@ -48,11 +46,8 @@ public class BatchComponentCache {
     return components.get(resource.getEffectiveKey());
   }
 
-  public BatchComponent get(InputPath inputPath) {
-    if (inputPath instanceof DefaultInputFile) {
-      return components.get(((DefaultInputFile) inputPath).key());
-    }
-    return components.get(((DefaultInputDir) inputPath).key());
+  public BatchComponent get(InputComponent inputComponent) {
+    return components.get(inputComponent.key());
   }
 
   public BatchComponent add(Resource resource, @Nullable Resource parentResource) {
index adacbb995466d7305a9e6abb8f9bd7610c76c79f..8cef84ace5b71760386b5562264c8e6f3c49d08c 100644 (file)
@@ -29,6 +29,7 @@ import javax.annotation.Nonnull;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.sonar.api.batch.fs.FileSystem;
+import org.sonar.api.batch.fs.InputComponent;
 import org.sonar.api.batch.fs.InputFile;
 import org.sonar.api.batch.fs.TextRange;
 import org.sonar.api.batch.fs.internal.DefaultInputFile;
@@ -48,7 +49,6 @@ import org.sonar.api.config.Settings;
 import org.sonar.api.measures.CoreMetrics;
 import org.sonar.api.measures.Metric;
 import org.sonar.api.resources.File;
-import org.sonar.api.resources.Project;
 import org.sonar.api.resources.Resource;
 import org.sonar.api.source.Symbol;
 import org.sonar.api.utils.KeyValueFormat;
@@ -92,7 +92,6 @@ public class DefaultSensorStorage implements SensorStorage {
     CoreMetrics.DUPLICATIONS_DATA_KEY);
 
   private final MetricFinder metricFinder;
-  private final Project project;
   private final ModuleIssues moduleIssues;
   private final CoverageExclusions coverageExclusions;
   private final DuplicationCache duplicationCache;
@@ -100,11 +99,10 @@ public class DefaultSensorStorage implements SensorStorage {
   private final ReportPublisher reportPublisher;
   private final MeasureCache measureCache;
 
-  public DefaultSensorStorage(MetricFinder metricFinder, Project project, ModuleIssues moduleIssues,
+  public DefaultSensorStorage(MetricFinder metricFinder, ModuleIssues moduleIssues,
     Settings settings, FileSystem fs, ActiveRules activeRules, DuplicationCache duplicationCache,
     CoverageExclusions coverageExclusions, BatchComponentCache resourceCache, ReportPublisher reportPublisher, MeasureCache measureCache) {
     this.metricFinder = metricFinder;
-    this.project = project;
     this.moduleIssues = moduleIssues;
     this.coverageExclusions = coverageExclusions;
     this.duplicationCache = duplicationCache;
@@ -128,14 +126,10 @@ public class DefaultSensorStorage implements SensorStorage {
     org.sonar.api.measures.Measure measureToSave = new org.sonar.api.measures.Measure(m);
     setValueAccordingToMetricType(newMeasure, m, measureToSave);
     measureToSave.setFromCore(measure.isFromCore());
-    InputFile inputFile = newMeasure.inputFile();
-    if (inputFile != null) {
-      File sonarFile = getFile(inputFile);
-      if (coverageExclusions.accept(sonarFile, measureToSave)) {
-        saveMeasure(sonarFile, measureToSave);
-      }
-    } else {
-      saveMeasure(project, measureToSave);
+    InputComponent inputComponent = newMeasure.inputComponent();
+    Resource resource = resourceCache.get(inputComponent).resource();
+    if (coverageExclusions.accept(resource, measureToSave)) {
+      saveMeasure(resource, measureToSave);
     }
   }
 
index a38d5c2df4faa191c7ebe1ce41a4e27d803fd672..cce62e7fcfb34ba552eadd8b2d0f5e999573825a 100644 (file)
@@ -43,24 +43,24 @@ public final class LinesSensor implements Sensor {
     FileSystem fs = context.fileSystem();
     for (InputFile f : fs.inputFiles(fs.predicates().hasType(Type.MAIN))) {
       ((DefaultMeasure<Integer>) context.<Integer>newMeasure()
-        .onFile(f)
+        .on(f)
         .forMetric(CoreMetrics.LINES)
         .withValue(f.lines()))
-        .setFromCore()
-        .save();
+          .setFromCore()
+          .save();
       if (f.language() == null) {
         // As an approximation for files with no language plugin we consider every non blank line as ncloc
         ((DefaultMeasure<Integer>) context.<Integer>newMeasure()
-          .onFile(f)
+          .on(f)
           .forMetric(CoreMetrics.NCLOC)
           .withValue(((DefaultInputFile) f).nonBlankLines()))
-          .save();
+            .save();
         // No test and no coverage on those files
         ((DefaultMeasure<Integer>) context.<Integer>newMeasure()
-          .onFile(f)
+          .on(f)
           .forMetric(CoreMetrics.LINES_TO_COVER)
           .withValue(0))
-          .save();
+            .save();
       }
     }
   }
index 71d80a37c5b737c389277b49911161162c016c35..f3b802da8e6dfdb1dbf1352fa1111141ea8791d4 100644 (file)
  */
 package org.sonar.batch.cpd;
 
+import java.io.IOException;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
 import org.junit.Before;
 import org.junit.Rule;
 import org.junit.Test;
@@ -36,11 +40,6 @@ import org.sonar.api.measures.CoreMetrics;
 import org.sonar.duplications.index.CloneGroup;
 import org.sonar.duplications.index.ClonePart;
 
-import java.io.IOException;
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.List;
-
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.verifyZeroInteractions;
@@ -88,9 +87,9 @@ public class JavaCpdEngineTest {
     List<CloneGroup> groups = Arrays.asList(newCloneGroup(new ClonePart("key1", 0, 2, 4), new ClonePart("key2", 0, 15, 17)));
     JavaCpdEngine.save(context, inputFile, groups);
 
-    verify(storage).store(new DefaultMeasure().forMetric(CoreMetrics.DUPLICATED_FILES).onFile(inputFile).withValue(1));
-    verify(storage).store(new DefaultMeasure().forMetric(CoreMetrics.DUPLICATED_BLOCKS).onFile(inputFile).withValue(1));
-    verify(storage).store(new DefaultMeasure().forMetric(CoreMetrics.DUPLICATED_LINES).onFile(inputFile).withValue(3));
+    verify(storage).store(new DefaultMeasure().forMetric(CoreMetrics.DUPLICATED_FILES).on(inputFile).withValue(1));
+    verify(storage).store(new DefaultMeasure().forMetric(CoreMetrics.DUPLICATED_BLOCKS).on(inputFile).withValue(1));
+    verify(storage).store(new DefaultMeasure().forMetric(CoreMetrics.DUPLICATED_LINES).on(inputFile).withValue(3));
 
     verify(storage).store(new DefaultDuplication()
       .originBlock(inputFile, 2, 4)
@@ -102,9 +101,9 @@ public class JavaCpdEngineTest {
     List<CloneGroup> groups = Arrays.asList(newCloneGroup(new ClonePart("key1", 0, 5, 204), new ClonePart("key1", 0, 215, 414)));
     JavaCpdEngine.save(context, inputFile, groups);
 
-    verify(storage).store(new DefaultMeasure().forMetric(CoreMetrics.DUPLICATED_FILES).onFile(inputFile).withValue(1));
-    verify(storage).store(new DefaultMeasure().forMetric(CoreMetrics.DUPLICATED_BLOCKS).onFile(inputFile).withValue(2));
-    verify(storage).store(new DefaultMeasure().forMetric(CoreMetrics.DUPLICATED_LINES).onFile(inputFile).withValue(400));
+    verify(storage).store(new DefaultMeasure().forMetric(CoreMetrics.DUPLICATED_FILES).on(inputFile).withValue(1));
+    verify(storage).store(new DefaultMeasure().forMetric(CoreMetrics.DUPLICATED_BLOCKS).on(inputFile).withValue(2));
+    verify(storage).store(new DefaultMeasure().forMetric(CoreMetrics.DUPLICATED_LINES).on(inputFile).withValue(400));
 
     verify(storage).store(new DefaultDuplication()
       .originBlock(inputFile, 5, 204)
@@ -116,9 +115,9 @@ public class JavaCpdEngineTest {
     List<CloneGroup> groups = Arrays.asList(newCloneGroup(new ClonePart("key1", 0, 5, 204), new ClonePart("key2", 0, 15, 214), new ClonePart("key3", 0, 25, 224)));
     JavaCpdEngine.save(context, inputFile, groups);
 
-    verify(storage).store(new DefaultMeasure().forMetric(CoreMetrics.DUPLICATED_FILES).onFile(inputFile).withValue(1));
-    verify(storage).store(new DefaultMeasure().forMetric(CoreMetrics.DUPLICATED_BLOCKS).onFile(inputFile).withValue(1));
-    verify(storage).store(new DefaultMeasure().forMetric(CoreMetrics.DUPLICATED_LINES).onFile(inputFile).withValue(200));
+    verify(storage).store(new DefaultMeasure().forMetric(CoreMetrics.DUPLICATED_FILES).on(inputFile).withValue(1));
+    verify(storage).store(new DefaultMeasure().forMetric(CoreMetrics.DUPLICATED_BLOCKS).on(inputFile).withValue(1));
+    verify(storage).store(new DefaultMeasure().forMetric(CoreMetrics.DUPLICATED_LINES).on(inputFile).withValue(200));
 
     verify(storage).store(new DefaultDuplication()
       .originBlock(inputFile, 5, 204)
@@ -133,9 +132,9 @@ public class JavaCpdEngineTest {
       newCloneGroup(new ClonePart("key1", 0, 15, 214), new ClonePart("key3", 0, 15, 214)));
     JavaCpdEngine.save(context, inputFile, groups);
 
-    verify(storage).store(new DefaultMeasure().forMetric(CoreMetrics.DUPLICATED_FILES).onFile(inputFile).withValue(1));
-    verify(storage).store(new DefaultMeasure().forMetric(CoreMetrics.DUPLICATED_BLOCKS).onFile(inputFile).withValue(2));
-    verify(storage).store(new DefaultMeasure().forMetric(CoreMetrics.DUPLICATED_LINES).onFile(inputFile).withValue(210));
+    verify(storage).store(new DefaultMeasure().forMetric(CoreMetrics.DUPLICATED_FILES).on(inputFile).withValue(1));
+    verify(storage).store(new DefaultMeasure().forMetric(CoreMetrics.DUPLICATED_BLOCKS).on(inputFile).withValue(2));
+    verify(storage).store(new DefaultMeasure().forMetric(CoreMetrics.DUPLICATED_LINES).on(inputFile).withValue(210));
 
     verify(storage).store(new DefaultDuplication()
       .originBlock(inputFile, 5, 204)
index 3ad99b57f3151d0e8456699fdf250fb6a203862e..85ccba5628bfd447be83d4e68fd8b99837a93a15 100644 (file)
@@ -28,6 +28,7 @@ import org.mockito.ArgumentCaptor;
 import org.sonar.api.batch.fs.InputFile;
 import org.sonar.api.batch.fs.internal.DefaultFileSystem;
 import org.sonar.api.batch.fs.internal.DefaultInputFile;
+import org.sonar.api.batch.fs.internal.DefaultInputModule;
 import org.sonar.api.batch.measure.MetricFinder;
 import org.sonar.api.batch.rule.ActiveRules;
 import org.sonar.api.batch.rule.internal.ActiveRulesBuilder;
@@ -83,7 +84,7 @@ public class DefaultSensorStorageTest {
     CoverageExclusions coverageExclusions = mock(CoverageExclusions.class);
     when(coverageExclusions.accept(any(Resource.class), any(Measure.class))).thenReturn(true);
     resourceCache = new BatchComponentCache();
-    sensorStorage = new DefaultSensorStorage(metricFinder, project,
+    sensorStorage = new DefaultSensorStorage(metricFinder,
       moduleIssues, settings, fs, activeRules, mock(DuplicationCache.class), coverageExclusions, resourceCache, mock(ReportPublisher.class), measureCache);
   }
 
@@ -95,7 +96,7 @@ public class DefaultSensorStorageTest {
     thrown.expectMessage("Unknow metric with key: lines");
 
     sensorStorage.store(new DefaultMeasure()
-      .onFile(file)
+      .on(file)
       .forMetric(CoreMetrics.LINES)
       .withValue(10));
   }
@@ -109,7 +110,7 @@ public class DefaultSensorStorageTest {
     resourceCache.add(sonarFile, null).setInputComponent(file);
     when(measureCache.put(eq(sonarFile), argumentCaptor.capture())).thenReturn(null);
     sensorStorage.store(new DefaultMeasure()
-      .onFile(file)
+      .on(file)
       .forMetric(CoreMetrics.NCLOC)
       .withValue(10));
 
@@ -120,12 +121,14 @@ public class DefaultSensorStorageTest {
 
   @Test
   public void shouldSaveProjectMeasureToSensorContext() {
+    DefaultInputModule module = new DefaultInputModule(project.getEffectiveKey());
+    resourceCache.add(project, null).setInputComponent(module);
 
     ArgumentCaptor<org.sonar.api.measures.Measure> argumentCaptor = ArgumentCaptor.forClass(org.sonar.api.measures.Measure.class);
     when(measureCache.put(eq(project), argumentCaptor.capture())).thenReturn(null);
 
     sensorStorage.store(new DefaultMeasure()
-      .onProject()
+      .on(module)
       .forMetric(CoreMetrics.NCLOC)
       .withValue(10));
 
index e4f66be54b02fe29554e53049b6f39a62857805a..a2c7d5f59c05ab0a8e4299ccae1a7767e86dc3c8 100644 (file)
@@ -28,6 +28,11 @@ package org.sonar.api.batch.fs;
  */
 public interface InputComponent {
 
+  /**
+   * Component key shared by all part of SonarQube (batch, server, WS...)
+   */
+  String key();
+
   /**
    * Is the component an {@link InputFile}
    */
index 9a49dd4de66f9ead95dcc8da8024bc664e351205..2a213fc6629f6d2ce05b45574f2721c26ad6b1e0 100644 (file)
@@ -26,8 +26,6 @@ import org.sonar.api.batch.fs.InputComponent;
  */
 public abstract class DefaultInputComponent implements InputComponent {
 
-  public abstract String key();
-
   @Override
   public boolean equals(Object o) {
     if (this == o) {
index 8bec2b65ea4aab3582808a5ef9f7ea5fdd703619..0b506e112b4cd5b024f6fd26610d40dbfb8ddd3c 100644 (file)
@@ -20,6 +20,8 @@
 package org.sonar.api.batch.sensor.internal;
 
 import com.google.common.annotations.Beta;
+import com.google.common.collect.HashBasedTable;
+import com.google.common.collect.Table;
 import java.io.File;
 import java.io.Serializable;
 import java.util.ArrayList;
@@ -30,14 +32,8 @@ import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
 import javax.annotation.CheckForNull;
-import javax.annotation.Nullable;
 import org.sonar.api.batch.AnalysisMode;
-import org.sonar.api.batch.fs.InputDir;
-import org.sonar.api.batch.fs.InputFile;
-import org.sonar.api.batch.fs.InputPath;
 import org.sonar.api.batch.fs.internal.DefaultFileSystem;
-import org.sonar.api.batch.fs.internal.DefaultInputDir;
-import org.sonar.api.batch.fs.internal.DefaultInputFile;
 import org.sonar.api.batch.fs.internal.DefaultTextPointer;
 import org.sonar.api.batch.rule.ActiveRules;
 import org.sonar.api.batch.rule.internal.ActiveRulesBuilder;
@@ -128,24 +124,16 @@ public class SensorContextTester implements SensorContext {
     return new DefaultMeasure<>(sensorStorage);
   }
 
-  public Collection<Measure> measures(@Nullable String componetKey) {
-    if (componetKey == null) {
-      return sensorStorage.projectMeasuresByMetric.values();
-    }
-    Map<String, Measure> measures = sensorStorage.measuresByComponentAndMetric.get(componetKey);
-    return measures != null ? measures.values() : Collections.<Measure>emptyList();
+  public Collection<Measure> measures(String componentKey) {
+    return sensorStorage.measuresByComponentAndMetric.row(componentKey).values();
   }
 
   public <G extends Serializable> Measure<G> measure(String componetKey, Metric<G> metric) {
     return measure(componetKey, metric.key());
   }
 
-  public Measure measure(String componetKey, String metricKey) {
-    if (componetKey == null) {
-      return sensorStorage.projectMeasuresByMetric.get(metricKey);
-    }
-    Map<String, Measure> measures = sensorStorage.measuresByComponentAndMetric.get(componetKey);
-    return measures != null ? measures.get(metricKey) : null;
+  public <G extends Serializable> Measure<G> measure(String componentKey, String metricKey) {
+    return sensorStorage.measuresByComponentAndMetric.row(componentKey).get(metricKey);
   }
 
   @Override
@@ -254,7 +242,7 @@ public class SensorContextTester implements SensorContext {
     public boolean isQuick() {
       return this.isSingle;
     }
-    
+
     public void setSingle(boolean single) {
       this.isSingle = single;
     }
@@ -262,8 +250,7 @@ public class SensorContextTester implements SensorContext {
 
   private static class InMemorySensorStorage implements SensorStorage {
 
-    private Map<String, Measure> projectMeasuresByMetric = new HashMap<>();
-    private Map<String, Map<String, Measure>> measuresByComponentAndMetric = new HashMap<>();
+    private Table<String, String, Measure> measuresByComponentAndMetric = HashBasedTable.create();
 
     private Collection<Issue> allIssues = new ArrayList<>();
 
@@ -274,15 +261,7 @@ public class SensorContextTester implements SensorContext {
 
     @Override
     public void store(Measure measure) {
-      String key = getKey(measure.inputFile());
-      if (key == null) {
-        projectMeasuresByMetric.put(measure.metric().key(), measure);
-      } else {
-        if (!measuresByComponentAndMetric.containsKey(key)) {
-          measuresByComponentAndMetric.put(key, new HashMap<String, Measure>());
-        }
-        measuresByComponentAndMetric.get(key).put(measure.metric().key(), measure);
-      }
+      measuresByComponentAndMetric.row(measure.inputComponent().key()).put(measure.metric().key(), measure);
     }
 
     @Override
@@ -297,32 +276,18 @@ public class SensorContextTester implements SensorContext {
 
     @Override
     public void store(DefaultHighlighting highlighting) {
-      highlightingByComponent.put(getKey(highlighting.inputFile()), highlighting);
+      highlightingByComponent.put(highlighting.inputFile().key(), highlighting);
     }
 
     @Override
     public void store(DefaultCoverage defaultCoverage) {
-      String key = getKey(defaultCoverage.inputFile());
+      String key = defaultCoverage.inputFile().key();
       if (!coverageByComponent.containsKey(key)) {
         coverageByComponent.put(key, new EnumMap<CoverageType, DefaultCoverage>(CoverageType.class));
       }
       coverageByComponent.get(key).put(defaultCoverage.type(), defaultCoverage);
     }
 
-    @CheckForNull
-    private static String getKey(@Nullable InputPath inputPath) {
-      if (inputPath == null) {
-        return null;
-      }
-      if (inputPath instanceof InputFile) {
-        return ((DefaultInputFile) inputPath).key();
-      }
-      if (inputPath instanceof InputDir) {
-        return ((DefaultInputDir) inputPath).key();
-      }
-      throw new IllegalStateException("Unknow component " + inputPath);
-    }
-
   }
 
 }
index 87b6ff67d448798dab466a2a606e176adb19dc2e..df800a0bba242af2a91399c795472b3896070f14 100644 (file)
@@ -41,7 +41,7 @@ public class DefaultIssueLocation implements NewIssueLocation, IssueLocation {
   }
 
   @Override
-  public NewIssueLocation at(TextRange location) {
+  public DefaultIssueLocation at(TextRange location) {
     Preconditions.checkState(this.component != null, "at() should be called after on()");
     Preconditions.checkState(this.component.isFile(), "at() should be called only for an InputFile.");
     DefaultInputFile file = (DefaultInputFile) this.component;
@@ -51,7 +51,7 @@ public class DefaultIssueLocation implements NewIssueLocation, IssueLocation {
   }
 
   @Override
-  public NewIssueLocation message(String message) {
+  public DefaultIssueLocation message(String message) {
     Preconditions.checkNotNull(message, "Message can't be null");
     Preconditions.checkArgument(message.length() <= MESSAGE_MAX_SIZE,
       "Message of an issue can't be greater than " + MESSAGE_MAX_SIZE + ": [" + message + "] size is " + message.length());
index 4f82f8587b74bf57f73759ed9dc47f02aabb1a1b..469d073e1d95a708fd1a9c7a85e5876538a991a9 100644 (file)
 package org.sonar.api.batch.sensor.measure;
 
 import com.google.common.annotations.Beta;
-import org.sonar.api.batch.fs.InputFile;
-import org.sonar.api.batch.measure.Metric;
-
-import javax.annotation.CheckForNull;
-
 import java.io.Serializable;
+import org.sonar.api.batch.fs.InputComponent;
+import org.sonar.api.batch.measure.Metric;
 
 /**
  * Measure on File, Directory or Project.
@@ -36,11 +33,9 @@ import java.io.Serializable;
 public interface Measure<G extends Serializable> {
 
   /**
-   * The file the measure belong to.
-   * @return null if measure is on project
+   * The {@link InputComponent} this measure belongs to.
    */
-  @CheckForNull
-  InputFile inputFile();
+  InputComponent inputComponent();
 
   /**
    * The metric this measure belong to.
index 412e4df92036514152cd09a11b70db86bac3a2c6..82f190ccd6ce5a53fd993b5f2c6aa5cd833394d1 100644 (file)
 package org.sonar.api.batch.sensor.measure;
 
 import com.google.common.annotations.Beta;
-import org.sonar.api.batch.fs.InputFile;
-import org.sonar.api.batch.measure.Metric;
-
 import java.io.Serializable;
+import org.sonar.api.batch.fs.InputComponent;
+import org.sonar.api.batch.measure.Metric;
 
 /**
  * Builder to create new Measure.
  * Should not be implemented by client.
- * @since 5.1
+ * @since 5.2
  */
 @Beta
 public interface NewMeasure<G extends Serializable> {
 
   /**
-   * The file the measure belongs to.
-   */
-  NewMeasure<G> onFile(InputFile file);
-
-  /**
-   * Tell that the measure is global to the project.
+   * The {@link InputComponent} the measure belongs to. Mandatory.
    */
-  NewMeasure<G> onProject();
+  NewMeasure<G> on(InputComponent component);
 
   /**
    * Set the metric this measure belong to.
index f6cccb2f2e72b3a7e0310c749ad4e947aaaf3fb7..d80e2042afc70ae8257ad4bd973fadf0f9594e2e 100644 (file)
  */
 package org.sonar.api.batch.sensor.measure.internal;
 
-import org.sonar.api.batch.sensor.internal.SensorStorage;
-
 import com.google.common.base.Preconditions;
+import java.io.Serializable;
+import javax.annotation.Nullable;
 import org.apache.commons.lang.builder.EqualsBuilder;
 import org.apache.commons.lang.builder.HashCodeBuilder;
-import org.sonar.api.batch.fs.InputFile;
+import org.sonar.api.batch.fs.InputComponent;
 import org.sonar.api.batch.measure.Metric;
 import org.sonar.api.batch.sensor.internal.DefaultStorable;
+import org.sonar.api.batch.sensor.internal.SensorStorage;
 import org.sonar.api.batch.sensor.measure.Measure;
 import org.sonar.api.batch.sensor.measure.NewMeasure;
 
-import javax.annotation.CheckForNull;
-import javax.annotation.Nullable;
-
-import java.io.Serializable;
-
 public class DefaultMeasure<G extends Serializable> extends DefaultStorable implements Measure<G>, NewMeasure<G> {
 
-  private boolean onProject = false;
-  private InputFile file;
+  private InputComponent component;
   private Metric<G> metric;
   private G value;
   private boolean fromCore = false;
@@ -52,19 +47,10 @@ public class DefaultMeasure<G extends Serializable> extends DefaultStorable impl
   }
 
   @Override
-  public DefaultMeasure<G> onFile(InputFile inputFile) {
-    Preconditions.checkState(!this.onProject, "onProject already called");
-    Preconditions.checkState(this.file == null, "onFile already called");
-    Preconditions.checkNotNull(inputFile, "InputFile should be non null");
-    this.file = inputFile;
-    return this;
-  }
-
-  @Override
-  public DefaultMeasure<G> onProject() {
-    Preconditions.checkState(!this.onProject, "onProject already called");
-    Preconditions.checkState(this.file == null, "onFile already called");
-    this.onProject = true;
+  public DefaultMeasure<G> on(InputComponent component) {
+    Preconditions.checkArgument(component != null, "Component can't be null");
+    Preconditions.checkState(this.component == null, "on() already called");
+    this.component = component;
     return this;
   }
 
@@ -113,9 +99,8 @@ public class DefaultMeasure<G extends Serializable> extends DefaultStorable impl
   }
 
   @Override
-  @CheckForNull
-  public InputFile inputFile() {
-    return file;
+  public InputComponent inputComponent() {
+    return component;
   }
 
   @Override
@@ -138,7 +123,7 @@ public class DefaultMeasure<G extends Serializable> extends DefaultStorable impl
     }
     DefaultMeasure<?> rhs = (DefaultMeasure<?>) obj;
     return new EqualsBuilder()
-      .append(file, rhs.file)
+      .append(component, rhs.component)
       .append(metric, rhs.metric)
       .append(value, rhs.value)
       .isEquals();
@@ -146,11 +131,7 @@ public class DefaultMeasure<G extends Serializable> extends DefaultStorable impl
 
   @Override
   public int hashCode() {
-    return new HashCodeBuilder(27, 45).
-      append(file).
-      append(metric).
-      append(value).
-      toHashCode();
+    return new HashCodeBuilder(27, 45).append(component).append(metric).append(value).toHashCode();
   }
 
 }
index 7c15bd2c3f96b26967867781eaa120bd3d684a4e..35ad51f3c4017c5ce0b417998de259afb6ee0876 100644 (file)
@@ -27,6 +27,7 @@ import org.junit.Test;
 import org.junit.rules.TemporaryFolder;
 import org.sonar.api.batch.fs.internal.DefaultFileSystem;
 import org.sonar.api.batch.fs.internal.DefaultInputFile;
+import org.sonar.api.batch.fs.internal.DefaultInputModule;
 import org.sonar.api.batch.fs.internal.FileMetadata;
 import org.sonar.api.batch.rule.ActiveRules;
 import org.sonar.api.batch.rule.internal.ActiveRulesBuilder;
@@ -105,14 +106,14 @@ public class SensorContextTesterTest {
     assertThat(tester.measures("foo:src/Foo.java")).isEmpty();
     assertThat(tester.measure("foo:src/Foo.java", "ncloc")).isNull();
     tester.<Integer>newMeasure()
-      .onFile(new DefaultInputFile("foo", "src/Foo.java"))
+      .on(new DefaultInputFile("foo", "src/Foo.java"))
       .forMetric(CoreMetrics.NCLOC)
       .withValue(2)
       .save();
     assertThat(tester.measures("foo:src/Foo.java")).hasSize(1);
     assertThat(tester.measure("foo:src/Foo.java", "ncloc")).isNotNull();
     tester.<Integer>newMeasure()
-      .onFile(new DefaultInputFile("foo", "src/Foo.java"))
+      .on(new DefaultInputFile("foo", "src/Foo.java"))
       .forMetric(CoreMetrics.LINES)
       .withValue(4)
       .save();
@@ -120,12 +121,12 @@ public class SensorContextTesterTest {
     assertThat(tester.measure("foo:src/Foo.java", "ncloc")).isNotNull();
     assertThat(tester.measure("foo:src/Foo.java", "lines")).isNotNull();
     tester.<Integer>newMeasure()
-      .onProject()
+      .on(new DefaultInputModule("foo"))
       .forMetric(CoreMetrics.DIRECTORIES)
       .withValue(4)
       .save();
-    assertThat(tester.measures(null)).hasSize(1);
-    assertThat(tester.measure(null, "directories")).isNotNull();
+    assertThat(tester.measures("foo")).hasSize(1);
+    assertThat(tester.measure("foo", "directories")).isNotNull();
   }
 
   @Test
index 6dae7fc2dbf36ce039439f97cb10ebaef56d9d40..ba7af3f67c3f2c9dff8ea07a9eb05aed8b40bb28 100644 (file)
  */
 package org.sonar.api.batch.sensor.measure.internal;
 
-import org.sonar.api.batch.sensor.internal.SensorStorage;
-
 import org.junit.Rule;
 import org.junit.Test;
 import org.junit.rules.ExpectedException;
 import org.sonar.api.batch.fs.internal.DefaultInputFile;
+import org.sonar.api.batch.fs.internal.DefaultInputModule;
+import org.sonar.api.batch.sensor.internal.SensorStorage;
 import org.sonar.api.measures.CoreMetrics;
+
 import static org.assertj.core.api.Assertions.assertThat;
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.verify;
@@ -40,10 +41,10 @@ public class DefaultMeasureTest {
     SensorStorage storage = mock(SensorStorage.class);
     DefaultMeasure<Integer> newMeasure = new DefaultMeasure<Integer>(storage)
       .forMetric(CoreMetrics.LINES)
-      .onFile(new DefaultInputFile("foo", "src/Foo.php"))
+      .on(new DefaultInputFile("foo", "src/Foo.php"))
       .withValue(3);
 
-    assertThat(newMeasure.inputFile()).isEqualTo(new DefaultInputFile("foo", "src/Foo.php"));
+    assertThat(newMeasure.inputComponent()).isEqualTo(new DefaultInputFile("foo", "src/Foo.php"));
     assertThat(newMeasure.metric()).isEqualTo(CoreMetrics.LINES);
     assertThat(newMeasure.value()).isEqualTo(3);
 
@@ -55,12 +56,13 @@ public class DefaultMeasureTest {
   @Test
   public void build_project_measure() {
     SensorStorage storage = mock(SensorStorage.class);
+    DefaultInputModule module = new DefaultInputModule("foo");
     DefaultMeasure<Integer> newMeasure = new DefaultMeasure<Integer>(storage)
       .forMetric(CoreMetrics.LINES)
-      .onProject()
+      .on(module)
       .withValue(3);
 
-    assertThat(newMeasure.inputFile()).isNull();
+    assertThat(newMeasure.inputComponent()).isEqualTo(new DefaultInputModule("foo"));
     assertThat(newMeasure.metric()).isEqualTo(CoreMetrics.LINES);
     assertThat(newMeasure.value()).isEqualTo(3);
 
@@ -70,12 +72,12 @@ public class DefaultMeasureTest {
   }
 
   @Test
-  public void not_allowed_to_call_onFile_and_onProject() {
+  public void not_allowed_to_call_on_twice() {
     thrown.expect(IllegalStateException.class);
-    thrown.expectMessage("onProject already called");
+    thrown.expectMessage("on() already called");
     new DefaultMeasure<Integer>()
-      .onProject()
-      .onFile(new DefaultInputFile("foo", "src/Foo.php"))
+      .on(new DefaultInputModule("foo"))
+      .on(new DefaultInputFile("foo", "src/Foo.php"))
       .withValue(3)
       .save();
   }