]> source.dussan.org Git - sonarqube.git/commitdiff
Extract implementation from plugin API - Scanner Sensor
authorDuarte Meneses <duarte.meneses@sonarsource.com>
Tue, 4 Jun 2019 15:41:54 +0000 (10:41 -0500)
committerSonarTech <sonartech@sonarsource.com>
Fri, 12 Jul 2019 18:21:13 +0000 (20:21 +0200)
31 files changed:
sonar-plugin-api/src/main/java/org/sonar/api/batch/postjob/internal/DefaultPostJobDescriptor.java [deleted file]
sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/internal/DefaultSensorDescriptor.java [deleted file]
sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/internal/SensorStorage.java
sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/issue/internal/AbstractDefaultIssue.java [deleted file]
sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/issue/internal/DefaultExternalIssue.java [deleted file]
sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/issue/internal/DefaultIssue.java [deleted file]
sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/issue/internal/DefaultIssueLocation.java [deleted file]
sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/issue/internal/package-info.java [deleted file]
sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/measure/internal/DefaultMeasure.java [deleted file]
sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/measure/internal/package-info.java [deleted file]
sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/rule/internal/DefaultAdHocRule.java [deleted file]
sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/rule/internal/package-info.java [deleted file]
sonar-scanner-engine/src/main/java/org/sonar/scanner/DefaultFileLinesContext.java
sonar-scanner-engine/src/main/java/org/sonar/scanner/postjob/DefaultPostJobDescriptor.java [new file with mode: 0644]
sonar-scanner-engine/src/main/java/org/sonar/scanner/report/TestExecutionPublisher.java
sonar-scanner-engine/src/main/java/org/sonar/scanner/sensor/AbstractDefaultIssue.java [new file with mode: 0644]
sonar-scanner-engine/src/main/java/org/sonar/scanner/sensor/AbstractSensorOptimizer.java
sonar-scanner-engine/src/main/java/org/sonar/scanner/sensor/AbstractSensorWrapper.java
sonar-scanner-engine/src/main/java/org/sonar/scanner/sensor/DefaultAdHocRule.java [new file with mode: 0644]
sonar-scanner-engine/src/main/java/org/sonar/scanner/sensor/DefaultExternalIssue.java [new file with mode: 0644]
sonar-scanner-engine/src/main/java/org/sonar/scanner/sensor/DefaultIssue.java [new file with mode: 0644]
sonar-scanner-engine/src/main/java/org/sonar/scanner/sensor/DefaultIssueLocation.java [new file with mode: 0644]
sonar-scanner-engine/src/main/java/org/sonar/scanner/sensor/DefaultMeasure.java [new file with mode: 0644]
sonar-scanner-engine/src/main/java/org/sonar/scanner/sensor/DefaultSensorDescriptor.java [new file with mode: 0644]
sonar-scanner-engine/src/main/java/org/sonar/scanner/sensor/DefaultSensorStorage.java
sonar-scanner-engine/src/main/java/org/sonar/scanner/sensor/InMemorySensorStorage.java
sonar-scanner-engine/src/main/java/org/sonar/scanner/sensor/ProjectSensorContext.java
sonar-scanner-engine/src/main/java/org/sonar/scanner/sensor/SensorContextTester.java
sonar-scanner-engine/src/test/java/org/sonar/scanner/DefaultFileLinesContextTest.java
sonar-scanner-engine/src/test/java/org/sonar/scanner/issue/IssuePublisherTest.java
sonar-scanner-engine/src/test/java/org/sonar/scanner/sensor/DefaultSensorStorageTest.java

diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/batch/postjob/internal/DefaultPostJobDescriptor.java b/sonar-plugin-api/src/main/java/org/sonar/api/batch/postjob/internal/DefaultPostJobDescriptor.java
deleted file mode 100644 (file)
index c3c2396..0000000
+++ /dev/null
@@ -1,56 +0,0 @@
-/*
- * SonarQube
- * Copyright (C) 2009-2019 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program 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.
- *
- * This program 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.postjob.internal;
-
-import java.util.Arrays;
-import java.util.Collection;
-import org.sonar.api.batch.postjob.PostJobDescriptor;
-
-public class DefaultPostJobDescriptor implements PostJobDescriptor {
-
-  private String name;
-  private String[] properties = new String[0];
-
-  public String name() {
-    return name;
-  }
-
-  public Collection<String> properties() {
-    return Arrays.asList(properties);
-  }
-
-  @Override
-  public DefaultPostJobDescriptor name(String name) {
-    this.name = name;
-    return this;
-  }
-
-  @Override
-  public DefaultPostJobDescriptor requireProperty(String... propertyKey) {
-    return requireProperties(propertyKey);
-  }
-
-  @Override
-  public DefaultPostJobDescriptor requireProperties(String... propertyKeys) {
-    this.properties = propertyKeys;
-    return this;
-  }
-
-}
diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/internal/DefaultSensorDescriptor.java b/sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/internal/DefaultSensorDescriptor.java
deleted file mode 100644 (file)
index ef29870..0000000
+++ /dev/null
@@ -1,123 +0,0 @@
-/*
- * SonarQube
- * Copyright (C) 2009-2019 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program 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.
- *
- * This program 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.sensor.internal;
-
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.function.Predicate;
-import javax.annotation.Nullable;
-import org.sonar.api.batch.fs.InputFile;
-import org.sonar.api.batch.sensor.SensorDescriptor;
-import org.sonar.api.config.Configuration;
-
-import static java.util.Arrays.asList;
-
-public class DefaultSensorDescriptor implements SensorDescriptor {
-
-  private String name;
-  private String[] languages = new String[0];
-  private InputFile.Type type = null;
-  private String[] ruleRepositories = new String[0];
-  private boolean global = false;
-  private Predicate<Configuration> configurationPredicate;
-
-  public String name() {
-    return name;
-  }
-
-  public Collection<String> languages() {
-    return Arrays.asList(languages);
-  }
-
-  @Nullable
-  public InputFile.Type type() {
-    return type;
-  }
-
-  public Collection<String> ruleRepositories() {
-    return Arrays.asList(ruleRepositories);
-  }
-
-  public Predicate<Configuration> configurationPredicate() {
-    return configurationPredicate;
-  }
-
-  public boolean isGlobal() {
-    return global;
-  }
-
-  @Override
-  public DefaultSensorDescriptor name(String name) {
-    this.name = name;
-    return this;
-  }
-
-  @Override
-  public DefaultSensorDescriptor onlyOnLanguage(String languageKey) {
-    return onlyOnLanguages(languageKey);
-  }
-
-  @Override
-  public DefaultSensorDescriptor onlyOnLanguages(String... languageKeys) {
-    this.languages = languageKeys;
-    return this;
-  }
-
-  @Override
-  public DefaultSensorDescriptor onlyOnFileType(InputFile.Type type) {
-    this.type = type;
-    return this;
-  }
-
-  @Override
-  public DefaultSensorDescriptor createIssuesForRuleRepository(String... repositoryKey) {
-    return createIssuesForRuleRepositories(repositoryKey);
-  }
-
-  @Override
-  public DefaultSensorDescriptor createIssuesForRuleRepositories(String... repositoryKeys) {
-    this.ruleRepositories = repositoryKeys;
-    return this;
-  }
-
-  @Override
-  public DefaultSensorDescriptor requireProperty(String... propertyKey) {
-    return requireProperties(propertyKey);
-  }
-
-  @Override
-  public DefaultSensorDescriptor requireProperties(String... propertyKeys) {
-    this.configurationPredicate = config -> asList(propertyKeys).stream().allMatch(config::hasKey);
-    return this;
-  }
-
-  @Override
-  public SensorDescriptor global() {
-    this.global = true;
-    return this;
-  }
-
-  @Override
-  public SensorDescriptor onlyWhenConfiguration(Predicate<Configuration> configurationPredicate) {
-    this.configurationPredicate = configurationPredicate;
-    return this;
-  }
-
-}
index f3d1210a2d3e668404ecc0d7e6c2f85b4d7e8f64..2bfe79bfba84898de9fca0ffaaa1690c24773f3b 100644 (file)
@@ -19,6 +19,8 @@
  */
 package org.sonar.api.batch.sensor.internal;
 
+import org.sonar.api.batch.sensor.issue.ExternalIssue;
+import org.sonar.api.batch.sensor.rule.AdHocRule;
 import org.sonar.api.scanner.ScannerSide;
 import org.sonar.api.batch.sensor.code.internal.DefaultSignificantCode;
 import org.sonar.api.batch.sensor.coverage.internal.DefaultCoverage;
