]> source.dussan.org Git - sonarqube.git/commitdiff
SONAR-5389 Improve analyzer API
authorJulien HENRY <julien.henry@sonarsource.com>
Wed, 18 Jun 2014 15:28:54 +0000 (17:28 +0200)
committerJulien HENRY <julien.henry@sonarsource.com>
Wed, 18 Jun 2014 15:29:46 +0000 (17:29 +0200)
12 files changed:
sonar-batch/src/main/java/org/sonar/batch/scan/AnalyzerContextAdaptor.java
sonar-batch/src/main/java/org/sonar/batch/scan2/AnalyzerMeasureCache.java
sonar-batch/src/main/java/org/sonar/batch/scan2/DefaultAnalyzerContext.java
sonar-plugin-api/src/main/java/org/sonar/api/batch/analyzer/AnalyzerContext.java
sonar-plugin-api/src/main/java/org/sonar/api/batch/analyzer/AnalyzerDescriptor.java
sonar-plugin-api/src/main/java/org/sonar/api/batch/analyzer/issue/AnalyzerIssue.java
sonar-plugin-api/src/main/java/org/sonar/api/batch/analyzer/issue/AnalyzerIssueBuilder.java [new file with mode: 0644]
sonar-plugin-api/src/main/java/org/sonar/api/batch/analyzer/issue/internal/DefaultAnalyzerIssue.java [new file with mode: 0644]
sonar-plugin-api/src/main/java/org/sonar/api/batch/analyzer/issue/internal/DefaultAnalyzerIssueBuilder.java [new file with mode: 0644]
sonar-plugin-api/src/main/java/org/sonar/api/batch/analyzer/measure/AnalyzerMeasure.java
sonar-plugin-api/src/main/java/org/sonar/api/batch/analyzer/measure/internal/DefaultAnalyzerMeasure.java
sonar-plugin-api/src/main/java/org/sonar/api/batch/analyzer/measure/internal/DefaultAnalyzerMeasureBuilder.java

index 97bf89d1aa99859336324e70b644fb02772cbfdc..c83c090f2529321db88ddff643187037f07df32c 100644 (file)
@@ -22,12 +22,17 @@ package org.sonar.batch.scan;
 import org.sonar.api.batch.SensorContext;
 import org.sonar.api.batch.analyzer.AnalyzerContext;
 import org.sonar.api.batch.analyzer.issue.AnalyzerIssue;
+import org.sonar.api.batch.analyzer.issue.AnalyzerIssueBuilder;
+import org.sonar.api.batch.analyzer.issue.internal.DefaultAnalyzerIssueBuilder;
 import org.sonar.api.batch.analyzer.measure.AnalyzerMeasure;
 import org.sonar.api.batch.analyzer.measure.AnalyzerMeasureBuilder;
 import org.sonar.api.batch.analyzer.measure.internal.DefaultAnalyzerMeasureBuilder;
+import org.sonar.api.batch.fs.FileSystem;
 import org.sonar.api.batch.fs.InputFile;
 import org.sonar.api.batch.measures.Metric;
+import org.sonar.api.batch.rule.ActiveRules;
 import org.sonar.api.component.ResourcePerspectives;
+import org.sonar.api.config.Settings;
 import org.sonar.api.issue.Issuable;
 import org.sonar.api.measures.Measure;
 import org.sonar.api.measures.MetricFinder;
@@ -37,20 +42,45 @@ import org.sonar.api.resources.Resource;
 import org.sonar.api.rule.RuleKey;
 
 import java.io.Serializable;
-import java.util.Collection;
 
