diff options
author | Julien HENRY <julien.henry@sonarsource.com> | 2014-06-18 17:28:54 +0200 |
---|---|---|
committer | Julien HENRY <julien.henry@sonarsource.com> | 2014-06-18 17:29:46 +0200 |
commit | 7b8ec8c4770a2c856cc52f98feddb0231d172051 (patch) | |
tree | 6cc4fe34e4b8659609888bc4b9a2d3559e6c09b9 /sonar-plugin-api | |
parent | d53af792fde9bd9eae47141a1b8abe17d70fe09d (diff) | |
download | sonarqube-7b8ec8c4770a2c856cc52f98feddb0231d172051.tar.gz sonarqube-7b8ec8c4770a2c856cc52f98feddb0231d172051.zip |
SONAR-5389 Improve analyzer API
Diffstat (limited to 'sonar-plugin-api')
9 files changed, 318 insertions, 116 deletions
diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/batch/analyzer/AnalyzerContext.java b/sonar-plugin-api/src/main/java/org/sonar/api/batch/analyzer/AnalyzerContext.java index 68e9a04aa04..b28ab8af61b 100644 --- a/sonar-plugin-api/src/main/java/org/sonar/api/batch/analyzer/AnalyzerContext.java +++ b/sonar-plugin-api/src/main/java/org/sonar/api/batch/analyzer/AnalyzerContext.java @@ -20,21 +20,39 @@ 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); } diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/batch/analyzer/AnalyzerDescriptor.java b/sonar-plugin-api/src/main/java/org/sonar/api/batch/analyzer/AnalyzerDescriptor.java index f03c98392ec..ab52f9a8b80 100644 --- a/sonar-plugin-api/src/main/java/org/sonar/api/batch/analyzer/AnalyzerDescriptor.java +++ b/sonar-plugin-api/src/main/java/org/sonar/api/batch/analyzer/AnalyzerDescriptor.java @@ -20,21 +20,43 @@ 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); } diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/batch/analyzer/issue/AnalyzerIssue.java b/sonar-plugin-api/src/main/java/org/sonar/api/batch/analyzer/issue/AnalyzerIssue.java index 7aa2b2e163f..ed1de433607 100644 --- a/sonar-plugin-api/src/main/java/org/sonar/api/batch/analyzer/issue/AnalyzerIssue.java +++ b/sonar-plugin-api/src/main/java/org/sonar/api/batch/analyzer/issue/AnalyzerIssue.java @@ -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 index 00000000000..5c272632984 --- /dev/null +++ b/sonar-plugin-api/src/main/java/org/sonar/api/batch/analyzer/issue/AnalyzerIssueBuilder.java @@ -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 index 00000000000..7b10db79945 --- /dev/null +++ b/sonar-plugin-api/src/main/java/org/sonar/api/batch/analyzer/issue/internal/DefaultAnalyzerIssue.java @@ -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 index 00000000000..7092caa368d --- /dev/null +++ b/sonar-plugin-api/src/main/java/org/sonar/api/batch/analyzer/issue/internal/DefaultAnalyzerIssueBuilder.java @@ -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); + } + +} diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/batch/analyzer/measure/AnalyzerMeasure.java b/sonar-plugin-api/src/main/java/org/sonar/api/batch/analyzer/measure/AnalyzerMeasure.java index e0b89e10812..554efed34de 100644 --- a/sonar-plugin-api/src/main/java/org/sonar/api/batch/analyzer/measure/AnalyzerMeasure.java +++ b/sonar-plugin-api/src/main/java/org/sonar/api/batch/analyzer/measure/AnalyzerMeasure.java @@ -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(); diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/batch/analyzer/measure/internal/DefaultAnalyzerMeasure.java b/sonar-plugin-api/src/main/java/org/sonar/api/batch/analyzer/measure/internal/DefaultAnalyzerMeasure.java index 63d9736e07d..fa87d0953c9 100644 --- a/sonar-plugin-api/src/main/java/org/sonar/api/batch/analyzer/measure/internal/DefaultAnalyzerMeasure.java +++ b/sonar-plugin-api/src/main/java/org/sonar/api/batch/analyzer/measure/internal/DefaultAnalyzerMeasure.java @@ -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 + "]"; } } diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/batch/analyzer/measure/internal/DefaultAnalyzerMeasureBuilder.java b/sonar-plugin-api/src/main/java/org/sonar/api/batch/analyzer/measure/internal/DefaultAnalyzerMeasureBuilder.java index 3df03fb5241..4eea5eb624d 100644 --- a/sonar-plugin-api/src/main/java/org/sonar/api/batch/analyzer/measure/internal/DefaultAnalyzerMeasureBuilder.java +++ b/sonar-plugin-api/src/main/java/org/sonar/api/batch/analyzer/measure/internal/DefaultAnalyzerMeasureBuilder.java @@ -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; |