@@ -26,9 +28,7 @@ import org.sonar.api.batch.sensor.cpd.internal.DefaultCpdTokens;
 import org.sonar.api.batch.sensor.error.AnalysisError;
 import org.sonar.api.batch.sensor.highlighting.internal.DefaultHighlighting;
 import org.sonar.api.batch.sensor.issue.Issue;
-import org.sonar.api.batch.sensor.issue.internal.DefaultExternalIssue;
 import org.sonar.api.batch.sensor.measure.Measure;
-import org.sonar.api.batch.sensor.rule.internal.DefaultAdHocRule;
 import org.sonar.api.batch.sensor.symbol.internal.DefaultSymbolTable;
 
 /**
@@ -42,9 +42,9 @@ public interface SensorStorage {
 
   void store(Issue issue);
 
-  void store(DefaultExternalIssue issue);
+  void store(ExternalIssue issue);
 
-  void store(DefaultAdHocRule adHocRule);
+  void store(AdHocRule adHocRule);
 
   void store(DefaultHighlighting highlighting);
 
diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/issue/internal/AbstractDefaultIssue.java b/sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/issue/internal/AbstractDefaultIssue.java
deleted file mode 100644 (file)
index 4f24641..0000000
+++ /dev/null
@@ -1,122 +0,0 @@
-/*
- * SonarQube
- * Copyright (C) 2009-2019 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program 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.
- *
- * This program 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.sensor.issue.internal;
-
-import java.nio.file.Path;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.List;
-import java.util.Objects;
-import java.util.Optional;
-import javax.annotation.Nullable;
-import org.sonar.api.batch.fs.InputComponent;
-import org.sonar.api.batch.fs.internal.DefaultInputDir;
-import org.sonar.api.batch.fs.internal.DefaultInputModule;
-import org.sonar.api.batch.fs.internal.DefaultInputProject;
-import org.sonar.api.batch.sensor.internal.DefaultStorable;
-import org.sonar.api.batch.sensor.internal.SensorStorage;
-import org.sonar.api.batch.sensor.issue.Issue.Flow;
-import org.sonar.api.batch.sensor.issue.IssueLocation;
-import org.sonar.api.batch.sensor.issue.NewIssueLocation;
-import org.sonar.api.utils.PathUtils;
-
-import static java.util.Collections.unmodifiableList;
-import static java.util.stream.Collectors.toList;
-import static org.sonar.api.utils.Preconditions.checkArgument;
-import static org.sonar.api.utils.Preconditions.checkState;
-
-public abstract class AbstractDefaultIssue<T extends AbstractDefaultIssue> extends DefaultStorable {
-  protected IssueLocation primaryLocation;
-  protected List<List<IssueLocation>> flows = new ArrayList<>();
-  protected DefaultInputProject project;
-
-  protected AbstractDefaultIssue(DefaultInputProject project) {
-    this(project, null);
-  }
-
-  public AbstractDefaultIssue(DefaultInputProject project, @Nullable SensorStorage storage) {
-    super(storage);
-    this.project = project;
-  }
-
-  public IssueLocation primaryLocation() {
-    return primaryLocation;
-  }
-
-  public List<Flow> flows() {
-    return this.flows.stream()
-      .<Flow>map(l -> () -> unmodifiableList(new ArrayList<>(l)))
-      .collect(toList());
-  }
-
-  public NewIssueLocation newLocation() {
-    return new DefaultIssueLocation();
-  }
-
-  public T at(NewIssueLocation primaryLocation) {
-    checkArgument(primaryLocation != null, "Cannot use a location that is null");
-    checkState(this.primaryLocation == null, "at() already called");
-    this.primaryLocation = rewriteLocation((DefaultIssueLocation) primaryLocation);
-    checkArgument(this.primaryLocation.inputComponent() != null, "Cannot use a location with no input component");
-    return (T) this;
-  }
-
-  public T addLocation(NewIssueLocation secondaryLocation) {
-    flows.add(Collections.singletonList(rewriteLocation((DefaultIssueLocation) secondaryLocation)));
-    return (T) this;
-  }
-
-  public T addFlow(Iterable<NewIssueLocation> locations) {
-    List<IssueLocation> flowAsList = new ArrayList<>();
-    for (NewIssueLocation issueLocation : locations) {
-      flowAsList.add(rewriteLocation((DefaultIssueLocation) issueLocation));
-    }
-    flows.add(flowAsList);
-    return (T) this;
-  }
-
-  private DefaultIssueLocation rewriteLocation(DefaultIssueLocation location) {
-    InputComponent component = location.inputComponent();
-    Optional<Path> dirOrModulePath = Optional.empty();
-
-    if (component instanceof DefaultInputDir) {
-      DefaultInputDir dirComponent = (DefaultInputDir) component;
-      dirOrModulePath = Optional.of(project.getBaseDir().relativize(dirComponent.path()));
-    } else if (component instanceof DefaultInputModule && !Objects.equals(project.key(), component.key())) {
-      DefaultInputModule moduleComponent = (DefaultInputModule) component;
-      dirOrModulePath = Optional.of(project.getBaseDir().relativize(moduleComponent.getBaseDir()));
-    }
-
-    if (dirOrModulePath.isPresent()) {
-      String path = PathUtils.sanitize(dirOrModulePath.get().toString());
-      DefaultIssueLocation fixedLocation = new DefaultIssueLocation();
-      fixedLocation.on(project);
-      StringBuilder fullMessage = new StringBuilder();
-      if (path != null && !path.isEmpty()) {
-        fullMessage.append("[").append(path).append("] ");
-      }
-      fullMessage.append(location.message());
-      fixedLocation.message(fullMessage.toString());
-      return fixedLocation;
-    } else {
-      return location;
-    }
-  }
-}
diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/issue/internal/DefaultExternalIssue.java b/sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/issue/internal/DefaultExternalIssue.java
deleted file mode 100644 (file)
index c402d6b..0000000
+++ /dev/null
@@ -1,134 +0,0 @@
-/*
- * SonarQube
- * Copyright (C) 2009-2019 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program 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.
- *
- * This program 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.sensor.issue.internal;
-
-import javax.annotation.Nullable;
-import org.sonar.api.batch.fs.internal.DefaultInputProject;
-import org.sonar.api.batch.rule.Severity;
-import org.sonar.api.batch.sensor.internal.SensorStorage;
-import org.sonar.api.batch.sensor.issue.ExternalIssue;
-import org.sonar.api.batch.sensor.issue.NewExternalIssue;
-import org.sonar.api.rule.RuleKey;
-import org.sonar.api.rules.RuleType;
-
-import static java.lang.String.format;
-import static java.util.Objects.requireNonNull;
-import static org.sonar.api.utils.Preconditions.checkArgument;
-import static org.sonar.api.utils.Preconditions.checkState;
-
-public class DefaultExternalIssue extends AbstractDefaultIssue<DefaultExternalIssue> implements ExternalIssue, NewExternalIssue {
-  private Long effort;
-  private Severity severity;
-  private RuleType type;
-  private String engineId;
-  private String ruleId;
-
-  public DefaultExternalIssue(DefaultInputProject project) {
-    this(project, null);
-  }
-
-  public DefaultExternalIssue(DefaultInputProject project, @Nullable SensorStorage storage) {
-    super(project, storage);
-  }
-
-  @Override
-  public DefaultExternalIssue remediationEffortMinutes(@Nullable Long effort) {
-    checkArgument(effort == null || effort >= 0, format("effort must be greater than or equal 0 (got %s)", effort));
-    this.effort = effort;
-    return this;
-  }
-
-  @Override
-  public DefaultExternalIssue severity(Severity severity) {
-    this.severity = severity;
-    return this;
-  }
-
-  @Override
-  public String engineId() {
-    return engineId;
-  }
-
-  @Override
-  public String ruleId() {
-    return ruleId;
-  }
-
-  @Override
-  public Severity severity() {
-    return this.severity;
-  }
-
-  @Override
-  public Long remediationEffort() {
-    return this.effort;
-  }
-
-  @Override
-  public void doSave() {
-    requireNonNull(this.engineId, "Engine id is mandatory on external issue");
-    requireNonNull(this.ruleId, "Rule id is mandatory on external issue");
-    checkState(primaryLocation != null, "Primary location is mandatory on every external issue");
-    checkState(primaryLocation.inputComponent().isFile(), "External issues must be located in files");
-    checkState(primaryLocation.message() != null, "External issues must have a message");
-    checkState(severity != null, "Severity is mandatory on every external issue");
-    checkState(type != null, "Type is mandatory on every external issue");
-    storage.store(this);
-  }
-
-  @Override
-  public RuleType type() {
-    return type;
-  }
-
-  @Override
-  public NewExternalIssue engineId(String engineId) {
-    this.engineId = engineId;
-    return this;
-  }
-
-  @Override
-  public NewExternalIssue ruleId(String ruleId) {
-    this.ruleId = ruleId;
-    return this;
-  }
-
-  @Override
-  public DefaultExternalIssue forRule(RuleKey ruleKey) {
-    this.engineId = ruleKey.repository();
-    this.ruleId = ruleKey.rule();
-    return this;
-  }
-
-  @Override
-  public RuleKey ruleKey() {
-    if (engineId != null && ruleId != null) {
-      return RuleKey.of(RuleKey.EXTERNAL_RULE_REPO_PREFIX + engineId, ruleId);
-    }
-    return null;
-  }
-
-  @Override
-  public DefaultExternalIssue type(RuleType type) {
-    this.type = type;
-    return this;
-  }
-
-}
diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/issue/internal/DefaultIssue.java b/sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/issue/internal/DefaultIssue.java
deleted file mode 100644 (file)
index 2f59ddd..0000000
+++ /dev/null
@@ -1,93 +0,0 @@
-/*
- * SonarQube
- * Copyright (C) 2009-2019 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program 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.
- *
- * This program 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.sensor.issue.internal;
-
-import javax.annotation.Nullable;
-import org.sonar.api.batch.fs.internal.DefaultInputProject;
-import org.sonar.api.batch.rule.Severity;
-import org.sonar.api.batch.sensor.internal.SensorStorage;
-import org.sonar.api.batch.sensor.issue.Issue;
-import org.sonar.api.batch.sensor.issue.IssueLocation;
-import org.sonar.api.batch.sensor.issue.NewIssue;
-import org.sonar.api.rule.RuleKey;
-
-import static java.lang.String.format;
-import static java.util.Objects.requireNonNull;
-import static org.sonar.api.utils.Preconditions.checkArgument;
-import static org.sonar.api.utils.Preconditions.checkState;
-
-public class DefaultIssue extends AbstractDefaultIssue<DefaultIssue> implements Issue, NewIssue {
-  private RuleKey ruleKey;
-  private Double gap;
-  private Severity overriddenSeverity;
-
-  public DefaultIssue(DefaultInputProject project) {
-    this(project, null);
-  }
-
-  public DefaultIssue(DefaultInputProject project, @Nullable SensorStorage storage) {
-    super(project, storage);
-  }
-
-  public DefaultIssue forRule(RuleKey ruleKey) {
-    this.ruleKey = ruleKey;
-    return this;
-  }
-
-  public RuleKey ruleKey() {
-    return this.ruleKey;
-  }
-
-  @Override
-  public DefaultIssue gap(@Nullable Double gap) {
-    checkArgument(gap == null || gap >= 0, format("Gap must be greater than or equal 0 (got %s)", gap));
-    this.gap = gap;
-    return this;
-  }
-
-  @Override
-  public DefaultIssue overrideSeverity(@Nullable Severity severity) {
-    this.overriddenSeverity = severity;
-    return this;
-  }
-
-  @Override
-  public Severity overriddenSeverity() {
-    return this.overriddenSeverity;
-  }
-
-  @Override
-  public Double gap() {
-    return this.gap;
-  }
-
-  @Override
-  public IssueLocation primaryLocation() {
-    return primaryLocation;
-  }
-
-  @Override
-  public void doSave() {
-    requireNonNull(this.ruleKey, "ruleKey is mandatory on issue");
-    checkState(primaryLocation != null, "Primary location is mandatory on every issue");
-    storage.store(this);
-  }
-
-}
diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/issue/internal/DefaultIssueLocation.java b/sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/issue/internal/DefaultIssueLocation.java
deleted file mode 100644 (file)
index 124e787..0000000
+++ /dev/null
@@ -1,92 +0,0 @@
-/*
- * SonarQube
- * Copyright (C) 2009-2019 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program 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.
- *
- * This program 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.sensor.issue.internal;
-
-import javax.annotation.Nullable;
-import org.sonar.api.batch.fs.InputComponent;
-import org.sonar.api.batch.fs.TextRange;
-import org.sonar.api.batch.fs.internal.DefaultInputFile;
-import org.sonar.api.batch.sensor.issue.IssueLocation;
-import org.sonar.api.batch.sensor.issue.NewIssueLocation;
-
-import static java.util.Objects.requireNonNull;
-import static org.apache.commons.lang.StringUtils.abbreviate;
-import static org.apache.commons.lang.StringUtils.trim;
-import static org.sonar.api.utils.Preconditions.checkArgument;
-import static org.sonar.api.utils.Preconditions.checkState;
-
-public class DefaultIssueLocation implements NewIssueLocation, IssueLocation {
-
-  private InputComponent component;
-  private TextRange textRange;
-  private String message;
-
-  @Override
-  public DefaultIssueLocation on(InputComponent component) {
-    checkArgument(component != null, "Component can't be null");
-    checkState(this.component == null, "on() already called");
-    this.component = component;
-    return this;
-  }
-
-  @Override
-  public DefaultIssueLocation at(TextRange location) {
-    checkState(this.component != null, "at() should be called after on()");
-    checkState(this.component.isFile(), "at() should be called only for an InputFile.");
-    DefaultInputFile file = (DefaultInputFile) this.component;
-    file.validate(location);
-    this.textRange = location;
-    return this;
-  }
-
-  @Override
-  public DefaultIssueLocation message(String message) {
-    requireNonNull(message, "Message can't be null");
-    if (message.contains("\u0000")) {
-      throw new IllegalArgumentException(unsupportedCharacterError(message, component));
-    }
-    this.message = abbreviate(trim(message), MESSAGE_MAX_SIZE);
-    return this;
-  }
-
-  private static String unsupportedCharacterError(String message, @Nullable InputComponent component) {
-    String error = "Character \\u0000 is not supported in issue message '" + message + "'";
-    if (component != null) {
-      error += ", on component: " + component.toString();
-    }
-    return error;
-  }
-
-  @Override
-  public InputComponent inputComponent() {
-    return this.component;
-  }
-
-  @Override
-  public TextRange textRange() {
-    return textRange;
-  }
-
-  @Override
-  public String message() {
-    return this.message;
-  }
-
-}
diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/issue/internal/package-info.java b/sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/issue/internal/package-info.java
deleted file mode 100644 (file)
index f63492c..0000000
+++ /dev/null
@@ -1,21 +0,0 @@
-/*
- * SonarQube
- * Copyright (C) 2009-2019 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program 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.
- *
- * This program 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.
- */
-@javax.annotation.ParametersAreNonnullByDefault
-package org.sonar.api.batch.sensor.issue.internal;
diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/measure/internal/DefaultMeasure.java b/sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/measure/internal/DefaultMeasure.java
deleted file mode 100644 (file)
index b359e2d..0000000
+++ /dev/null
@@ -1,140 +0,0 @@
-/*
- * SonarQube
- * Copyright (C) 2009-2019 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program 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.
- *
- * This program 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.sensor.measure.internal;
-
-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.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 static java.util.Objects.requireNonNull;
-import static org.sonar.api.utils.Preconditions.checkArgument;
-import static org.sonar.api.utils.Preconditions.checkState;
-
-public class DefaultMeasure<G extends Serializable> extends DefaultStorable implements Measure<G>, NewMeasure<G> {
-
-  private InputComponent component;
-  private Metric<G> metric;
-  private G value;
-  private boolean fromCore = false;
-
-  public DefaultMeasure() {
-    super();
-  }
-
-  public DefaultMeasure(@Nullable SensorStorage storage) {
-    super(storage);
-  }
-
-  @Override
-  public DefaultMeasure<G> on(InputComponent component) {
-    checkArgument(component != null, "Component can't be null");
-    checkState(this.component == null, "on() already called");
-    this.component = component;
-    return this;
-  }
-
-  @Override
-  public DefaultMeasure<G> forMetric(Metric<G> metric) {
-    checkState(this.metric == null, "Metric already defined");
-    requireNonNull(metric, "metric should be non null");
-    this.metric = metric;
-    return this;
-  }
-
-  @Override
-  public DefaultMeasure<G> withValue(G value) {
-    checkState(this.value == null, "Measure value already defined");
-    requireNonNull(value, "Measure value can't be null");
-    this.value = value;
-    return this;
-  }
-
-  /**
-   * For internal use.
-   */
-  public boolean isFromCore() {
-    return fromCore;
-  }
-
-  /**
-   * For internal use. Used by core components to bypass check that prevent a plugin to store core measures.
-   */
-  public DefaultMeasure<G> setFromCore() {
-    this.fromCore = true;
-    return this;
-  }
-
-  @Override
-  public void doSave() {
-    requireNonNull(this.value, "Measure value can't be null");
-    requireNonNull(this.metric, "Measure metric can't be null");
-    checkState(this.metric.valueType().equals(this.value.getClass()), "Measure value should be of type %s", this.metric.valueType());
-    storage.store(this);
-  }
-
-  @Override
-  public Metric<G> metric() {
-    return metric;
-  }
-
-  @Override
-  public InputComponent inputComponent() {
-    return component;
-  }
-
-  @Override
-  public G value() {
-    return value;
-  }
-
-  // For testing purpose
-
-  @Override
-  public boolean equals(Object obj) {
-    if (obj == null) {
-      return false;
-    }
-    if (obj == this) {
-      return true;
-    }
-    if (obj.getClass() != getClass()) {
-      return false;
-    }
-    DefaultMeasure<?> rhs = (DefaultMeasure<?>) obj;
-    return new EqualsBuilder()
-      .append(component, rhs.component)
-      .append(metric, rhs.metric)
-      .append(value, rhs.value)
-      .isEquals();
-  }
-
-  @Override
-  public int hashCode() {
-    return new HashCodeBuilder(27, 45).append(component).append(metric).append(value).toHashCode();
-  }
-
-}
diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/measure/internal/package-info.java b/sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/measure/internal/package-info.java
deleted file mode 100644 (file)
index 8b3dfba..0000000
+++ /dev/null
@@ -1,21 +0,0 @@
-/*
- * SonarQube
- * Copyright (C) 2009-2019 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program 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.
- *
- * This program 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.
- */
-@javax.annotation.ParametersAreNonnullByDefault
-package org.sonar.api.batch.sensor.measure.internal;
diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/rule/internal/DefaultAdHocRule.java b/sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/rule/internal/DefaultAdHocRule.java
deleted file mode 100644 (file)
index 7ccf8ae..0000000
+++ /dev/null
@@ -1,127 +0,0 @@
-/*
- * SonarQube
- * Copyright (C) 2009-2019 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program 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.
- *
- * This program 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.sensor.rule.internal;
-
-import javax.annotation.CheckForNull;
-import javax.annotation.Nullable;
-import org.sonar.api.batch.rule.Severity;
-import org.sonar.api.batch.sensor.internal.DefaultStorable;
-import org.sonar.api.batch.sensor.internal.SensorStorage;
-import org.sonar.api.batch.sensor.rule.AdHocRule;
-import org.sonar.api.batch.sensor.rule.NewAdHocRule;
-import org.sonar.api.rules.RuleType;
-
-import static org.apache.commons.lang.StringUtils.isNotBlank;
-import static org.sonar.api.utils.Preconditions.checkState;
-
-public class DefaultAdHocRule extends DefaultStorable implements AdHocRule, NewAdHocRule {
-  private Severity severity;
-  private RuleType type;
-  private String name;
-  private String description;
-  private String engineId;
-  private String ruleId;
-
-  public DefaultAdHocRule() {
-    super(null);
-  }
-
-  public DefaultAdHocRule(@Nullable SensorStorage storage) {
-    super(storage);
-  }
-
-  @Override
-  public DefaultAdHocRule severity(Severity severity) {
-    this.severity = severity;
-    return this;
-  }
-
-  @Override
-  public String engineId() {
-    return engineId;
-  }
-
-  @Override
-  public String ruleId() {
-    return ruleId;
-  }
-
-  @Override
-  public String name() {
-    return name;
-  }
-
-  @CheckForNull
-  @Override
-  public String description() {
-    return description;
-  }
-
-  @Override
-  public Severity severity() {
-    return this.severity;
-  }
-
-  @Override
-  public void doSave() {
-    checkState(isNotBlank(engineId), "Engine id is mandatory on ad hoc rule");
-    checkState(isNotBlank(ruleId), "Rule id is mandatory on ad hoc rule");
-    checkState(isNotBlank(name), "Name is mandatory on every ad hoc rule");
-    checkState(severity != null, "Severity is mandatory on every ad hoc rule");
-    checkState(type != null, "Type is mandatory on every ad hoc rule");
-    storage.store(this);
-  }
-
-  @Override
-  public RuleType type() {
-    return type;
-  }
-
-  @Override
-  public DefaultAdHocRule engineId(String engineId) {
-    this.engineId = engineId;
-    return this;
-  }
-
-  @Override
-  public DefaultAdHocRule ruleId(String ruleId) {
-    this.ruleId = ruleId;
-    return this;
-  }
-
-  @Override
-  public DefaultAdHocRule name(String name) {
-    this.name = name;
-    return this;
-  }
-
-  @Override
-  public DefaultAdHocRule description(@Nullable String description) {
-    this.description = description;
-    return this;
-  }
-
-  @Override
-  public DefaultAdHocRule type(RuleType type) {
-    this.type = type;
-    return this;
-  }
-
-}
diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/rule/internal/package-info.java b/sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/rule/internal/package-info.java
deleted file mode 100644 (file)
index 26995ef..0000000
+++ /dev/null
@@ -1,21 +0,0 @@
-/*
- * SonarQube
- * Copyright (C) 2009-2019 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program 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.
- *
- * This program 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.
- */
-@javax.annotation.ParametersAreNonnullByDefault
-package org.sonar.api.batch.sensor.rule.internal;
index eecbbd15e8406d466f7324e111f91c3995fcbadb..be5b715891fb69e262dfa5d69b8626e863e24361 100644 (file)
@@ -28,7 +28,7 @@ import java.util.Map.Entry;
 import org.sonar.api.batch.fs.InputFile;
 import org.sonar.api.batch.measure.MetricFinder;
 import org.sonar.api.batch.sensor.internal.SensorStorage;