+/**
+ * Implements {@link AnalyzerContext} but forward everything to {@link SensorContext} for backward compatibility.
+ *
+ */
 public class AnalyzerContextAdaptor implements AnalyzerContext {
 
   private SensorContext sensorContext;
   private MetricFinder metricFinder;
   private Project project;
   private ResourcePerspectives perspectives;
+  private Settings settings;
+  private FileSystem fs;
+  private ActiveRules activeRules;
 
-  public AnalyzerContextAdaptor(SensorContext sensorContext, MetricFinder metricFinder, Project project, ResourcePerspectives perspectives) {
+  public AnalyzerContextAdaptor(SensorContext sensorContext, MetricFinder metricFinder, Project project, ResourcePerspectives perspectives,
+    Settings settings, FileSystem fs, ActiveRules activeRules) {
     this.sensorContext = sensorContext;
     this.metricFinder = metricFinder;
     this.project = project;
     this.perspectives = perspectives;
+    this.settings = settings;
+    this.fs = fs;
+    this.activeRules = activeRules;
+  }
+
+  @Override
+  public Settings settings() {
+    return settings;
+  }
+
+  @Override
+  public FileSystem fileSystem() {
+    return fs;
+  }
+
+  @Override
+  public ActiveRules activeRules() {
+    return activeRules;
   }
 
   @Override
@@ -107,7 +137,7 @@ public class AnalyzerContextAdaptor implements AnalyzerContext {
 
   @Override
   public void addMeasure(AnalyzerMeasure<?> measure) {
-    org.sonar.api.measures.Metric<?> m = metricFinder.findByKey(measure.metricKey());
+    org.sonar.api.measures.Metric<?> m = metricFinder.findByKey(measure.metric().key());
 
     Measure measureToSave = new Measure(m);
     switch (m.getType()) {
@@ -149,6 +179,11 @@ public class AnalyzerContextAdaptor implements AnalyzerContext {
     }
   }
 
+  @Override
+  public AnalyzerIssueBuilder issueBuilder() {
+    return new DefaultAnalyzerIssueBuilder();
+  }
+
   @Override
   public void addIssue(AnalyzerIssue issue) {
     Resource r;
@@ -166,11 +201,4 @@ public class AnalyzerContextAdaptor implements AnalyzerContext {
       .build());
   }
 
-  @Override
-  public void addIssues(Collection<AnalyzerIssue> issues) {
-    for (AnalyzerIssue analyzerIssue : issues) {
-      addIssue(analyzerIssue);
-    }
-  }
-
 }
index 593324a1c73a99318f734feda8326195ad31eafc..07d313f224905801ce753428c485422fa5786469 100644 (file)
@@ -47,15 +47,15 @@ public class AnalyzerMeasureCache implements BatchComponent {
 
   public AnalyzerMeasureCache put(String resourceKey, DefaultAnalyzerMeasure<?> measure) {
     Preconditions.checkNotNull(resourceKey);
-    Preconditions.checkNotNull(measure.metricKey());
-    cache.put(resourceKey, measure.metricKey(), measure);
+    Preconditions.checkNotNull(measure);
+    cache.put(resourceKey, measure.metric().key(), measure);
     return this;
   }
 
   public boolean contains(String resourceKey, DefaultAnalyzerMeasure<?> measure) {
     Preconditions.checkNotNull(resourceKey);
     Preconditions.checkNotNull(measure);
-    return cache.containsKey(resourceKey, measure.metricKey());
+    return cache.containsKey(resourceKey, measure.metric().key());
   }
 
   public Iterable<DefaultAnalyzerMeasure> all() {
index 5fc2961ef843cf4988ec1fd603674b6f313217f9..e411fbbfe742e96284bdddc41296cbd7146fd03a 100644 (file)
@@ -21,13 +21,18 @@ package org.sonar.batch.scan2;
 
 import org.sonar.api.batch.analyzer.AnalyzerContext;
 import org.sonar.api.batch.analyzer.issue.AnalyzerIssue;
+import org.sonar.api.batch.analyzer.issue.AnalyzerIssueBuilder;
+import org.sonar.api.batch.analyzer.issue.internal.DefaultAnalyzerIssueBuilder;
 import org.sonar.api.batch.analyzer.measure.AnalyzerMeasure;
 import org.sonar.api.batch.analyzer.measure.AnalyzerMeasureBuilder;
 import org.sonar.api.batch.analyzer.measure.internal.DefaultAnalyzerMeasure;
 import org.sonar.api.batch.analyzer.measure.internal.DefaultAnalyzerMeasureBuilder;
 import org.sonar.api.batch.bootstrap.ProjectDefinition;
+import org.sonar.api.batch.fs.FileSystem;
 import org.sonar.api.batch.fs.InputFile;
 import org.sonar.api.batch.measures.Metric;
+import org.sonar.api.batch.rule.ActiveRules;
+import org.sonar.api.config.Settings;
 import org.sonar.api.issue.internal.DefaultIssue;
 import org.sonar.api.rule.RuleKey;
 import org.sonar.batch.issue.ModuleIssues;
@@ -35,18 +40,39 @@ import org.sonar.core.component.ComponentKeys;
 import org.sonar.core.issue.DefaultIssueBuilder;
 
 import java.io.Serializable;
-import java.util.Collection;
 
 public class DefaultAnalyzerContext implements AnalyzerContext {
 
   private final AnalyzerMeasureCache measureCache;
   private ProjectDefinition def;
   private ModuleIssues moduleIssues;
+  private Settings settings;
+  private FileSystem fs;
+  private ActiveRules activeRules;
 
-  public DefaultAnalyzerContext(ProjectDefinition def, AnalyzerMeasureCache measureCache, ModuleIssues moduleIssues) {
+  public DefaultAnalyzerContext(ProjectDefinition def, AnalyzerMeasureCache measureCache,
+    ModuleIssues moduleIssues, Settings settings, FileSystem fs, ActiveRules activeRules) {
     this.def = def;
     this.measureCache = measureCache;
     this.moduleIssues = moduleIssues;
+    this.settings = settings;
+    this.fs = fs;
+    this.activeRules = activeRules;
+  }
+
+  @Override
+  public Settings settings() {
+    return settings;
+  }
+
+  @Override
+  public FileSystem fileSystem() {
+    return fs;
+  }
+
+  @Override
+  public ActiveRules activeRules() {
+    return activeRules;
   }
 
   @Override
@@ -83,6 +109,11 @@ public class DefaultAnalyzerContext implements AnalyzerContext {
     }
   }
 
+  @Override
+  public AnalyzerIssueBuilder issueBuilder() {
+    return new DefaultAnalyzerIssueBuilder();
+  }
+
   @Override
   public void addIssue(AnalyzerIssue issue) {
     DefaultIssueBuilder builder = new DefaultIssueBuilder()
@@ -101,12 +132,4 @@ public class DefaultAnalyzerContext implements AnalyzerContext {
       .build());
   }
 
-  @Override
-  public void addIssues(Collection<AnalyzerIssue> issues) {
-    for (AnalyzerIssue analyzerIssue : issues) {
-      addIssue(analyzerIssue);
-    }
-
-  }
-
 }
index 68e9a04aa04883d344d5a39db68f22e0d8973fcb..b28ab8af61bea25f6098e7b04933f382b2c89867 100644 (file)
 package org.sonar.api.batch.analyzer;
 
 import org.sonar.api.batch.analyzer.issue.AnalyzerIssue;
+import org.sonar.api.batch.analyzer.issue.AnalyzerIssueBuilder;
 import org.sonar.api.batch.analyzer.measure.AnalyzerMeasure;
 import org.sonar.api.batch.analyzer.measure.AnalyzerMeasureBuilder;
+import org.sonar.api.batch.fs.FileSystem;
 import org.sonar.api.batch.fs.InputFile;
 import org.sonar.api.batch.measures.Metric;
+import org.sonar.api.batch.rule.ActiveRules;
+import org.sonar.api.config.Settings;
 
 import javax.annotation.CheckForNull;
 
 import java.io.Serializable;
-import java.util.Collection;
 
 /**
  * @since 4.4
  */
 public interface AnalyzerContext {
 
+  /**
+   * Get settings of the current project.
+   */
+  Settings settings();
+
+  /**
+   * Get filesystem of the current project.
+   */
+  FileSystem fileSystem();
+
+  /**
+   * Get list of active rules.
+   */
+  ActiveRules activeRules();
+
   // ----------- MEASURES --------------
 
   /**
@@ -74,13 +92,13 @@ public interface AnalyzerContext {
   // ----------- ISSUES --------------
 
   /**
-   * Add an issue.
+   * Builder to create a new {@link AnalyzerIssue}.
    */
-  void addIssue(AnalyzerIssue issue);
+  AnalyzerIssueBuilder issueBuilder();
 
   /**
-   * Add a list of issues.
+   * Add an issue. Use {@link #issueBuilder()} to create the new issue.
    */
-  void addIssues(Collection<AnalyzerIssue> issues);
+  void addIssue(AnalyzerIssue issue);
 
 }
index f03c98392ecabba0a9b63b24a2e55d7569aec96a..ab52f9a8b8077d30671acf9e06b28e36b16f128f 100644 (file)
 package org.sonar.api.batch.analyzer;
 
 import org.sonar.api.batch.fs.InputFile;
+import org.sonar.api.batch.languages.Language;
 import org.sonar.api.batch.measures.Metric;
 
 /**
+ * Describe what an {@link Analyzer} is doing. Information may be used by the platform
+ * to log interesting information or perform some optimization.
  * @since 4.4
  */
 public interface AnalyzerDescriptor {
 
+  /**
+   * Name of the {@link Analyzer}. Will be displayed in logs.
+   */
   AnalyzerDescriptor name(String name);
 
+  /**
+   * List {@link Metric} this {@link Analyzer} depends on. Will be used to execute Analyzers in correct order.
+   */
   AnalyzerDescriptor dependsOn(Metric<?>... metrics);
 
+  /**
+   * List {@link Metric} this {@link Analyzer} provides. Will be used to execute Analyzers in correct order.
+   */
   AnalyzerDescriptor provides(Metric<?>... metrics);
 
+  /**
+   * List {@link Language} this {@link Analyzer} work on. May be used by the platform to skip execution of the {@link Analyzer} when
+   * no file for given languages are present in the project.
+   * If no language is provided then it will be executed for all languages.
+   */
   AnalyzerDescriptor runOnLanguages(String... languageKeys);
 
+  /**
+   * List {@link InputFile.Type} this {@link Analyzer} work on. May be used by the platform to skip execution of the {@link Analyzer} when
+   * no file for given type are present in the project.
+   * If not type is provided then t will be executed for all types.
+   */
   AnalyzerDescriptor runOnTypes(InputFile.Type... types);
 
 }
index 7aa2b2e163f1400b3ff15f622eaa90f187a0bf3e..ed1de433607688371abf2b440830f47f513a6410 100644 (file)
@@ -19,7 +19,6 @@
  */
 package org.sonar.api.batch.analyzer.issue;
 
-import com.google.common.base.Preconditions;
 import org.sonar.api.batch.analyzer.Analyzer;
 import org.sonar.api.batch.fs.InputFile;
 import org.sonar.api.rule.RuleKey;
@@ -31,96 +30,33 @@ import javax.annotation.Nullable;
  *
  * @since 4.4
  */
-public class AnalyzerIssue {
-
-  private final InputFile inputFile;
-  private final RuleKey ruleKey;
-  private final String message;
-  private final Integer line;
-  private final Double effortToFix;
-
-  private AnalyzerIssue(Builder builder) {
-    this.inputFile = builder.file;
-    this.ruleKey = builder.ruleKey;
-    this.message = builder.message;
-    this.line = builder.line;
-    this.effortToFix = builder.effortToFix;
-  }
-
-  public static Builder builder() {
-    return new Builder();
-  }
+public interface AnalyzerIssue {
 
+  /**
+   * The {@link InputFile} this issue belongs to. Returns null if issue is global to the project.
+   */
   @Nullable
-  public InputFile inputFile() {
-    return inputFile;
-  }
-
-  public RuleKey ruleKey() {
-    return ruleKey;
-  }
-
-  public String message() {
-    return message;
-  }
-
-  public Integer line() {
-    return line;
-  }
-
+  InputFile inputFile();
+
+  /**
+   * The {@link RuleKey} of this issue.
+   */
+  RuleKey ruleKey();
+
+  /**
+   * Message of the issue.
+   */
+  String message();
+
+  /**
+   * Line of the issue.
+   */
+  Integer line();
+
+  /**
+   * Effort to fix the issue. Used by technical debt model.
+   */
   @Nullable
-  public Double effortToFix() {
-    return effortToFix;
-  }
-
-  public static class Builder {
-
-    private Boolean onProject = null;
-    private InputFile file;
-    private RuleKey ruleKey;
-    private String message;
-    private Integer line;
-    private Double effortToFix;
-
-    public AnalyzerIssue build() {
-      return new AnalyzerIssue(this);
-    }
-
-    public Builder ruleKey(RuleKey ruleKey) {
-      this.ruleKey = ruleKey;
-      return this;
-    }
-
-    public Builder onFile(InputFile file) {
-      Preconditions.checkState(onProject == null, "onFile or onProject can be called only once");
-      Preconditions.checkNotNull(file, "InputFile should be non null");
-      this.file = file;
-      this.onProject = false;
-      return this;
-    }
-
-    public Builder onProject() {
-      Preconditions.checkState(onProject == null, "onFile or onProject can be called only once");
-      this.file = null;
-      this.onProject = true;
-      return this;
-    }
-
-    public Builder atLine(int line) {
-      this.line = line;
-      return this;
-    }
-
-    public Builder effortToFix(@Nullable Double effortToFix) {
-      this.effortToFix = effortToFix;
-      return this;
-    }
-
-    public Builder message(String message) {
-      this.message = message;
-      return this;
-    }
-
-  }
+  Double effortToFix();
 
 }
diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/batch/analyzer/issue/AnalyzerIssueBuilder.java b/sonar-plugin-api/src/main/java/org/sonar/api/batch/analyzer/issue/AnalyzerIssueBuilder.java
new file mode 100644 (file)
index 0000000..5c27263
--- /dev/null
@@ -0,0 +1,69 @@
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2014 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube 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.
+ *
+ * SonarQube 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 this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ */
+package org.sonar.api.batch.analyzer.issue;
+
+import org.sonar.api.batch.fs.InputFile;
+import org.sonar.api.rule.RuleKey;
+
+import javax.annotation.Nullable;
+
+/**
+ * Builder for {@link AnalyzerIssue}.
+ *
+ * @since 4.4
+ */
+public interface AnalyzerIssueBuilder {
+
+  /**
+   * The {@link RuleKey} of the issue.
+   */
+  AnalyzerIssueBuilder ruleKey(RuleKey ruleKey);
+
+  /**
+   * The {@link InputFile} the issue belongs to. For global issues call {@link #onProject()}.
+   */
+  AnalyzerIssueBuilder onFile(InputFile file);
+
+  /**
+   * Tell that the issue is global to the project.
+   */
+  AnalyzerIssueBuilder onProject();
+
+  /**
+   * Line of the issue.
+   */
+  AnalyzerIssueBuilder atLine(int line);
+
+  /**
+   * Effort to fix for the issue.
+   */
+  AnalyzerIssueBuilder effortToFix(@Nullable Double effortToFix);
+
+  /**
+   * Message of the issue.
+   */
+  AnalyzerIssueBuilder message(String message);
+
+  /**
+   * Build the issue.
+   */
+  AnalyzerIssue build();
+
+}
diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/batch/analyzer/issue/internal/DefaultAnalyzerIssue.java b/sonar-plugin-api/src/main/java/org/sonar/api/batch/analyzer/issue/internal/DefaultAnalyzerIssue.java
new file mode 100644 (file)
index 0000000..7b10db7
--- /dev/null
@@ -0,0 +1,73 @@
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2014 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube 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.
+ *
+ * SonarQube 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 this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ */
+package org.sonar.api.batch.analyzer.issue.internal;
+
+import org.sonar.api.batch.analyzer.issue.AnalyzerIssue;
+import org.sonar.api.batch.fs.InputFile;
+import org.sonar.api.rule.RuleKey;
+
+import javax.annotation.Nullable;
+
+import java.io.Serializable;
+
+public class DefaultAnalyzerIssue implements AnalyzerIssue, Serializable {
+
+  private final InputFile inputFile;
+  private final RuleKey ruleKey;
+  private final String message;
+  private final Integer line;
+  private final Double effortToFix;
+
+  DefaultAnalyzerIssue(DefaultAnalyzerIssueBuilder builder) {
+    this.inputFile = builder.file;
+    this.ruleKey = builder.ruleKey;
+    this.message = builder.message;
+    this.line = builder.line;
+    this.effortToFix = builder.effortToFix;
+  }
+
+  @Override
+  @Nullable
+  public InputFile inputFile() {
+    return inputFile;
+  }
+
+  @Override
+  public RuleKey ruleKey() {
+    return ruleKey;
+  }
+
+  @Override
+  public String message() {
+    return message;
+  }
+
+  @Override
+  public Integer line() {
+    return line;
+  }
+
+  @Override
+  @Nullable
+  public Double effortToFix() {
+    return effortToFix;
+  }
+
+}
diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/batch/analyzer/issue/internal/DefaultAnalyzerIssueBuilder.java b/sonar-plugin-api/src/main/java/org/sonar/api/batch/analyzer/issue/internal/DefaultAnalyzerIssueBuilder.java
new file mode 100644 (file)
index 0000000..7092caa
--- /dev/null
@@ -0,0 +1,85 @@
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2014 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube 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.
+ *
+ * SonarQube 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 this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ */
+package org.sonar.api.batch.analyzer.issue.internal;
+
+import com.google.common.base.Preconditions;
+import org.sonar.api.batch.analyzer.issue.AnalyzerIssue;
+import org.sonar.api.batch.analyzer.issue.AnalyzerIssueBuilder;
+import org.sonar.api.batch.fs.InputFile;
+import org.sonar.api.rule.RuleKey;
+
+import javax.annotation.Nullable;
+
+public class DefaultAnalyzerIssueBuilder implements AnalyzerIssueBuilder {
+
+  Boolean onProject = null;
+  InputFile file;
+  RuleKey ruleKey;
+  String message;
+  Integer line;
+  Double effortToFix;
+
+  @Override
+  public DefaultAnalyzerIssueBuilder ruleKey(RuleKey ruleKey) {
+    this.ruleKey = ruleKey;
+    return this;
+  }
+
+  @Override
+  public DefaultAnalyzerIssueBuilder onFile(InputFile file) {
+    Preconditions.checkState(onProject == null, "onFile or onProject can be called only once");
+    Preconditions.checkNotNull(file, "InputFile should be non null");
+    this.file = file;
+    this.onProject = false;
+    return this;
+  }
+
+  @Override
+  public DefaultAnalyzerIssueBuilder onProject() {
+    Preconditions.checkState(onProject == null, "onFile or onProject can be called only once");
+    this.file = null;
+    this.onProject = true;
+    return this;
+  }
+
+  @Override
+  public DefaultAnalyzerIssueBuilder atLine(int line) {
+    this.line = line;
+    return this;
+  }
+
+  @Override
+  public DefaultAnalyzerIssueBuilder effortToFix(@Nullable Double effortToFix) {
+    this.effortToFix = effortToFix;
+    return this;
+  }
+
+  @Override
+  public DefaultAnalyzerIssueBuilder message(String message) {
+    this.message = message;
+    return this;
+  }
+
+  @Override
+  public AnalyzerIssue build() {
+    return new DefaultAnalyzerIssue(this);
+  }
+
+}
index e0b89e108123155b79cebaf5f9c31b749aef2fa5..554efed34de4ba427242f9147139c4121ba80f02 100644 (file)
@@ -21,13 +21,14 @@ package org.sonar.api.batch.analyzer.measure;
 
 import org.sonar.api.batch.analyzer.Analyzer;
 import org.sonar.api.batch.fs.InputFile;
+import org.sonar.api.batch.measures.Metric;
 
 import javax.annotation.Nullable;
 
 import java.io.Serializable;
 
 /**
- * A measure produced by {@link Analyzer}.
+ * A measure computed by an {@link Analyzer}.
  * @since 4.4
  */
 public interface AnalyzerMeasure<G extends Serializable> {
@@ -38,7 +39,7 @@ public interface AnalyzerMeasure<G extends Serializable> {
   @Nullable
   InputFile inputFile();
 
-  String metricKey();
+  Metric<G> metric();
 
   G value();
 
index 63d9736e07d13b4aa020edf2f1202cb6fa98c729..fa87d0953c9ae5ee6eae69df5dcedbfbd1429a60 100644 (file)
@@ -22,6 +22,7 @@ package org.sonar.api.batch.analyzer.measure.internal;
 import com.google.common.base.Preconditions;
 import org.sonar.api.batch.analyzer.measure.AnalyzerMeasure;
 import org.sonar.api.batch.fs.InputFile;
+import org.sonar.api.batch.measures.Metric;
 
 import javax.annotation.Nullable;
 
@@ -30,14 +31,14 @@ import java.io.Serializable;
 public class DefaultAnalyzerMeasure<G extends Serializable> implements AnalyzerMeasure<G>, Serializable {
 
   private final InputFile inputFile;
-  private final String metricKey;
+  private final Metric<G> metric;
   private final G value;
 
   DefaultAnalyzerMeasure(DefaultAnalyzerMeasureBuilder<G> builder) {
     Preconditions.checkNotNull(builder.value, "Measure value can't be null");
-    Preconditions.checkNotNull(builder.metricKey, "Measure metricKey can't be null");
+    Preconditions.checkNotNull(builder.metric, "Measure metricKey can't be null");
     this.inputFile = builder.file;
-    this.metricKey = builder.metricKey;
+    this.metric = builder.metric;
     this.value = builder.value;
   }
 
@@ -48,8 +49,8 @@ public class DefaultAnalyzerMeasure<G extends Serializable> implements AnalyzerM
   }
 
   @Override
-  public String metricKey() {
-    return metricKey;
+  public Metric<G> metric() {
+    return metric;
   }
 
   @Override
@@ -63,14 +64,14 @@ public class DefaultAnalyzerMeasure<G extends Serializable> implements AnalyzerM
       return false;
     }
     DefaultAnalyzerMeasure<?> other = (DefaultAnalyzerMeasure<?>) obj;
-    return metricKey.equals(other.metricKey)
+    return metric.equals(other.metric)
       && value.equals(other.value)
       && (inputFile == null ? other.inputFile == null : inputFile.equals(other.inputFile));
   }
 
   @Override
   public int hashCode() {
-    return metricKey.hashCode()
+    return metric.hashCode()
       + value.hashCode()
       + (inputFile != null ? inputFile.hashCode() : 0);
   }
@@ -78,7 +79,7 @@ public class DefaultAnalyzerMeasure<G extends Serializable> implements AnalyzerM
   @Override
   public String toString() {
     return "AnalyzerMeasure[" + (inputFile != null ? "inputFile=" + inputFile.toString() : "onProject")
-      + ",metricKey=" + metricKey + ",value=" + value + "]";
+      + ",metric=" + metric + ",value=" + value + "]";
   }
 
 }
index 3df03fb52414420983c1856a7f298ed1a3ce6ab3..4eea5eb624d1dc8411213efb4a777e62d4915308 100644 (file)
@@ -31,14 +31,14 @@ public class DefaultAnalyzerMeasureBuilder<G extends Serializable> implements An
 
   Boolean onProject = null;
   InputFile file;
-  String metricKey;
+  Metric<G> metric;
   G value;
 
   @Override
-  public AnalyzerMeasureBuilder<G> onFile(InputFile file) {
+  public AnalyzerMeasureBuilder<G> onFile(InputFile inputFile) {
     Preconditions.checkState(onProject == null, "onFile or onProject can be called only once");
-    Preconditions.checkNotNull(file, "InputFile should be non null");
-    this.file = file;
+    Preconditions.checkNotNull(inputFile, "inputFile should be non null");
+    this.file = inputFile;
     this.onProject = false;
     return this;
   }
@@ -51,20 +51,17 @@ public class DefaultAnalyzerMeasureBuilder<G extends Serializable> implements An
     return this;
   }
 
-  private AnalyzerMeasureBuilder<G> metricKey(String metricKey) {
-    Preconditions.checkState(metricKey != null, "Metric already defined");
-    this.metricKey = metricKey;
-    return this;
-  }
-
   @Override
   public AnalyzerMeasureBuilder<G> forMetric(Metric<G> metric) {
-    return metricKey(metric.key());
+    Preconditions.checkState(metric != null, "Metric already defined");
+    Preconditions.checkNotNull(metric, "metric should be non null");
+    this.metric = metric;
+    return this;
   }
 
   @Override
   public AnalyzerMeasureBuilder<G> withValue(G value) {
-    Preconditions.checkState(value != null, "Measure value already defined");
+    Preconditions.checkState(this.value == null, "Measure value already defined");
     Preconditions.checkNotNull(value, "Measure value can't be null");
     this.value = value;
     return this;