+++ /dev/null
-/*
- * 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;
- }
-
-}
+++ /dev/null
-/*
- * 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;
- }
-
-}
*/
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;
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;
/**
void store(Issue issue);
- void store(DefaultExternalIssue issue);
+ void store(ExternalIssue issue);
- void store(DefaultAdHocRule adHocRule);
+ void store(AdHocRule adHocRule);
void store(DefaultHighlighting highlighting);
+++ /dev/null
-/*
- * 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;
- }
- }
-}
+++ /dev/null
-/*
- * 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;
- }
-
-}
+++ /dev/null
-/*
- * 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);
- }
-
-}
+++ /dev/null
-/*
- * 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;
- }
-
-}
+++ /dev/null
-/*
- * 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;
+++ /dev/null
-/*
- * 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();
- }
-
-}
+++ /dev/null
-/*
- * 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;
+++ /dev/null
-/*
- * 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;
- }
-
-}
+++ /dev/null
-/*
- * 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;
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;
--- /dev/null
+/*
+ * 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;
+ }
+
+}
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;
--- /dev/null
+/*
+ * 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;
+ }
+ }
+}
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 {
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> {
--- /dev/null
+/*
+ * 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;
+ }
+
+}
--- /dev/null
+/*
+ * 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;
+ }
+
+}
--- /dev/null
+/*
+ * 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);
+ }
+
+}
--- /dev/null
+/*
+ * 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;
+ }
+
+}
--- /dev/null
+/*
+ * 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();
+ }
+
+}
--- /dev/null
+/*
+ * 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;
+ }
+
+}
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;
* 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);
}
@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());
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;
}
@Override
- public void store(DefaultAdHocRule adHocRule) {
+ public void store(AdHocRule adHocRule) {
allAdHocRules.add(adHocRule);
}
}
@Override
- public void store(DefaultExternalIssue issue) {
+ public void store(ExternalIssue issue) {
allExternalIssues.add(issue);
}
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;
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;
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;
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;
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;