-import org.sonar.api.batch.sensor.measure.internal.DefaultMeasure;
+import org.sonar.scanner.sensor.DefaultMeasure;
 import org.sonar.api.measures.CoreMetrics;
 import org.sonar.api.measures.FileLinesContext;
 import org.sonar.api.utils.KeyValueFormat;
diff --git a/sonar-scanner-engine/src/main/java/org/sonar/scanner/postjob/DefaultPostJobDescriptor.java b/sonar-scanner-engine/src/main/java/org/sonar/scanner/postjob/DefaultPostJobDescriptor.java
new file mode 100644 (file)
index 0000000..c3c2396
--- /dev/null
@@ -0,0 +1,56 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2019 SonarSource SA
+ * mailto:info AT sonarsource DOT com
+ *
+ * This program 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.
+ *
+ * This program 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.postjob.internal;
+
+import java.util.Arrays;
+import java.util.Collection;
+import org.sonar.api.batch.postjob.PostJobDescriptor;
+
+public class DefaultPostJobDescriptor implements PostJobDescriptor {
+
+  private String name;
+  private String[] properties = new String[0];
+
+  public String name() {
+    return name;
+  }
+
+  public Collection<String> properties() {
+    return Arrays.asList(properties);
+  }
+
+  @Override
+  public DefaultPostJobDescriptor name(String name) {
+    this.name = name;
+    return this;
+  }
+
+  @Override
+  public DefaultPostJobDescriptor requireProperty(String... propertyKey) {
+    return requireProperties(propertyKey);
+  }
+
+  @Override
+  public DefaultPostJobDescriptor requireProperties(String... propertyKeys) {
+    this.properties = propertyKeys;
+    return this;
+  }
+
+}
index 9c19a887d68162ae80889f32de3b55488b88828e..ad4ac749120bfbc3dfd7f251ff2501d1de2c808b 100644 (file)
@@ -26,7 +26,7 @@ import org.sonar.api.batch.fs.InputComponent;
 import org.sonar.api.batch.fs.InputFile;
 import org.sonar.api.batch.fs.internal.DefaultInputComponent;
 import org.sonar.api.batch.fs.internal.DefaultInputFile;
-import org.sonar.api.batch.sensor.measure.internal.DefaultMeasure;
+import org.sonar.scanner.sensor.DefaultMeasure;
 import org.sonar.api.test.MutableTestPlan;
 import org.sonar.api.test.TestCase;
 import org.sonar.api.test.TestCase.Status;
diff --git a/sonar-scanner-engine/src/main/java/org/sonar/scanner/sensor/AbstractDefaultIssue.java b/sonar-scanner-engine/src/main/java/org/sonar/scanner/sensor/AbstractDefaultIssue.java
new file mode 100644 (file)
index 0000000..b77d114
--- /dev/null
@@ -0,0 +1,122 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2019 SonarSource SA
+ * mailto:info AT sonarsource DOT com
+ *
+ * This program 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.
+ *
+ * This program 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.scanner.sensor;
+
+import java.nio.file.Path;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import java.util.Objects;
+import java.util.Optional;
+import javax.annotation.Nullable;
+import org.sonar.api.batch.fs.InputComponent;
+import org.sonar.api.batch.fs.internal.DefaultInputDir;
+import org.sonar.api.batch.fs.internal.DefaultInputModule;
+import org.sonar.api.batch.fs.internal.DefaultInputProject;
+import org.sonar.api.batch.sensor.internal.DefaultStorable;
+import org.sonar.api.batch.sensor.internal.SensorStorage;
+import org.sonar.api.batch.sensor.issue.Issue.Flow;
+import org.sonar.api.batch.sensor.issue.IssueLocation;
+import org.sonar.api.batch.sensor.issue.NewIssueLocation;
+import org.sonar.api.utils.PathUtils;
+
+import static java.util.Collections.unmodifiableList;
+import static java.util.stream.Collectors.toList;
+import static org.sonar.api.utils.Preconditions.checkArgument;
+import static org.sonar.api.utils.Preconditions.checkState;
+
+public abstract class AbstractDefaultIssue<T extends AbstractDefaultIssue> extends DefaultStorable {
+  protected IssueLocation primaryLocation;
+  protected List<List<IssueLocation>> flows = new ArrayList<>();
+  protected DefaultInputProject project;
+
+  protected AbstractDefaultIssue(DefaultInputProject project) {
+    this(project, null);
+  }
+
+  public AbstractDefaultIssue(DefaultInputProject project, @Nullable SensorStorage storage) {
+    super(storage);
+    this.project = project;
+  }
+
+  public IssueLocation primaryLocation() {
+    return primaryLocation;
+  }
+
+  public List<Flow> flows() {
+    return this.flows.stream()
+      .<Flow>map(l -> () -> unmodifiableList(new ArrayList<>(l)))
+      .collect(toList());
+  }
+
+  public NewIssueLocation newLocation() {
+    return new DefaultIssueLocation();
+  }
+
+  public T at(NewIssueLocation primaryLocation) {
+    checkArgument(primaryLocation != null, "Cannot use a location that is null");
+    checkState(this.primaryLocation == null, "at() already called");
+    this.primaryLocation = rewriteLocation((DefaultIssueLocation) primaryLocation);
+    checkArgument(this.primaryLocation.inputComponent() != null, "Cannot use a location with no input component");
+    return (T) this;
+  }
+
+  public T addLocation(NewIssueLocation secondaryLocation) {
+    flows.add(Collections.singletonList(rewriteLocation((DefaultIssueLocation) secondaryLocation)));
+    return (T) this;
+  }
+
+  public T addFlow(Iterable<NewIssueLocation> locations) {
+    List<IssueLocation> flowAsList = new ArrayList<>();
+    for (NewIssueLocation issueLocation : locations) {
+      flowAsList.add(rewriteLocation((DefaultIssueLocation) issueLocation));
+    }
+    flows.add(flowAsList);
+    return (T) this;
+  }
+
+  private DefaultIssueLocation rewriteLocation(DefaultIssueLocation location) {
+    InputComponent component = location.inputComponent();
+    Optional<Path> dirOrModulePath = Optional.empty();
+
+    if (component instanceof DefaultInputDir) {
+      DefaultInputDir dirComponent = (DefaultInputDir) component;
+      dirOrModulePath = Optional.of(project.getBaseDir().relativize(dirComponent.path()));
+    } else if (component instanceof DefaultInputModule && !Objects.equals(project.key(), component.key())) {
+      DefaultInputModule moduleComponent = (DefaultInputModule) component;
+      dirOrModulePath = Optional.of(project.getBaseDir().relativize(moduleComponent.getBaseDir()));
+    }
+
+    if (dirOrModulePath.isPresent()) {
+      String path = PathUtils.sanitize(dirOrModulePath.get().toString());
+      DefaultIssueLocation fixedLocation = new DefaultIssueLocation();
+      fixedLocation.on(project);
+      StringBuilder fullMessage = new StringBuilder();
+      if (path != null && !path.isEmpty()) {
+        fullMessage.append("[").append(path).append("] ");
+      }
+      fullMessage.append(location.message());
+      fixedLocation.message(fullMessage.toString());
+      return fixedLocation;
+    } else {
+      return location;
+    }
+  }
+}
index f9dae8328e6932cd8d3d4002e3cf69d2509873fa..95b473e05ceb46b0edde47d0f48ccf020151c828 100644 (file)
@@ -24,7 +24,6 @@ import org.slf4j.LoggerFactory;
 import org.sonar.api.batch.fs.FilePredicate;
 import org.sonar.api.batch.fs.FileSystem;
 import org.sonar.api.batch.rule.ActiveRules;
-import org.sonar.api.batch.sensor.internal.DefaultSensorDescriptor;
 import org.sonar.api.config.Configuration;
 
 public abstract class AbstractSensorOptimizer {
index 43773f1eb1d8b27173276a6ed65aa183e9c0eea6..caba9bc9101491ef5cd2694a7dae12c9632896a9 100644 (file)
@@ -20,7 +20,6 @@
 package org.sonar.scanner.sensor;
 
 import org.sonar.api.batch.sensor.SensorContext;
-import org.sonar.api.batch.sensor.internal.DefaultSensorDescriptor;
 import org.sonar.api.scanner.sensor.ProjectSensor;
 
 public abstract class AbstractSensorWrapper<G extends ProjectSensor> {
diff --git a/sonar-scanner-engine/src/main/java/org/sonar/scanner/sensor/DefaultAdHocRule.java b/sonar-scanner-engine/src/main/java/org/sonar/scanner/sensor/DefaultAdHocRule.java
new file mode 100644 (file)
index 0000000..23dbd34
--- /dev/null
@@ -0,0 +1,127 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2019 SonarSource SA
+ * mailto:info AT sonarsource DOT com
+ *
+ * This program 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.
+ *
+ * This program 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.scanner.sensor;
+
+import javax.annotation.CheckForNull;
+import javax.annotation.Nullable;
+import org.sonar.api.batch.rule.Severity;
+import org.sonar.api.batch.sensor.internal.DefaultStorable;
+import org.sonar.api.batch.sensor.internal.SensorStorage;
+import org.sonar.api.batch.sensor.rule.AdHocRule;
+import org.sonar.api.batch.sensor.rule.NewAdHocRule;
+import org.sonar.api.rules.RuleType;
+
+import static org.apache.commons.lang.StringUtils.isNotBlank;
+import static org.sonar.api.utils.Preconditions.checkState;
+
+public class DefaultAdHocRule extends DefaultStorable implements AdHocRule, NewAdHocRule {
+  private Severity severity;
+  private RuleType type;
+  private String name;
+  private String description;
+  private String engineId;
+  private String ruleId;
+
+  public DefaultAdHocRule() {
+    super(null);
+  }
+
+  public DefaultAdHocRule(@Nullable SensorStorage storage) {
+    super(storage);
+  }
+
+  @Override
+  public DefaultAdHocRule severity(Severity severity) {
+    this.severity = severity;
+    return this;
+  }
+
+  @Override
+  public String engineId() {
+    return engineId;
+  }
+
+  @Override
+  public String ruleId() {
+    return ruleId;
+  }
+
+  @Override
+  public String name() {
+    return name;
+  }
+
+  @CheckForNull
+  @Override
+  public String description() {
+    return description;
+  }
+
+  @Override
+  public Severity severity() {
+    return this.severity;
+  }
+
+  @Override
+  public void doSave() {
+    checkState(isNotBlank(engineId), "Engine id is mandatory on ad hoc rule");
+    checkState(isNotBlank(ruleId), "Rule id is mandatory on ad hoc rule");
+    checkState(isNotBlank(name), "Name is mandatory on every ad hoc rule");
+    checkState(severity != null, "Severity is mandatory on every ad hoc rule");
+    checkState(type != null, "Type is mandatory on every ad hoc rule");
+    storage.store(this);
+  }
+
+  @Override
+  public RuleType type() {
+    return type;
+  }
+
+  @Override
+  public DefaultAdHocRule engineId(String engineId) {
+    this.engineId = engineId;
+    return this;
+  }
+
+  @Override
+  public DefaultAdHocRule ruleId(String ruleId) {
+    this.ruleId = ruleId;
+    return this;
+  }
+
+  @Override
+  public DefaultAdHocRule name(String name) {
+    this.name = name;
+    return this;
+  }
+
+  @Override
+  public DefaultAdHocRule description(@Nullable String description) {
+    this.description = description;
+    return this;
+  }
+
+  @Override
+  public DefaultAdHocRule type(RuleType type) {
+    this.type = type;
+    return this;
+  }
+
+}
diff --git a/sonar-scanner-engine/src/main/java/org/sonar/scanner/sensor/DefaultExternalIssue.java b/sonar-scanner-engine/src/main/java/org/sonar/scanner/sensor/DefaultExternalIssue.java
new file mode 100644 (file)
index 0000000..3c09a40
--- /dev/null
@@ -0,0 +1,134 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2019 SonarSource SA
+ * mailto:info AT sonarsource DOT com
+ *
+ * This program 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.
+ *
+ * This program 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.scanner.sensor;
+
+import javax.annotation.Nullable;
+import org.sonar.api.batch.fs.internal.DefaultInputProject;
+import org.sonar.api.batch.rule.Severity;
+import org.sonar.api.batch.sensor.internal.SensorStorage;
+import org.sonar.api.batch.sensor.issue.ExternalIssue;
+import org.sonar.api.batch.sensor.issue.NewExternalIssue;
+import org.sonar.api.rule.RuleKey;
+import org.sonar.api.rules.RuleType;
+
+import static java.lang.String.format;
+import static java.util.Objects.requireNonNull;
+import static org.sonar.api.utils.Preconditions.checkArgument;
+import static org.sonar.api.utils.Preconditions.checkState;
+
+public class DefaultExternalIssue extends AbstractDefaultIssue<DefaultExternalIssue> implements ExternalIssue, NewExternalIssue {
+  private Long effort;
+  private Severity severity;
+  private RuleType type;
+  private String engineId;
+  private String ruleId;
+
+  public DefaultExternalIssue(DefaultInputProject project) {
+    this(project, null);
+  }
+
+  public DefaultExternalIssue(DefaultInputProject project, @Nullable SensorStorage storage) {
+    super(project, storage);
+  }
+
+  @Override
+  public DefaultExternalIssue remediationEffortMinutes(@Nullable Long effort) {
+    checkArgument(effort == null || effort >= 0, format("effort must be greater than or equal 0 (got %s)", effort));
+    this.effort = effort;
+    return this;
+  }
+
+  @Override
+  public DefaultExternalIssue severity(Severity severity) {
+    this.severity = severity;
+    return this;
+  }
+
+  @Override
+  public String engineId() {
+    return engineId;
+  }
+
+  @Override
+  public String ruleId() {
+    return ruleId;
+  }
+
+  @Override
+  public Severity severity() {
+    return this.severity;
+  }
+
+  @Override
+  public Long remediationEffort() {
+    return this.effort;
+  }
+
+  @Override
+  public void doSave() {
+    requireNonNull(this.engineId, "Engine id is mandatory on external issue");
+    requireNonNull(this.ruleId, "Rule id is mandatory on external issue");
+    checkState(primaryLocation != null, "Primary location is mandatory on every external issue");
+    checkState(primaryLocation.inputComponent().isFile(), "External issues must be located in files");
+    checkState(primaryLocation.message() != null, "External issues must have a message");
+    checkState(severity != null, "Severity is mandatory on every external issue");
+    checkState(type != null, "Type is mandatory on every external issue");
+    storage.store(this);
+  }
+
+  @Override
+  public RuleType type() {
+    return type;
+  }
+
+  @Override
+  public NewExternalIssue engineId(String engineId) {
+    this.engineId = engineId;
+    return this;
+  }
+
+  @Override
+  public NewExternalIssue ruleId(String ruleId) {
+    this.ruleId = ruleId;
+    return this;
+  }
+
+  @Override
+  public DefaultExternalIssue forRule(RuleKey ruleKey) {
+    this.engineId = ruleKey.repository();
+    this.ruleId = ruleKey.rule();
+    return this;
+  }
+
+  @Override
+  public RuleKey ruleKey() {
+    if (engineId != null && ruleId != null) {
+      return RuleKey.of(RuleKey.EXTERNAL_RULE_REPO_PREFIX + engineId, ruleId);
+    }
+    return null;
+  }
+
+  @Override
+  public DefaultExternalIssue type(RuleType type) {
+    this.type = type;
+    return this;
+  }
+
+}
diff --git a/sonar-scanner-engine/src/main/java/org/sonar/scanner/sensor/DefaultIssue.java b/sonar-scanner-engine/src/main/java/org/sonar/scanner/sensor/DefaultIssue.java
new file mode 100644 (file)
index 0000000..369d731
--- /dev/null
@@ -0,0 +1,93 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2019 SonarSource SA
+ * mailto:info AT sonarsource DOT com
+ *
+ * This program 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.
+ *
+ * This program 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.scanner.sensor;
+
+import javax.annotation.Nullable;
+import org.sonar.api.batch.fs.internal.DefaultInputProject;
+import org.sonar.api.batch.rule.Severity;
+import org.sonar.api.batch.sensor.internal.SensorStorage;
+import org.sonar.api.batch.sensor.issue.Issue;
+import org.sonar.api.batch.sensor.issue.IssueLocation;
+import org.sonar.api.batch.sensor.issue.NewIssue;
+import org.sonar.api.rule.RuleKey;
+
+import static java.lang.String.format;
+import static java.util.Objects.requireNonNull;
+import static org.sonar.api.utils.Preconditions.checkArgument;
+import static org.sonar.api.utils.Preconditions.checkState;
+
+public class DefaultIssue extends AbstractDefaultIssue<DefaultIssue> implements Issue, NewIssue {
+  private RuleKey ruleKey;
+  private Double gap;
+  private Severity overriddenSeverity;
+
+  public DefaultIssue(DefaultInputProject project) {
+    this(project, null);
+  }
+
+  public DefaultIssue(DefaultInputProject project, @Nullable SensorStorage storage) {
+    super(project, storage);
+  }
+
+  public DefaultIssue forRule(RuleKey ruleKey) {
+    this.ruleKey = ruleKey;
+    return this;
+  }
+
+  public RuleKey ruleKey() {
+    return this.ruleKey;
+  }
+
+  @Override
+  public DefaultIssue gap(@Nullable Double gap) {
+    checkArgument(gap == null || gap >= 0, format("Gap must be greater than or equal 0 (got %s)", gap));
+    this.gap = gap;
+    return this;
+  }
+
+  @Override
+  public DefaultIssue overrideSeverity(@Nullable Severity severity) {
+    this.overriddenSeverity = severity;
+    return this;
+  }
+
+  @Override
+  public Severity overriddenSeverity() {
+    return this.overriddenSeverity;
+  }
+
+  @Override
+  public Double gap() {
+    return this.gap;
+  }
+
+  @Override
+  public IssueLocation primaryLocation() {
+    return primaryLocation;
+  }
+
+  @Override
+  public void doSave() {
+    requireNonNull(this.ruleKey, "ruleKey is mandatory on issue");
+    checkState(primaryLocation != null, "Primary location is mandatory on every issue");
+    storage.store(this);
+  }
+
+}
diff --git a/sonar-scanner-engine/src/main/java/org/sonar/scanner/sensor/DefaultIssueLocation.java b/sonar-scanner-engine/src/main/java/org/sonar/scanner/sensor/DefaultIssueLocation.java
new file mode 100644 (file)
index 0000000..b08d093
--- /dev/null
@@ -0,0 +1,92 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2019 SonarSource SA
+ * mailto:info AT sonarsource DOT com
+ *
+ * This program 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.
+ *
+ * This program 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.scanner.sensor;
+
+import javax.annotation.Nullable;
+import org.sonar.api.batch.fs.InputComponent;
+import org.sonar.api.batch.fs.TextRange;
+import org.sonar.api.batch.fs.internal.DefaultInputFile;
+import org.sonar.api.batch.sensor.issue.IssueLocation;
+import org.sonar.api.batch.sensor.issue.NewIssueLocation;
+
+import static java.util.Objects.requireNonNull;
+import static org.apache.commons.lang.StringUtils.abbreviate;
+import static org.apache.commons.lang.StringUtils.trim;
+import static org.sonar.api.utils.Preconditions.checkArgument;
+import static org.sonar.api.utils.Preconditions.checkState;
+
+public class DefaultIssueLocation implements NewIssueLocation, IssueLocation {
+
+  private InputComponent component;
+  private TextRange textRange;
+  private String message;
+
+  @Override
+  public DefaultIssueLocation on(InputComponent component) {
+    checkArgument(component != null, "Component can't be null");
+    checkState(this.component == null, "on() already called");
+    this.component = component;
+    return this;
+  }
+
+  @Override
+  public DefaultIssueLocation at(TextRange location) {
+    checkState(this.component != null, "at() should be called after on()");
+    checkState(this.component.isFile(), "at() should be called only for an InputFile.");
+    DefaultInputFile file = (DefaultInputFile) this.component;
+    file.validate(location);
+    this.textRange = location;
+    return this;
+  }
+
+  @Override
+  public DefaultIssueLocation message(String message) {
+    requireNonNull(message, "Message can't be null");
+    if (message.contains("\u0000")) {
+      throw new IllegalArgumentException(unsupportedCharacterError(message, component));
+    }
+    this.message = abbreviate(trim(message), MESSAGE_MAX_SIZE);
+    return this;
+  }
+
+  private static String unsupportedCharacterError(String message, @Nullable InputComponent component) {
+    String error = "Character \\u0000 is not supported in issue message '" + message + "'";
+    if (component != null) {
+      error += ", on component: " + component.toString();
+    }
+    return error;
+  }
+
+  @Override
+  public InputComponent inputComponent() {
+    return this.component;
+  }
+
+  @Override
+  public TextRange textRange() {
+    return textRange;
+  }
+
+  @Override
+  public String message() {
+    return this.message;
+  }
+
+}
diff --git a/sonar-scanner-engine/src/main/java/org/sonar/scanner/sensor/DefaultMeasure.java b/sonar-scanner-engine/src/main/java/org/sonar/scanner/sensor/DefaultMeasure.java
new file mode 100644 (file)
index 0000000..87d1aa1
--- /dev/null
@@ -0,0 +1,140 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2019 SonarSource SA
+ * mailto:info AT sonarsource DOT com
+ *
+ * This program 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.
+ *
+ * This program 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.scanner.sensor;
+
+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.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 static java.util.Objects.requireNonNull;
+import static org.sonar.api.utils.Preconditions.checkArgument;
+import static org.sonar.api.utils.Preconditions.checkState;
+
+public class DefaultMeasure<G extends Serializable> extends DefaultStorable implements Measure<G>, NewMeasure<G> {
+
+  private InputComponent component;
+  private Metric<G> metric;
+  private G value;
+  private boolean fromCore = false;
+
+  public DefaultMeasure() {
+    super();
+  }
+
+  public DefaultMeasure(@Nullable SensorStorage storage) {
+    super(storage);
+  }
+
+  @Override
+  public DefaultMeasure<G> on(InputComponent component) {
+    checkArgument(component != null, "Component can't be null");
+    checkState(this.component == null, "on() already called");
+    this.component = component;
+    return this;
+  }
+
+  @Override
+  public DefaultMeasure<G> forMetric(Metric<G> metric) {
+    checkState(this.metric == null, "Metric already defined");
+    requireNonNull(metric, "metric should be non null");
+    this.metric = metric;
+    return this;
+  }
+
+  @Override
+  public DefaultMeasure<G> withValue(G value) {
+    checkState(this.value == null, "Measure value already defined");
+    requireNonNull(value, "Measure value can't be null");
+    this.value = value;
+    return this;
+  }
+
+  /**
+   * For internal use.
+   */
+  public boolean isFromCore() {
+    return fromCore;
+  }
+
+  /**
+   * For internal use. Used by core components to bypass check that prevent a plugin to store core measures.
+   */
+  public DefaultMeasure<G> setFromCore() {
+    this.fromCore = true;
+    return this;
+  }
+
+  @Override
+  public void doSave() {
+    requireNonNull(this.value, "Measure value can't be null");
+    requireNonNull(this.metric, "Measure metric can't be null");
+    checkState(this.metric.valueType().equals(this.value.getClass()), "Measure value should be of type %s", this.metric.valueType());
+    storage.store(this);
+  }
+
+  @Override
+  public Metric<G> metric() {
+    return metric;
+  }
+
+  @Override
+  public InputComponent inputComponent() {
+    return component;
+  }
+
+  @Override
+  public G value() {
+    return value;
+  }
+
+  // For testing purpose
+
+  @Override
+  public boolean equals(Object obj) {
+    if (obj == null) {
+      return false;
+    }
+    if (obj == this) {
+      return true;
+    }
+    if (obj.getClass() != getClass()) {
+      return false;
+    }
+    DefaultMeasure<?> rhs = (DefaultMeasure<?>) obj;
+    return new EqualsBuilder()
+      .append(component, rhs.component)
+      .append(metric, rhs.metric)
+      .append(value, rhs.value)
+      .isEquals();
+  }
+
+  @Override
+  public int hashCode() {
+    return new HashCodeBuilder(27, 45).append(component).append(metric).append(value).toHashCode();
+  }
+
+}
diff --git a/sonar-scanner-engine/src/main/java/org/sonar/scanner/sensor/DefaultSensorDescriptor.java b/sonar-scanner-engine/src/main/java/org/sonar/scanner/sensor/DefaultSensorDescriptor.java
new file mode 100644 (file)
index 0000000..1bb7466
--- /dev/null
@@ -0,0 +1,123 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2019 SonarSource SA
+ * mailto:info AT sonarsource DOT com
+ *
+ * This program 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.
+ *
+ * This program 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.scanner.sensor;
+
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.function.Predicate;
+import javax.annotation.Nullable;
+import org.sonar.api.batch.fs.InputFile;
+import org.sonar.api.batch.sensor.SensorDescriptor;
+import org.sonar.api.config.Configuration;
+
+import static java.util.Arrays.asList;
+
+public class DefaultSensorDescriptor implements SensorDescriptor {
+
+  private String name;
+  private String[] languages = new String[0];
+  private InputFile.Type type = null;
+  private String[] ruleRepositories = new String[0];
+  private boolean global = false;
+  private Predicate<Configuration> configurationPredicate;
+
+  public String name() {
+    return name;
+  }
+
+  public Collection<String> languages() {
+    return Arrays.asList(languages);
+  }
+
+  @Nullable
+  public InputFile.Type type() {
+    return type;
+  }
+
+  public Collection<String> ruleRepositories() {
+    return Arrays.asList(ruleRepositories);
+  }
+
+  public Predicate<Configuration> configurationPredicate() {
+    return configurationPredicate;
+  }
+
+  public boolean isGlobal() {
+    return global;
+  }
+
+  @Override
+  public DefaultSensorDescriptor name(String name) {
+    this.name = name;
+    return this;
+  }
+
+  @Override
+  public DefaultSensorDescriptor onlyOnLanguage(String languageKey) {
+    return onlyOnLanguages(languageKey);
+  }
+
+  @Override
+  public DefaultSensorDescriptor onlyOnLanguages(String... languageKeys) {
+    this.languages = languageKeys;
+    return this;
+  }
+
+  @Override
+  public DefaultSensorDescriptor onlyOnFileType(InputFile.Type type) {
+    this.type = type;
+    return this;
+  }
+
+  @Override
+  public DefaultSensorDescriptor createIssuesForRuleRepository(String... repositoryKey) {
+    return createIssuesForRuleRepositories(repositoryKey);
+  }
+
+  @Override
+  public DefaultSensorDescriptor createIssuesForRuleRepositories(String... repositoryKeys) {
+    this.ruleRepositories = repositoryKeys;
+    return this;
+  }
+
+  @Override
+  public DefaultSensorDescriptor requireProperty(String... propertyKey) {
+    return requireProperties(propertyKey);
+  }
+
+  @Override
+  public DefaultSensorDescriptor requireProperties(String... propertyKeys) {
+    this.configurationPredicate = config -> asList(propertyKeys).stream().allMatch(config::hasKey);
+    return this;
+  }
+
+  @Override
+  public SensorDescriptor global() {
+    this.global = true;
+    return this;
+  }
+
+  @Override
+  public SensorDescriptor onlyWhenConfiguration(Predicate<Configuration> configurationPredicate) {
+    this.configurationPredicate = configurationPredicate;
+    return this;
+  }
+
+}
index 75a7806beab7798385afc1b1d777797e542c922d..415a884380b2c9f6d8b4e8034446f6ffd4b96d26 100644 (file)
@@ -43,11 +43,10 @@ import org.sonar.api.batch.sensor.cpd.internal.DefaultCpdTokens;
 import org.sonar.api.batch.sensor.error.AnalysisError;
 import org.sonar.api.batch.sensor.highlighting.internal.DefaultHighlighting;
 import org.sonar.api.batch.sensor.internal.SensorStorage;
+import org.sonar.api.batch.sensor.issue.ExternalIssue;
 import org.sonar.api.batch.sensor.issue.Issue;
-import org.sonar.api.batch.sensor.issue.internal.DefaultExternalIssue;
 import org.sonar.api.batch.sensor.measure.Measure;
-import org.sonar.api.batch.sensor.measure.internal.DefaultMeasure;
-import org.sonar.api.batch.sensor.rule.internal.DefaultAdHocRule;
+import org.sonar.api.batch.sensor.rule.AdHocRule;
 import org.sonar.api.batch.sensor.symbol.internal.DefaultSymbolTable;
 import org.sonar.api.config.Configuration;
 import org.sonar.api.measures.CoreMetrics;
@@ -231,7 +230,7 @@ public class DefaultSensorStorage implements SensorStorage {
    * Thread safe assuming that each issues for each file are only written once.
    */
   @Override
-  public void store(DefaultExternalIssue externalIssue) {
+  public void store(ExternalIssue externalIssue) {
     if (externalIssue.primaryLocation().inputComponent() instanceof DefaultInputFile) {
       DefaultInputFile defaultInputFile = (DefaultInputFile) externalIssue.primaryLocation().inputComponent();
       defaultInputFile.setPublished(true);
@@ -240,7 +239,7 @@ public class DefaultSensorStorage implements SensorStorage {
   }
 
   @Override
-  public void store(DefaultAdHocRule adHocRule) {
+  public void store(AdHocRule adHocRule) {
     ScannerReportWriter writer = reportPublisher.getWriter();
     final ScannerReport.AdHocRule.Builder builder = ScannerReport.AdHocRule.newBuilder();
     builder.setEngineId(adHocRule.engineId());
index c0ec11759ed4bbc9f9e17861f1a0de77c1f2052f..887f1d02c66cc8de1f1e1998676039140cf89bb3 100644 (file)
@@ -33,10 +33,8 @@ import org.sonar.api.batch.sensor.highlighting.internal.DefaultHighlighting;
 import org.sonar.api.batch.sensor.internal.SensorStorage;
 import org.sonar.api.batch.sensor.issue.ExternalIssue;
 import org.sonar.api.batch.sensor.issue.Issue;
-import org.sonar.api.batch.sensor.issue.internal.DefaultExternalIssue;
 import org.sonar.api.batch.sensor.measure.Measure;
 import org.sonar.api.batch.sensor.rule.AdHocRule;
-import org.sonar.api.batch.sensor.rule.internal.DefaultAdHocRule;
 import org.sonar.api.batch.sensor.symbol.internal.DefaultSymbolTable;
 
 import static org.sonar.api.utils.Preconditions.checkArgument;
@@ -74,7 +72,7 @@ class InMemorySensorStorage implements SensorStorage {
   }
 
   @Override
-  public void store(DefaultAdHocRule adHocRule) {
+  public void store(AdHocRule adHocRule) {
     allAdHocRules.add(adHocRule);
   }
 
@@ -127,7 +125,7 @@ class InMemorySensorStorage implements SensorStorage {
   }
 
   @Override
-  public void store(DefaultExternalIssue issue) {
+  public void store(ExternalIssue issue) {
     allExternalIssues.add(issue);
   }
 
index 0fe743dfbe2b078b3d1ea23383445335f366b9af..21e6d2b8f70a15ae05df724586bb367d6e0af4b2 100644 (file)
@@ -41,12 +41,8 @@ import org.sonar.api.batch.sensor.highlighting.internal.DefaultHighlighting;
 import org.sonar.api.batch.sensor.internal.SensorStorage;
 import org.sonar.api.batch.sensor.issue.NewExternalIssue;
 import org.sonar.api.batch.sensor.issue.NewIssue;
-import org.sonar.api.batch.sensor.issue.internal.DefaultExternalIssue;
-import org.sonar.api.batch.sensor.issue.internal.DefaultIssue;
 import org.sonar.api.batch.sensor.measure.NewMeasure;
-import org.sonar.api.batch.sensor.measure.internal.DefaultMeasure;
 import org.sonar.api.batch.sensor.rule.NewAdHocRule;
-import org.sonar.api.batch.sensor.rule.internal.DefaultAdHocRule;
 import org.sonar.api.batch.sensor.symbol.NewSymbolTable;
 import org.sonar.api.batch.sensor.symbol.internal.DefaultSymbolTable;
 import org.sonar.api.config.Configuration;
index 21e5a8271ca95a87f3a205db0edd156b3f36c0d0..26777fc0a9936c114b6440b3650d36522929cb11 100644 (file)
@@ -65,14 +65,10 @@ import org.sonar.api.batch.sensor.issue.ExternalIssue;
 import org.sonar.api.batch.sensor.issue.Issue;
 import org.sonar.api.batch.sensor.issue.NewExternalIssue;
 import org.sonar.api.batch.sensor.issue.NewIssue;
-import org.sonar.api.batch.sensor.issue.internal.DefaultExternalIssue;
-import org.sonar.api.batch.sensor.issue.internal.DefaultIssue;
 import org.sonar.api.batch.sensor.measure.Measure;
 import org.sonar.api.batch.sensor.measure.NewMeasure;
-import org.sonar.api.batch.sensor.measure.internal.DefaultMeasure;
 import org.sonar.api.batch.sensor.rule.AdHocRule;
 import org.sonar.api.batch.sensor.rule.NewAdHocRule;
-import org.sonar.api.batch.sensor.rule.internal.DefaultAdHocRule;
 import org.sonar.api.batch.sensor.symbol.NewSymbolTable;
 import org.sonar.api.batch.sensor.symbol.internal.DefaultSymbolTable;
 import org.sonar.api.config.Configuration;
index 6bd3a77f43c7d00e651e5e46ab5406b9921d61f4..19ce32d686cb7ce583f35c5de66514cdeb8824a0 100644 (file)
@@ -29,7 +29,7 @@ import org.sonar.api.batch.fs.internal.DefaultInputFile;
 import org.sonar.api.batch.fs.internal.TestInputFileBuilder;
 import org.sonar.api.batch.measure.MetricFinder;
 import org.sonar.api.batch.sensor.internal.SensorStorage;
-import org.sonar.api.batch.sensor.measure.internal.DefaultMeasure;
+import org.sonar.scanner.sensor.DefaultMeasure;
 import org.sonar.api.measures.CoreMetrics;
 
 import static org.assertj.core.api.Assertions.assertThat;
index 9a89d6ad18ba058cc8c4767389d6169cab28377a..50ea80aceb733779f9279731fde504b19dec0299 100644 (file)
@@ -38,9 +38,9 @@ import org.sonar.api.batch.fs.internal.TestInputFileBuilder;
 import org.sonar.scanner.rule.ActiveRulesBuilder;
 import org.sonar.scanner.rule.NewActiveRule;
 import org.sonar.scanner.rule.RulesBuilder;
-import org.sonar.api.batch.sensor.issue.internal.DefaultExternalIssue;
-import org.sonar.api.batch.sensor.issue.internal.DefaultIssue;
-import org.sonar.api.batch.sensor.issue.internal.DefaultIssueLocation;
+import org.sonar.scanner.sensor.DefaultExternalIssue;
+import org.sonar.scanner.sensor.DefaultIssue;
+import org.sonar.scanner.sensor.DefaultIssueLocation;
 import org.sonar.api.rule.RuleKey;
 import org.sonar.api.rule.Severity;
 import org.sonar.api.rules.RuleType;
index 264e666429f6a4bf2d74b807fa5a1192df522c07..bdefb6f3436382cd8682e173f8d8d27ca89ec09b 100644 (file)
@@ -40,10 +40,6 @@ import org.sonar.api.batch.sensor.highlighting.TypeOfText;
 import org.sonar.api.batch.sensor.highlighting.internal.DefaultHighlighting;
 import org.sonar.api.batch.sensor.issue.ExternalIssue;
 import org.sonar.api.batch.sensor.issue.Issue;
-import org.sonar.api.batch.sensor.issue.internal.DefaultExternalIssue;
-import org.sonar.api.batch.sensor.issue.internal.DefaultIssue;
-import org.sonar.api.batch.sensor.issue.internal.DefaultIssueLocation;
-import org.sonar.api.batch.sensor.measure.internal.DefaultMeasure;
 import org.sonar.api.batch.sensor.symbol.internal.DefaultSymbolTable;
 import org.sonar.api.config.internal.MapSettings;
 import org.sonar.api.measures.CoreMetrics;