aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--sonar-plugin-api/build.gradle3
-rw-r--r--sonar-plugin-api/src/main/java/org/sonar/api/batch/fs/internal/DefaultFileSystem.java12
-rw-r--r--sonar-plugin-api/src/main/java/org/sonar/api/batch/fs/internal/DefaultInputFile.java20
-rw-r--r--sonar-plugin-api/src/main/java/org/sonar/api/batch/rule/internal/DefaultActiveRules.java32
-rw-r--r--sonar-plugin-api/src/main/java/org/sonar/api/batch/rule/internal/DefaultRules.java58
-rw-r--r--sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/code/internal/DefaultSignificantCode.java2
-rw-r--r--sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/coverage/internal/DefaultCoverage.java2
-rw-r--r--sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/cpd/internal/DefaultCpdTokens.java2
-rw-r--r--sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/error/internal/DefaultAnalysisError.java9
-rw-r--r--sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/highlighting/internal/DefaultHighlighting.java4
-rw-r--r--sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/internal/DefaultStorable.java4
-rw-r--r--sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/internal/InMemorySensorStorage.java20
-rw-r--r--sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/internal/SensorContextTester.java10
-rw-r--r--sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/issue/internal/AbstractDefaultIssue.java11
-rw-r--r--sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/issue/internal/DefaultExternalIssue.java6
-rw-r--r--sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/issue/internal/DefaultIssue.java6
-rw-r--r--sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/issue/internal/DefaultIssueLocation.java13
-rw-r--r--sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/measure/internal/DefaultMeasure.java13
-rw-r--r--sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/rule/internal/DefaultAdHocRule.java2
-rw-r--r--sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/symbol/internal/DefaultSymbolTable.java7
-rw-r--r--sonar-plugin-api/src/main/java/org/sonar/api/ce/measure/RangeDistributionBuilder.java17
-rw-r--r--sonar-plugin-api/src/main/java/org/sonar/api/ce/measure/test/TestComponent.java2
-rw-r--r--sonar-plugin-api/src/main/java/org/sonar/api/ce/measure/test/TestIssue.java2
-rw-r--r--sonar-plugin-api/src/main/java/org/sonar/api/ce/measure/test/TestMeasure.java2
-rw-r--r--sonar-plugin-api/src/main/java/org/sonar/api/ce/measure/test/TestMeasureComputerContext.java18
-rw-r--r--sonar-plugin-api/src/main/java/org/sonar/api/ce/measure/test/TestMeasureComputerDefinition.java2
-rw-r--r--sonar-plugin-api/src/main/java/org/sonar/api/ce/posttask/PostProjectAnalysisTaskTester.java7
-rw-r--r--sonar-plugin-api/src/main/java/org/sonar/api/config/PropertyDefinition.java6
-rw-r--r--sonar-plugin-api/src/main/java/org/sonar/api/config/PropertyFieldDefinition.java6
-rw-r--r--sonar-plugin-api/src/main/java/org/sonar/api/config/Settings.java24
-rw-r--r--sonar-plugin-api/src/main/java/org/sonar/api/config/internal/MultivalueProperty.java2
-rw-r--r--sonar-plugin-api/src/main/java/org/sonar/api/internal/MetadataLoader.java12
-rw-r--r--sonar-plugin-api/src/main/java/org/sonar/api/internal/SonarRuntimeImpl.java2
-rw-r--r--sonar-plugin-api/src/main/java/org/sonar/api/measures/Metric.java14
-rw-r--r--sonar-plugin-api/src/main/java/org/sonar/api/resources/AbstractLanguage.java10
-rw-r--r--sonar-plugin-api/src/main/java/org/sonar/api/resources/ResourceType.java5
-rw-r--r--sonar-plugin-api/src/main/java/org/sonar/api/resources/ResourceTypeTree.java30
-rw-r--r--sonar-plugin-api/src/main/java/org/sonar/api/resources/ResourceTypes.java2
-rw-r--r--sonar-plugin-api/src/main/java/org/sonar/api/rule/RuleKey.java9
-rw-r--r--sonar-plugin-api/src/main/java/org/sonar/api/rules/AnnotationRuleParser.java29
-rw-r--r--sonar-plugin-api/src/main/java/org/sonar/api/rules/Rule.java11
-rw-r--r--sonar-plugin-api/src/main/java/org/sonar/api/rules/XMLRuleParser.java3
-rw-r--r--sonar-plugin-api/src/main/java/org/sonar/api/server/authentication/Display.java3
-rw-r--r--sonar-plugin-api/src/main/java/org/sonar/api/server/authentication/UserIdentity.java2
-rw-r--r--sonar-plugin-api/src/main/java/org/sonar/api/server/debt/internal/DefaultDebtRemediationFunction.java16
-rw-r--r--sonar-plugin-api/src/main/java/org/sonar/api/server/profile/BuiltInQualityProfilesDefinition.java8
-rw-r--r--sonar-plugin-api/src/main/java/org/sonar/api/server/rule/RulesDefinition.java54
-rw-r--r--sonar-plugin-api/src/main/java/org/sonar/api/server/ws/Request.java26
-rw-r--r--sonar-plugin-api/src/main/java/org/sonar/api/server/ws/WebService.java39
-rw-r--r--sonar-plugin-api/src/main/java/org/sonar/api/server/ws/internal/SimpleGetRequest.java6
-rw-r--r--sonar-plugin-api/src/main/java/org/sonar/api/server/ws/internal/ValidatingRequest.java33
-rw-r--r--sonar-plugin-api/src/main/java/org/sonar/api/task/TaskDefinition.java11
-rw-r--r--sonar-plugin-api/src/main/java/org/sonar/api/user/UserGroupValidation.java2
-rw-r--r--sonar-plugin-api/src/main/java/org/sonar/api/utils/DateUtils.java2
-rw-r--r--sonar-plugin-api/src/main/java/org/sonar/api/utils/Paging.java2
-rw-r--r--sonar-plugin-api/src/main/java/org/sonar/api/utils/Preconditions.java (renamed from sonar-plugin-api/src/main/java/org/sonar/api/measures/MultisetDistributionFormat.java)48
-rw-r--r--sonar-plugin-api/src/main/java/org/sonar/api/utils/UriReader.java17
-rw-r--r--sonar-plugin-api/src/main/java/org/sonar/api/utils/Version.java37
-rw-r--r--sonar-plugin-api/src/main/java/org/sonar/api/utils/command/Command.java10
-rw-r--r--sonar-plugin-api/src/main/java/org/sonar/api/utils/internal/AlwaysIncreasingSystem2.java2
-rw-r--r--sonar-plugin-api/src/main/java/org/sonar/api/utils/log/LogInterceptors.java4
-rw-r--r--sonar-plugin-api/src/main/java/org/sonar/api/web/Dashboard.java11
-rw-r--r--sonar-plugin-api/src/main/java/org/sonar/api/web/ServletFilter.java2
-rw-r--r--sonar-plugin-api/src/test/java/org/sonar/api/batch/sensor/internal/SensorContextTesterTest.java3
-rw-r--r--sonar-plugin-api/src/test/java/org/sonar/api/server/rule/RuleTagsToTypeConverterTest.java2
-rw-r--r--sonar-plugin-api/src/test/java/org/sonar/api/server/rule/RulesDefinitionXmlLoaderTest.java2
-rw-r--r--sonar-plugin-api/src/test/java/org/sonar/api/utils/ExceptionCauseMatcher.java91
-rw-r--r--sonar-plugin-api/src/test/java/org/sonar/api/utils/KeyValueFormatTest.java3
-rw-r--r--sonar-plugin-api/src/test/java/org/sonar/api/utils/PathUtilsTest.java6
-rw-r--r--sonar-plugin-api/src/test/java/org/sonar/api/utils/TestUtils.java55
-rw-r--r--sonar-plugin-api/src/test/java/org/sonar/api/utils/command/CommandExecutorTest.java31
-rw-r--r--sonar-plugin-api/src/test/java/org/sonar/api/utils/log/ConsoleFormatterTest.java2
-rw-r--r--sonar-plugin-api/src/test/java/org/sonar/api/utils/log/LogInterceptorsTest.java2
73 files changed, 542 insertions, 441 deletions
diff --git a/sonar-plugin-api/build.gradle b/sonar-plugin-api/build.gradle
index 08ed5c8e6c8..3c2b3d3a0da 100644
--- a/sonar-plugin-api/build.gradle
+++ b/sonar-plugin-api/build.gradle
@@ -13,7 +13,6 @@ dependencies {
compile 'commons-io:commons-io'
compile 'commons-lang:commons-lang'
compile 'com.google.code.gson:gson'
- compile 'com.google.guava:guava'
compile 'org.apache.commons:commons-csv'
// shaded, but not relocated
@@ -30,10 +29,10 @@ dependencies {
compileOnly 'junit:junit'
compileOnly 'org.slf4j:slf4j-api'
+ testCompile 'com.google.guava:guava'
testCompile 'com.tngtech.java:junit-dataprovider'
testCompile 'org.assertj:assertj-core'
testCompile 'org.mockito:mockito-core'
- testCompile project(':sonar-testing-harness')
}
sourceSets {
diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/batch/fs/internal/DefaultFileSystem.java b/sonar-plugin-api/src/main/java/org/sonar/api/batch/fs/internal/DefaultFileSystem.java
index a69479c6b11..3b9b7ac22e9 100644
--- a/sonar-plugin-api/src/main/java/org/sonar/api/batch/fs/internal/DefaultFileSystem.java
+++ b/sonar-plugin-api/src/main/java/org/sonar/api/batch/fs/internal/DefaultFileSystem.java
@@ -19,16 +19,16 @@
*/
package org.sonar.api.batch.fs.internal;
-import com.google.common.collect.LinkedHashMultimap;
-import com.google.common.collect.SetMultimap;
import java.io.File;
import java.io.IOException;
import java.nio.charset.Charset;
import java.nio.file.Path;
import java.util.ArrayList;
import java.util.HashMap;
+import java.util.HashSet;
import java.util.Iterator;
import java.util.Map;
+import java.util.Set;
import java.util.SortedSet;
import java.util.TreeSet;
import java.util.stream.StreamSupport;
@@ -188,8 +188,8 @@ public class DefaultFileSystem implements FileSystem {
*/
private static class MapCache extends Cache {
private final Map<String, InputFile> fileMap = new HashMap<>();
- private final SetMultimap<String, InputFile> filesByNameCache = LinkedHashMultimap.create();
- private final SetMultimap<String, InputFile> filesByExtensionCache = LinkedHashMultimap.create();
+ private final Map<String, Set<InputFile>> filesByNameCache = new HashMap<>();
+ private final Map<String, Set<InputFile>> filesByExtensionCache = new HashMap<>();
private SortedSet<String> languages = new TreeSet<>();
@Override
@@ -218,8 +218,8 @@ public class DefaultFileSystem implements FileSystem {
languages.add(inputFile.language());
}
fileMap.put(inputFile.relativePath(), inputFile);
- filesByNameCache.put(inputFile.filename(), inputFile);
- filesByExtensionCache.put(FileExtensionPredicate.getExtension(inputFile), inputFile);
+ filesByNameCache.computeIfAbsent(inputFile.filename(), x -> new HashSet<>()).add(inputFile);
+ filesByExtensionCache.computeIfAbsent(FileExtensionPredicate.getExtension(inputFile), x -> new HashSet<>()).add(inputFile);
}
@Override
diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/batch/fs/internal/DefaultInputFile.java b/sonar-plugin-api/src/main/java/org/sonar/api/batch/fs/internal/DefaultInputFile.java
index cf72686859d..5dbcf99c541 100644
--- a/sonar-plugin-api/src/main/java/org/sonar/api/batch/fs/internal/DefaultInputFile.java
+++ b/sonar-plugin-api/src/main/java/org/sonar/api/batch/fs/internal/DefaultInputFile.java
@@ -19,7 +19,6 @@
*/
package org.sonar.api.batch.fs.internal;
-import com.google.common.base.Preconditions;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
@@ -45,7 +44,8 @@ import org.sonar.api.batch.fs.InputFile;
import org.sonar.api.batch.fs.TextPointer;
import org.sonar.api.batch.fs.TextRange;
-import static com.google.common.base.Preconditions.checkState;
+import static org.sonar.api.utils.Preconditions.checkArgument;
+import static org.sonar.api.utils.Preconditions.checkState;
/**
* @since 4.2
@@ -96,7 +96,7 @@ public class DefaultInputFile extends DefaultInputComponent implements InputFile
public InputStream inputStream() throws IOException {
return contents != null ? new ByteArrayInputStream(contents.getBytes(charset()))
: new BOMInputStream(Files.newInputStream(path()),
- ByteOrderMark.UTF_8, ByteOrderMark.UTF_16LE, ByteOrderMark.UTF_16BE, ByteOrderMark.UTF_32LE, ByteOrderMark.UTF_32BE);
+ ByteOrderMark.UTF_8, ByteOrderMark.UTF_16LE, ByteOrderMark.UTF_16BE, ByteOrderMark.UTF_32LE, ByteOrderMark.UTF_32BE);
}
@Override
@@ -313,8 +313,8 @@ public class DefaultInputFile extends DefaultInputComponent implements InputFile
public TextPointer newPointer(int globalOffset) {
checkMetadata();
- Preconditions.checkArgument(globalOffset >= 0, "%s is not a valid offset for a file", globalOffset);
- Preconditions.checkArgument(globalOffset <= lastValidOffset(), "%s is not a valid offset for file %s. Max offset is %s", globalOffset, this, lastValidOffset());
+ checkArgument(globalOffset >= 0, "%s is not a valid offset for a file", globalOffset);
+ checkArgument(globalOffset <= lastValidOffset(), "%s is not a valid offset for file %s. Max offset is %s", globalOffset, this, lastValidOffset());
int line = findLine(globalOffset);
int startLineOffset = originalLineStartOffsets()[line - 1];
// In case the global offset is between \r and \n, move the pointer to a valid location
@@ -332,11 +332,11 @@ public class DefaultInputFile extends DefaultInputComponent implements InputFile
}
private void checkValid(TextPointer pointer, String owner) {
- Preconditions.checkArgument(pointer.line() >= 1, "%s is not a valid line for a file", pointer.line());
- Preconditions.checkArgument(pointer.line() <= this.metadata.lines(), "%s is not a valid line for %s. File %s has %s line(s)", pointer.line(), owner, this, metadata.lines());
- Preconditions.checkArgument(pointer.lineOffset() >= 0, "%s is not a valid line offset for a file", pointer.lineOffset());
+ checkArgument(pointer.line() >= 1, "%s is not a valid line for a file", pointer.line());
+ checkArgument(pointer.line() <= this.metadata.lines(), "%s is not a valid line for %s. File %s has %s line(s)", pointer.line(), owner, this, metadata.lines());
+ checkArgument(pointer.lineOffset() >= 0, "%s is not a valid line offset for a file", pointer.lineOffset());
int lineLength = lineLength(pointer.line());
- Preconditions.checkArgument(pointer.lineOffset() <= lineLength,
+ checkArgument(pointer.lineOffset() <= lineLength,
"%s is not a valid line offset for %s. File %s has %s character(s) at line %s", pointer.lineOffset(), owner, this, lineLength, pointer.line());
}
@@ -345,7 +345,7 @@ public class DefaultInputFile extends DefaultInputComponent implements InputFile
}
private static TextRange newRangeValidPointers(TextPointer start, TextPointer end, boolean acceptEmptyRange) {
- Preconditions.checkArgument(acceptEmptyRange ? (start.compareTo(end) <= 0) : (start.compareTo(end) < 0),
+ checkArgument(acceptEmptyRange ? (start.compareTo(end) <= 0) : (start.compareTo(end) < 0),
"Start pointer %s should be before end pointer %s", start, end);
return new DefaultTextRange(start, end);
}
diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/batch/rule/internal/DefaultActiveRules.java b/sonar-plugin-api/src/main/java/org/sonar/api/batch/rule/internal/DefaultActiveRules.java
index 732955e332e..845137acf60 100644
--- a/sonar-plugin-api/src/main/java/org/sonar/api/batch/rule/internal/DefaultActiveRules.java
+++ b/sonar-plugin-api/src/main/java/org/sonar/api/batch/rule/internal/DefaultActiveRules.java
@@ -19,34 +19,32 @@
*/
package org.sonar.api.batch.rule.internal;
-import com.google.common.collect.ImmutableListMultimap;
-import org.sonar.api.batch.rule.ActiveRule;
-import org.sonar.api.batch.rule.ActiveRules;
-import org.sonar.api.rule.RuleKey;
-
-import javax.annotation.concurrent.Immutable;
-
+import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
+import java.util.List;
import java.util.Map;
+import java.util.stream.Collectors;
+import javax.annotation.concurrent.Immutable;
+import org.sonar.api.batch.rule.ActiveRule;
+import org.sonar.api.batch.rule.ActiveRules;
+import org.sonar.api.rule.RuleKey;
@Immutable
public class DefaultActiveRules implements ActiveRules {
- private final ImmutableListMultimap<String, ActiveRule> activeRulesByRepository;
+ private final Map<String, List<ActiveRule>> activeRulesByRepository = new HashMap<>();
private final Map<String, Map<String, ActiveRule>> activeRulesByRepositoryAndKey = new HashMap<>();
private final Map<String, Map<String, ActiveRule>> activeRulesByRepositoryAndInternalKey = new HashMap<>();
- private final ImmutableListMultimap<String, ActiveRule> activeRulesByLanguage;
+ private final Map<String, List<ActiveRule>> activeRulesByLanguage = new HashMap<>();
public DefaultActiveRules(Collection<NewActiveRule> newActiveRules) {
- ImmutableListMultimap.Builder<String, ActiveRule> repoBuilder = ImmutableListMultimap.builder();
- ImmutableListMultimap.Builder<String, ActiveRule> langBuilder = ImmutableListMultimap.builder();
for (NewActiveRule newAR : newActiveRules) {
DefaultActiveRule ar = new DefaultActiveRule(newAR);
String repo = ar.ruleKey().repository();
- repoBuilder.put(repo, ar);
+ activeRulesByRepository.computeIfAbsent(repo, x -> new ArrayList<>()).add(ar);
if (ar.language() != null) {
- langBuilder.put(ar.language(), ar);
+ activeRulesByLanguage.computeIfAbsent(ar.language(), x -> new ArrayList<>()).add(ar);
}
activeRulesByRepositoryAndKey.computeIfAbsent(repo, r -> new HashMap<>()).put(ar.ruleKey().rule(), ar);
@@ -55,8 +53,6 @@ public class DefaultActiveRules implements ActiveRules {
activeRulesByRepositoryAndInternalKey.computeIfAbsent(repo, r -> new HashMap<>()).put(internalKey, ar);
}
}
- activeRulesByRepository = repoBuilder.build();
- activeRulesByLanguage = langBuilder.build();
}
@Override
@@ -67,17 +63,17 @@ public class DefaultActiveRules implements ActiveRules {
@Override
public Collection<ActiveRule> findAll() {
- return activeRulesByRepository.values();
+ return activeRulesByRepository.entrySet().stream().flatMap(x -> x.getValue().stream()).collect(Collectors.toList());
}
@Override
public Collection<ActiveRule> findByRepository(String repository) {
- return activeRulesByRepository.get(repository);
+ return activeRulesByRepository.getOrDefault(repository, Collections.emptyList());
}
@Override
public Collection<ActiveRule> findByLanguage(String language) {
- return activeRulesByLanguage.get(language);
+ return activeRulesByLanguage.getOrDefault(language, Collections.emptyList());
}
@Override
diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/batch/rule/internal/DefaultRules.java b/sonar-plugin-api/src/main/java/org/sonar/api/batch/rule/internal/DefaultRules.java
index 048973a6891..def001211e7 100644
--- a/sonar-plugin-api/src/main/java/org/sonar/api/batch/rule/internal/DefaultRules.java
+++ b/sonar-plugin-api/src/main/java/org/sonar/api/batch/rule/internal/DefaultRules.java
@@ -19,60 +19,50 @@
*/
package org.sonar.api.batch.rule.internal;
-import com.google.common.collect.ImmutableTable;
-
-import com.google.common.collect.HashBasedTable;
-import org.sonar.api.batch.rule.Rule;
-import com.google.common.collect.Table;
-import com.google.common.collect.ImmutableListMultimap;
-import org.sonar.api.batch.rule.Rules;
-import org.sonar.api.rule.RuleKey;
-
-import javax.annotation.concurrent.Immutable;
-
+import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
-import java.util.LinkedList;
import java.util.List;
import java.util.Map;
+import java.util.stream.Collectors;
+import javax.annotation.concurrent.Immutable;
+import org.sonar.api.batch.rule.Rule;
+import org.sonar.api.batch.rule.Rules;
+import org.sonar.api.rule.RuleKey;
@Immutable
class DefaultRules implements Rules {
- private final ImmutableListMultimap<String, Rule> rulesByRepository;
- private final ImmutableTable<String, String, List<Rule>> rulesByRepositoryAndInternalKey;
+ private final Map<String, List<Rule>> rulesByRepository;
+ private final Map<String, Map<String, List<Rule>>> rulesByRepositoryAndInternalKey;
private final Map<RuleKey, Rule> rulesByRuleKey;
DefaultRules(Collection<NewRule> newRules) {
+ Map<String, List<Rule>> rulesByRepositoryBuilder = new HashMap<>();
+ Map<String, Map<String, List<Rule>>> rulesByRepositoryAndInternalKeyBuilder = new HashMap<>();
Map<RuleKey, Rule> rulesByRuleKeyBuilder = new HashMap<>();
- ImmutableListMultimap.Builder<String, Rule> builder = ImmutableListMultimap.builder();
- Table<String, String, List<Rule>> tableBuilder = HashBasedTable.create();
for (NewRule newRule : newRules) {
DefaultRule r = new DefaultRule(newRule);
rulesByRuleKeyBuilder.put(r.key(), r);
- builder.put(r.key().repository(), r);
- addToTable(tableBuilder, r);
+ rulesByRepositoryBuilder.computeIfAbsent(r.key().repository(), x -> new ArrayList<>()).add(r);
+ addToTable(rulesByRepositoryAndInternalKeyBuilder, r);
}
rulesByRuleKey = Collections.unmodifiableMap(rulesByRuleKeyBuilder);
- rulesByRepository = builder.build();
- rulesByRepositoryAndInternalKey = ImmutableTable.copyOf(tableBuilder);
+ rulesByRepository = Collections.unmodifiableMap(rulesByRepositoryBuilder);
+ rulesByRepositoryAndInternalKey = Collections.unmodifiableMap(rulesByRepositoryAndInternalKeyBuilder);
}
- private static void addToTable(Table<String, String, List<Rule>> table, DefaultRule r) {
+ private static void addToTable(Map<String, Map<String, List<Rule>>> rulesByRepositoryAndInternalKeyBuilder, DefaultRule r) {
if (r.internalKey() == null) {
return;
}
- List<Rule> ruleList = table.get(r.key().repository(), r.internalKey());
-
- if (ruleList == null) {
- ruleList = new LinkedList<>();
- }
-
- ruleList.add(r);
- table.put(r.key().repository(), r.internalKey(), ruleList);
+ rulesByRepositoryAndInternalKeyBuilder
+ .computeIfAbsent(r.key().repository(), x -> new HashMap<>())
+ .computeIfAbsent(r.internalKey(), x -> new ArrayList<>())
+ .add(r);
}
@Override
@@ -82,18 +72,18 @@ class DefaultRules implements Rules {
@Override
public Collection<Rule> findAll() {
- return rulesByRepository.values();
+ return rulesByRepository.values().stream().flatMap(List::stream).collect(Collectors.toList());
}
@Override
public Collection<Rule> findByRepository(String repository) {
- return rulesByRepository.get(repository);
+ return rulesByRepository.getOrDefault(repository, Collections.emptyList());
}
@Override
public Collection<Rule> findByInternalKey(String repository, String internalKey) {
- List<Rule> rules = rulesByRepositoryAndInternalKey.get(repository, internalKey);
-
- return rules != null ? rules : Collections.<Rule>emptyList();
+ return rulesByRepositoryAndInternalKey
+ .getOrDefault(repository, Collections.emptyMap())
+ .getOrDefault(internalKey, Collections.emptyList());
}
}
diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/code/internal/DefaultSignificantCode.java b/sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/code/internal/DefaultSignificantCode.java
index 830ce69db40..40ea16bd42b 100644
--- a/sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/code/internal/DefaultSignificantCode.java
+++ b/sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/code/internal/DefaultSignificantCode.java
@@ -19,7 +19,6 @@
*/
package org.sonar.api.batch.sensor.code.internal;
-import com.google.common.base.Preconditions;
import java.util.SortedMap;
import java.util.TreeMap;
import javax.annotation.Nullable;
@@ -28,6 +27,7 @@ import org.sonar.api.batch.fs.TextRange;
import org.sonar.api.batch.sensor.code.NewSignificantCode;
import org.sonar.api.batch.sensor.internal.DefaultStorable;
import org.sonar.api.batch.sensor.internal.SensorStorage;
+import org.sonar.api.utils.Preconditions;
public class DefaultSignificantCode extends DefaultStorable implements NewSignificantCode {
private SortedMap<Integer, TextRange> significantCodePerLine = new TreeMap<>();
diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/coverage/internal/DefaultCoverage.java b/sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/coverage/internal/DefaultCoverage.java
index d7546cae28d..94fc1887361 100644
--- a/sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/coverage/internal/DefaultCoverage.java
+++ b/sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/coverage/internal/DefaultCoverage.java
@@ -30,8 +30,8 @@ import org.sonar.api.batch.sensor.coverage.NewCoverage;
import org.sonar.api.batch.sensor.internal.DefaultStorable;
import org.sonar.api.batch.sensor.internal.SensorStorage;
-import static com.google.common.base.Preconditions.checkState;
import static java.util.Objects.requireNonNull;
+import static org.sonar.api.utils.Preconditions.checkState;
public class DefaultCoverage extends DefaultStorable implements NewCoverage {
diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/cpd/internal/DefaultCpdTokens.java b/sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/cpd/internal/DefaultCpdTokens.java
index f6907ba68ba..a2c592c37b5 100644
--- a/sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/cpd/internal/DefaultCpdTokens.java
+++ b/sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/cpd/internal/DefaultCpdTokens.java
@@ -30,9 +30,9 @@ import org.sonar.api.batch.sensor.internal.SensorStorage;
import org.sonar.api.utils.log.Logger;
import org.sonar.api.utils.log.Loggers;
-import static com.google.common.base.Preconditions.checkState;
import static java.util.Collections.unmodifiableList;
import static java.util.Objects.requireNonNull;
+import static org.sonar.api.utils.Preconditions.checkState;
public class DefaultCpdTokens extends DefaultStorable implements NewCpdTokens {
private static final Logger LOG = Loggers.get(DefaultCpdTokens.class);
diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/error/internal/DefaultAnalysisError.java b/sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/error/internal/DefaultAnalysisError.java
index a95838d903b..3a9073a5095 100644
--- a/sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/error/internal/DefaultAnalysisError.java
+++ b/sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/error/internal/DefaultAnalysisError.java
@@ -19,7 +19,6 @@
*/
package org.sonar.api.batch.sensor.error.internal;
-import com.google.common.base.Preconditions;
import org.sonar.api.batch.fs.InputFile;
import org.sonar.api.batch.fs.TextPointer;
import org.sonar.api.batch.sensor.error.AnalysisError;
@@ -28,6 +27,8 @@ import org.sonar.api.batch.sensor.internal.DefaultStorable;
import org.sonar.api.batch.sensor.internal.SensorStorage;
import static java.util.Objects.requireNonNull;
+import static org.sonar.api.utils.Preconditions.checkArgument;
+import static org.sonar.api.utils.Preconditions.checkState;
public class DefaultAnalysisError extends DefaultStorable implements NewAnalysisError, AnalysisError {
private InputFile inputFile;
@@ -59,8 +60,8 @@ public class DefaultAnalysisError extends DefaultStorable implements NewAnalysis
@Override
public NewAnalysisError onFile(InputFile inputFile) {
- Preconditions.checkArgument(inputFile != null, "Cannot use a inputFile that is null");
- Preconditions.checkState(this.inputFile == null, "onFile() already called");
+ checkArgument(inputFile != null, "Cannot use a inputFile that is null");
+ checkState(this.inputFile == null, "onFile() already called");
this.inputFile = inputFile;
return this;
}
@@ -73,7 +74,7 @@ public class DefaultAnalysisError extends DefaultStorable implements NewAnalysis
@Override
public NewAnalysisError at(TextPointer location) {
- Preconditions.checkState(this.location == null, "at() already called");
+ checkState(this.location == null, "at() already called");
this.location = location;
return this;
}
diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/highlighting/internal/DefaultHighlighting.java b/sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/highlighting/internal/DefaultHighlighting.java
index 20ee23ad283..89dea63e1cf 100644
--- a/sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/highlighting/internal/DefaultHighlighting.java
+++ b/sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/highlighting/internal/DefaultHighlighting.java
@@ -19,7 +19,6 @@
*/
package org.sonar.api.batch.sensor.highlighting.internal;
-import com.google.common.base.Preconditions;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Iterator;
@@ -33,6 +32,7 @@ import org.sonar.api.batch.sensor.internal.DefaultStorable;
import org.sonar.api.batch.sensor.internal.SensorStorage;
import static java.util.Objects.requireNonNull;
+import static org.sonar.api.utils.Preconditions.checkState;
public class DefaultHighlighting extends DefaultStorable implements NewHighlighting {
@@ -122,6 +122,6 @@ public class DefaultHighlighting extends DefaultStorable implements NewHighlight
}
private void checkInputFileNotNull() {
- Preconditions.checkState(inputFile != null, "Call onFile() first");
+ checkState(inputFile != null, "Call onFile() first");
}
}
diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/internal/DefaultStorable.java b/sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/internal/DefaultStorable.java
index 2b0684acfbb..822ffbc2a40 100644
--- a/sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/internal/DefaultStorable.java
+++ b/sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/internal/DefaultStorable.java
@@ -19,12 +19,12 @@
*/
package org.sonar.api.batch.sensor.internal;
-import com.google.common.base.Preconditions;
import javax.annotation.Nullable;
import org.apache.commons.lang.builder.ToStringBuilder;
import org.apache.commons.lang.builder.ToStringStyle;
import static java.util.Objects.requireNonNull;
+import static org.sonar.api.utils.Preconditions.checkState;
public abstract class DefaultStorable {
@@ -41,7 +41,7 @@ public abstract class DefaultStorable {
public final void save() {
requireNonNull(this.storage, "No persister on this object");
- Preconditions.checkState(!saved, "This object was already saved");
+ checkState(!saved, "This object was already saved");
doSave();
this.saved = true;
}
diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/internal/InMemorySensorStorage.java b/sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/internal/InMemorySensorStorage.java
index e14f8ab26c2..74b238c4b63 100644
--- a/sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/internal/InMemorySensorStorage.java
+++ b/sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/internal/InMemorySensorStorage.java
@@ -19,13 +19,11 @@
*/
package org.sonar.api.batch.sensor.internal;
-import com.google.common.collect.ArrayListMultimap;
-import com.google.common.collect.HashBasedTable;
-import com.google.common.collect.Multimap;
-import com.google.common.collect.Table;
import java.util.ArrayList;
import java.util.Collection;
+import java.util.Collections;
import java.util.HashMap;
+import java.util.List;
import java.util.Map;
import org.sonar.api.batch.sensor.code.internal.DefaultSignificantCode;
import org.sonar.api.batch.sensor.coverage.internal.DefaultCoverage;
@@ -40,11 +38,11 @@ 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 com.google.common.base.Preconditions.checkArgument;
+import static org.sonar.api.utils.Preconditions.checkArgument;
class InMemorySensorStorage implements SensorStorage {
- Table<String, String, Measure> measuresByComponentAndMetric = HashBasedTable.create();
+ Map<String, Map<String, Measure>> measuresByComponentAndMetric = new HashMap<>();
Collection<Issue> allIssues = new ArrayList<>();
Collection<ExternalIssue> allExternalIssues = new ArrayList<>();
@@ -53,7 +51,7 @@ class InMemorySensorStorage implements SensorStorage {
Map<String, DefaultHighlighting> highlightingByComponent = new HashMap<>();
Map<String, DefaultCpdTokens> cpdTokensByComponent = new HashMap<>();
- Multimap<String, DefaultCoverage> coverageByComponent = ArrayListMultimap.create();
+ Map<String, List<DefaultCoverage>> coverageByComponent = new HashMap<>();
Map<String, DefaultSymbolTable> symbolsPerComponent = new HashMap<>();
Map<String, String> contextProperties = new HashMap<>();
Map<String, DefaultSignificantCode> significantCodePerComponent = new HashMap<>();
@@ -63,10 +61,10 @@ class InMemorySensorStorage implements SensorStorage {
// Emulate duplicate measure check
String componentKey = measure.inputComponent().key();
String metricKey = measure.metric().key();
- if (measuresByComponentAndMetric.contains(componentKey, metricKey)) {
+ if (measuresByComponentAndMetric.getOrDefault(componentKey, Collections.emptyMap()).containsKey(metricKey)) {
throw new IllegalStateException("Can not add the same measure twice");
}
- measuresByComponentAndMetric.row(componentKey).put(metricKey, measure);
+ measuresByComponentAndMetric.computeIfAbsent(componentKey, x -> new HashMap<>()).put(metricKey, measure);
}
@Override
@@ -92,7 +90,7 @@ class InMemorySensorStorage implements SensorStorage {
@Override
public void store(DefaultCoverage defaultCoverage) {
String fileKey = defaultCoverage.inputFile().key();
- coverageByComponent.put(fileKey, defaultCoverage);
+ coverageByComponent.computeIfAbsent(fileKey, x -> new ArrayList<>()).add(defaultCoverage);
}
@Override
@@ -131,7 +129,7 @@ class InMemorySensorStorage implements SensorStorage {
public void store(DefaultExternalIssue issue) {
allExternalIssues.add(issue);
}
-
+
@Override
public void store(DefaultSignificantCode significantCode) {
String fileKey = significantCode.inputFile().key();
diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/internal/SensorContextTester.java b/sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/internal/SensorContextTester.java
index edf595685d4..70f5d509131 100644
--- a/sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/internal/SensorContextTester.java
+++ b/sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/internal/SensorContextTester.java
@@ -215,7 +215,7 @@ public class SensorContextTester implements SensorContext {
}
public Collection<Measure> measures(String componentKey) {
- return sensorStorage.measuresByComponentAndMetric.row(componentKey).values();
+ return sensorStorage.measuresByComponentAndMetric.getOrDefault(componentKey, Collections.emptyMap()).values();
}
public <G extends Serializable> Measure<G> measure(String componentKey, Metric<G> metric) {
@@ -223,7 +223,7 @@ public class SensorContextTester implements SensorContext {
}
public <G extends Serializable> Measure<G> measure(String componentKey, String metricKey) {
- return sensorStorage.measuresByComponentAndMetric.row(componentKey).get(metricKey);
+ return sensorStorage.measuresByComponentAndMetric.getOrDefault(componentKey, Collections.emptyMap()).get(metricKey);
}
@Override
@@ -259,7 +259,7 @@ public class SensorContextTester implements SensorContext {
@CheckForNull
public Integer lineHits(String fileKey, int line) {
- return sensorStorage.coverageByComponent.get(fileKey).stream()
+ return sensorStorage.coverageByComponent.getOrDefault(fileKey, Collections.emptyList()).stream()
.map(c -> c.hitsByLine().get(line))
.flatMap(Stream::of)
.filter(Objects::nonNull)
@@ -273,7 +273,7 @@ public class SensorContextTester implements SensorContext {
@CheckForNull
public Integer conditions(String fileKey, int line) {
- return sensorStorage.coverageByComponent.get(fileKey).stream()
+ return sensorStorage.coverageByComponent.getOrDefault(fileKey, Collections.emptyList()).stream()
.map(c -> c.conditionsByLine().get(line))
.flatMap(Stream::of)
.filter(Objects::nonNull)
@@ -282,7 +282,7 @@ public class SensorContextTester implements SensorContext {
@CheckForNull
public Integer coveredConditions(String fileKey, int line) {
- return sensorStorage.coverageByComponent.get(fileKey).stream()
+ return sensorStorage.coverageByComponent.getOrDefault(fileKey, Collections.emptyList()).stream()
.map(c -> c.coveredConditionsByLine().get(line))
.flatMap(Stream::of)
.filter(Objects::nonNull)
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
index 39f01a319fc..4f24641c57f 100644
--- 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
@@ -19,7 +19,6 @@
*/
package org.sonar.api.batch.sensor.issue.internal;
-import com.google.common.base.Preconditions;
import java.nio.file.Path;
import java.util.ArrayList;
import java.util.Collections;
@@ -38,10 +37,10 @@ import org.sonar.api.batch.sensor.issue.IssueLocation;
import org.sonar.api.batch.sensor.issue.NewIssueLocation;
import org.sonar.api.utils.PathUtils;
-import static com.google.common.base.Preconditions.checkState;
-import static com.google.common.base.Strings.isNullOrEmpty;
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;
@@ -72,10 +71,10 @@ public abstract class AbstractDefaultIssue<T extends AbstractDefaultIssue> exten
}
public T at(NewIssueLocation primaryLocation) {
- Preconditions.checkArgument(primaryLocation != null, "Cannot use a location that is null");
+ checkArgument(primaryLocation != null, "Cannot use a location that is null");
checkState(this.primaryLocation == null, "at() already called");
this.primaryLocation = rewriteLocation((DefaultIssueLocation) primaryLocation);
- Preconditions.checkArgument(this.primaryLocation.inputComponent() != null, "Cannot use a location with no input component");
+ checkArgument(this.primaryLocation.inputComponent() != null, "Cannot use a location with no input component");
return (T) this;
}
@@ -110,7 +109,7 @@ public abstract class AbstractDefaultIssue<T extends AbstractDefaultIssue> exten
DefaultIssueLocation fixedLocation = new DefaultIssueLocation();
fixedLocation.on(project);
StringBuilder fullMessage = new StringBuilder();
- if (!isNullOrEmpty(path)) {
+ if (path != null && !path.isEmpty()) {
fullMessage.append("[").append(path).append("] ");
}
fullMessage.append(location.message());
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
index db1f22102eb..c402d6bcc28 100644
--- 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
@@ -19,7 +19,6 @@
*/
package org.sonar.api.batch.sensor.issue.internal;
-import com.google.common.base.Preconditions;
import javax.annotation.Nullable;
import org.sonar.api.batch.fs.internal.DefaultInputProject;
import org.sonar.api.batch.rule.Severity;
@@ -29,9 +28,10 @@ import org.sonar.api.batch.sensor.issue.NewExternalIssue;
import org.sonar.api.rule.RuleKey;
import org.sonar.api.rules.RuleType;
-import static com.google.common.base.Preconditions.checkState;
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;
@@ -50,7 +50,7 @@ public class DefaultExternalIssue extends AbstractDefaultIssue<DefaultExternalIs
@Override
public DefaultExternalIssue remediationEffortMinutes(@Nullable Long effort) {
- Preconditions.checkArgument(effort == null || effort >= 0, format("effort must be greater than or equal 0 (got %s)", effort));
+ checkArgument(effort == null || effort >= 0, format("effort must be greater than or equal 0 (got %s)", effort));
this.effort = effort;
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
index 770562eb1d2..2f59ddd944a 100644
--- 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
@@ -19,7 +19,6 @@
*/
package org.sonar.api.batch.sensor.issue.internal;
-import com.google.common.base.Preconditions;
import javax.annotation.Nullable;
import org.sonar.api.batch.fs.internal.DefaultInputProject;
import org.sonar.api.batch.rule.Severity;
@@ -29,9 +28,10 @@ import org.sonar.api.batch.sensor.issue.IssueLocation;
import org.sonar.api.batch.sensor.issue.NewIssue;
import org.sonar.api.rule.RuleKey;
-import static com.google.common.base.Preconditions.checkState;
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;
@@ -57,7 +57,7 @@ public class DefaultIssue extends AbstractDefaultIssue<DefaultIssue> implements
@Override
public DefaultIssue gap(@Nullable Double gap) {
- Preconditions.checkArgument(gap == null || gap >= 0, format("Gap must be greater than or equal 0 (got %s)", gap));
+ checkArgument(gap == null || gap >= 0, format("Gap must be greater than or equal 0 (got %s)", gap));
this.gap = gap;
return 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
index 01f73c2a954..124e7876b3f 100644
--- 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
@@ -19,19 +19,18 @@
*/
package org.sonar.api.batch.sensor.issue.internal;
-import com.google.common.base.Preconditions;
+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 javax.annotation.Nullable;
-
-import static com.google.common.base.Preconditions.checkArgument;
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 {
@@ -42,15 +41,15 @@ public class DefaultIssueLocation implements NewIssueLocation, IssueLocation {
@Override
public DefaultIssueLocation on(InputComponent component) {
checkArgument(component != null, "Component can't be null");
- Preconditions.checkState(this.component == null, "on() already called");
+ checkState(this.component == null, "on() already called");
this.component = component;
return this;
}
@Override
public DefaultIssueLocation at(TextRange location) {
- Preconditions.checkState(this.component != null, "at() should be called after on()");
- Preconditions.checkState(this.component.isFile(), "at() should be called only for an InputFile.");
+ 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;
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
index fd0bfaad581..b359e2d20cd 100644
--- 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
@@ -19,7 +19,6 @@
*/
package org.sonar.api.batch.sensor.measure.internal;
-import com.google.common.base.Preconditions;
import java.io.Serializable;
import javax.annotation.Nullable;
import org.apache.commons.lang.builder.EqualsBuilder;
@@ -32,6 +31,8 @@ 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> {
@@ -50,15 +51,15 @@ public class DefaultMeasure<G extends Serializable> extends DefaultStorable impl
@Override
public DefaultMeasure<G> on(InputComponent component) {
- Preconditions.checkArgument(component != null, "Component can't be null");
- Preconditions.checkState(this.component == null, "on() already called");
+ 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) {
- Preconditions.checkState(this.metric == null, "Metric already defined");
+ checkState(this.metric == null, "Metric already defined");
requireNonNull(metric, "metric should be non null");
this.metric = metric;
return this;
@@ -66,7 +67,7 @@ public class DefaultMeasure<G extends Serializable> extends DefaultStorable impl
@Override
public DefaultMeasure<G> withValue(G value) {
- Preconditions.checkState(this.value == null, "Measure value already defined");
+ checkState(this.value == null, "Measure value already defined");
requireNonNull(value, "Measure value can't be null");
this.value = value;
return this;
@@ -91,7 +92,7 @@ public class DefaultMeasure<G extends Serializable> extends DefaultStorable impl
public void doSave() {
requireNonNull(this.value, "Measure value can't be null");
requireNonNull(this.metric, "Measure metric can't be null");
- Preconditions.checkState(this.metric.valueType().equals(this.value.getClass()), "Measure value should be of type %s", this.metric.valueType());
+ checkState(this.metric.valueType().equals(this.value.getClass()), "Measure value should be of type %s", this.metric.valueType());
storage.store(this);
}
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
index 8204ccc909f..7ccf8aef768 100644
--- 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
@@ -28,8 +28,8 @@ import org.sonar.api.batch.sensor.rule.AdHocRule;
import org.sonar.api.batch.sensor.rule.NewAdHocRule;
import org.sonar.api.rules.RuleType;
-import static com.google.common.base.Preconditions.checkState;
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;
diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/symbol/internal/DefaultSymbolTable.java b/sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/symbol/internal/DefaultSymbolTable.java
index 90f4daeb8ba..087681a5aa8 100644
--- a/sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/symbol/internal/DefaultSymbolTable.java
+++ b/sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/symbol/internal/DefaultSymbolTable.java
@@ -19,7 +19,6 @@
*/
package org.sonar.api.batch.sensor.symbol.internal;
-import com.google.common.base.Preconditions;
import java.util.Collection;
import java.util.LinkedHashMap;
import java.util.Map;
@@ -34,6 +33,8 @@ import org.sonar.api.batch.sensor.symbol.NewSymbol;
import org.sonar.api.batch.sensor.symbol.NewSymbolTable;
import static java.util.Objects.requireNonNull;
+import static org.sonar.api.utils.Preconditions.checkArgument;
+import static org.sonar.api.utils.Preconditions.checkState;
public class DefaultSymbolTable extends DefaultStorable implements NewSymbolTable {
@@ -129,7 +130,7 @@ public class DefaultSymbolTable extends DefaultStorable implements NewSymbolTabl
@Override
public NewSymbol newReference(TextRange range) {
requireNonNull(range, "Provided range is null");
- Preconditions.checkArgument(!declaration.overlap(range), "Overlapping symbol declaration and reference for symbol at %s", declaration);
+ checkArgument(!declaration.overlap(range), "Overlapping symbol declaration and reference for symbol at %s", declaration);
references.add(range);
return this;
}
@@ -143,6 +144,6 @@ public class DefaultSymbolTable extends DefaultStorable implements NewSymbolTabl
}
private void checkInputFileNotNull() {
- Preconditions.checkState(inputFile != null, "Call onFile() first");
+ checkState(inputFile != null, "Call onFile() first");
}
}
diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/ce/measure/RangeDistributionBuilder.java b/sonar-plugin-api/src/main/java/org/sonar/api/ce/measure/RangeDistributionBuilder.java
index 57548342ae4..09605d5ee67 100644
--- a/sonar-plugin-api/src/main/java/org/sonar/api/ce/measure/RangeDistributionBuilder.java
+++ b/sonar-plugin-api/src/main/java/org/sonar/api/ce/measure/RangeDistributionBuilder.java
@@ -19,8 +19,6 @@
*/
package org.sonar.api.ce.measure;
-import com.google.common.collect.Multiset;
-import com.google.common.collect.TreeMultiset;
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
@@ -40,7 +38,7 @@ import org.sonar.api.utils.KeyValueFormat;
*/
public class RangeDistributionBuilder {
- private Multiset<Number> distributionSet;
+ private Map<Number, Integer> distributionSet;
private boolean isEmpty = true;
private Number[] bottomLimits;
private boolean isValid = true;
@@ -114,7 +112,10 @@ public class RangeDistributionBuilder {
System.arraycopy(bottomLimits, 0, this.bottomLimits, 0, this.bottomLimits.length);
Arrays.sort(this.bottomLimits);
changeDoublesToInts();
- distributionSet = TreeMultiset.create(NumberComparator.INSTANCE);
+ distributionSet = new TreeMap<>(NumberComparator.INSTANCE);
+ for (Number n : this.bottomLimits) {
+ distributionSet.put(n, 0);
+ }
}
private void changeDoublesToInts() {
@@ -156,7 +157,7 @@ public class RangeDistributionBuilder {
private void addValue(Number value, int count) {
for (int i = bottomLimits.length - 1; i >= 0; i--) {
if (greaterOrEqualsThan(value, bottomLimits[i])) {
- this.distributionSet.add(bottomLimits[i], count);
+ this.distributionSet.compute(bottomLimits[i], (k, v) -> v + count);
return;
}
}
@@ -186,11 +187,7 @@ public class RangeDistributionBuilder {
if (bottomLimits == null || bottomLimits.length == 0) {
return Collections.emptyMap();
}
- Map<Number, Integer> map = new TreeMap<>();
- for (Number value : bottomLimits) {
- map.put(value, distributionSet.count(value));
- }
- return map;
+ return distributionSet;
}
private static boolean greaterOrEqualsThan(Number n1, Number n2) {
diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/ce/measure/test/TestComponent.java b/sonar-plugin-api/src/main/java/org/sonar/api/ce/measure/test/TestComponent.java
index 4cc799ec322..9a698e8d404 100644
--- a/sonar-plugin-api/src/main/java/org/sonar/api/ce/measure/test/TestComponent.java
+++ b/sonar-plugin-api/src/main/java/org/sonar/api/ce/measure/test/TestComponent.java
@@ -24,8 +24,8 @@ import javax.annotation.Nullable;
import javax.annotation.concurrent.Immutable;
import org.sonar.api.ce.measure.Component;
-import static com.google.common.base.Preconditions.checkState;
import static java.util.Objects.requireNonNull;
+import static org.sonar.api.utils.Preconditions.checkState;
@Immutable
public class TestComponent implements Component {
diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/ce/measure/test/TestIssue.java b/sonar-plugin-api/src/main/java/org/sonar/api/ce/measure/test/TestIssue.java
index f2b16910e0e..1b8173fac8b 100644
--- a/sonar-plugin-api/src/main/java/org/sonar/api/ce/measure/test/TestIssue.java
+++ b/sonar-plugin-api/src/main/java/org/sonar/api/ce/measure/test/TestIssue.java
@@ -28,8 +28,8 @@ import org.sonar.api.rule.Severity;
import org.sonar.api.rules.RuleType;
import org.sonar.api.utils.Duration;
-import static com.google.common.base.Preconditions.checkArgument;
import static java.util.Objects.requireNonNull;
+import static org.sonar.api.utils.Preconditions.checkArgument;
@Immutable
public class TestIssue implements Issue {
diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/ce/measure/test/TestMeasure.java b/sonar-plugin-api/src/main/java/org/sonar/api/ce/measure/test/TestMeasure.java
index 10299aae0e3..5454dce79e4 100644
--- a/sonar-plugin-api/src/main/java/org/sonar/api/ce/measure/test/TestMeasure.java
+++ b/sonar-plugin-api/src/main/java/org/sonar/api/ce/measure/test/TestMeasure.java
@@ -22,8 +22,8 @@ package org.sonar.api.ce.measure.test;
import javax.annotation.concurrent.Immutable;
import org.sonar.api.ce.measure.Measure;
-import static com.google.common.base.Preconditions.checkState;
import static java.util.Objects.requireNonNull;
+import static org.sonar.api.utils.Preconditions.checkState;
@Immutable
public class TestMeasure implements Measure {
diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/ce/measure/test/TestMeasureComputerContext.java b/sonar-plugin-api/src/main/java/org/sonar/api/ce/measure/test/TestMeasureComputerContext.java
index 1489eb18fa5..e8015be2031 100644
--- a/sonar-plugin-api/src/main/java/org/sonar/api/ce/measure/test/TestMeasureComputerContext.java
+++ b/sonar-plugin-api/src/main/java/org/sonar/api/ce/measure/test/TestMeasureComputerContext.java
@@ -19,9 +19,8 @@
*/
package org.sonar.api.ce.measure.test;
-import com.google.common.collect.ArrayListMultimap;
-import com.google.common.collect.Multimap;
import java.util.ArrayList;
+import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
@@ -33,9 +32,9 @@ import org.sonar.api.ce.measure.Issue;
import org.sonar.api.ce.measure.Measure;
import org.sonar.api.ce.measure.Settings;
-import static com.google.common.base.Preconditions.checkArgument;
import static org.sonar.api.ce.measure.MeasureComputer.MeasureComputerContext;
import static org.sonar.api.ce.measure.MeasureComputer.MeasureComputerDefinition;
+import static org.sonar.api.utils.Preconditions.checkArgument;
public class TestMeasureComputerContext implements MeasureComputerContext {
@@ -44,7 +43,7 @@ public class TestMeasureComputerContext implements MeasureComputerContext {
private final Settings settings;
private Map<String, Measure> componentMeasureByMetricKey = new HashMap<>();
- private Multimap<String, Measure> childrenComponentMeasureByMetricKey = ArrayListMultimap.create();
+ private Map<String, List<Measure>> childrenComponentMeasureByMetricKey = new HashMap<>();
private List<Issue> issues = new ArrayList<>();
public TestMeasureComputerContext(Component component, Settings settings, MeasureComputerDefinition definition) {
@@ -73,7 +72,7 @@ public class TestMeasureComputerContext implements MeasureComputerContext {
@Override
public Iterable<Measure> getChildrenMeasures(String metric) {
validateInputMetric(metric);
- return childrenComponentMeasureByMetricKey.get(metric);
+ return childrenComponentMeasureByMetricKey.getOrDefault(metric, Collections.emptyList());
}
@Override
@@ -88,7 +87,7 @@ public class TestMeasureComputerContext implements MeasureComputerContext {
public void addChildrenMeasures(String metricKey, Integer... values) {
for (Integer value : values) {
- childrenComponentMeasureByMetricKey.put(metricKey, TestMeasure.createMeasure(value));
+ childrenComponentMeasureByMetricKey.computeIfAbsent(metricKey, x -> new ArrayList<>()).add(TestMeasure.createMeasure(value));
}
}
@@ -104,7 +103,7 @@ public class TestMeasureComputerContext implements MeasureComputerContext {
public void addChildrenMeasures(String metricKey, Double... values) {
for (Double value : values) {
- childrenComponentMeasureByMetricKey.put(metricKey, TestMeasure.createMeasure(value));
+ childrenComponentMeasureByMetricKey.computeIfAbsent(metricKey, x -> new ArrayList<>()).add(TestMeasure.createMeasure(value));
}
}
@@ -120,7 +119,7 @@ public class TestMeasureComputerContext implements MeasureComputerContext {
public void addChildrenMeasures(String metricKey, Long... values) {
for (Long value : values) {
- childrenComponentMeasureByMetricKey.put(metricKey, TestMeasure.createMeasure(value));
+ childrenComponentMeasureByMetricKey.computeIfAbsent(metricKey, x -> new ArrayList<>()).add(TestMeasure.createMeasure(value));
}
}
@@ -136,7 +135,6 @@ public class TestMeasureComputerContext implements MeasureComputerContext {
componentMeasureByMetricKey.put(metricKey, TestMeasure.createMeasure(value));
}
-
public void addInputMeasure(String metricKey, boolean value) {
componentMeasureByMetricKey.put(metricKey, TestMeasure.createMeasure(value));
}
@@ -147,7 +145,7 @@ public class TestMeasureComputerContext implements MeasureComputerContext {
public void addChildrenMeasures(String metricKey, String... values) {
for (String value : values) {
- childrenComponentMeasureByMetricKey.put(metricKey, TestMeasure.createMeasure(value));
+ childrenComponentMeasureByMetricKey.computeIfAbsent(metricKey, x -> new ArrayList<>()).add(TestMeasure.createMeasure(value));
}
}
diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/ce/measure/test/TestMeasureComputerDefinition.java b/sonar-plugin-api/src/main/java/org/sonar/api/ce/measure/test/TestMeasureComputerDefinition.java
index 8eec9324106..a932efa6e00 100644
--- a/sonar-plugin-api/src/main/java/org/sonar/api/ce/measure/test/TestMeasureComputerDefinition.java
+++ b/sonar-plugin-api/src/main/java/org/sonar/api/ce/measure/test/TestMeasureComputerDefinition.java
@@ -26,10 +26,10 @@ import org.sonar.api.ce.measure.MeasureComputer;
import org.sonar.api.measures.CoreMetrics;
import org.sonar.api.measures.Metric;
-import static com.google.common.base.Preconditions.checkArgument;
import static java.util.Arrays.asList;
import static java.util.Collections.unmodifiableSet;
import static java.util.Objects.requireNonNull;
+import static org.sonar.api.utils.Preconditions.checkArgument;
public class TestMeasureComputerDefinition implements MeasureComputer.MeasureComputerDefinition {
diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/ce/posttask/PostProjectAnalysisTaskTester.java b/sonar-plugin-api/src/main/java/org/sonar/api/ce/posttask/PostProjectAnalysisTaskTester.java
index e50157cf9d0..db4576c053d 100644
--- a/sonar-plugin-api/src/main/java/org/sonar/api/ce/posttask/PostProjectAnalysisTaskTester.java
+++ b/sonar-plugin-api/src/main/java/org/sonar/api/ce/posttask/PostProjectAnalysisTaskTester.java
@@ -30,8 +30,8 @@ import java.util.Optional;
import javax.annotation.CheckForNull;
import javax.annotation.Nullable;
-import static com.google.common.base.Preconditions.checkArgument;
import static java.util.Objects.requireNonNull;
+import static org.sonar.api.utils.Preconditions.checkArgument;
/**
* This class can be used to test {@link PostProjectAnalysisTask} implementations, see example below:
@@ -41,21 +41,17 @@ import static java.util.Objects.requireNonNull;
* import static org.sonar.api.ce.posttask.PostProjectAnalysisTaskTester.newConditionBuilder;
* import static org.sonar.api.ce.posttask.PostProjectAnalysisTaskTester.newProjectBuilder;
* import static org.sonar.api.ce.posttask.PostProjectAnalysisTaskTester.newQualityGateBuilder;
- *
* public class CaptorPostProjectAnalysisTaskTest {
* private class CaptorPostProjectAnalysisTask implements PostProjectAnalysisTask {
* private ProjectAnalysis projectAnalysis;
- *
* {@literal @}Override
* public void finished(ProjectAnalysis analysis) {
* this.projectAnalysis = analysis;
* }
* }
- *
* {@literal @}Test
* public void execute_is_passed_a_non_null_ProjectAnalysis_object() {
* CaptorPostProjectAnalysisTask postProjectAnalysisTask = new CaptorPostProjectAnalysisTask();
- *
* PostProjectAnalysisTaskTester.of(postProjectAnalysisTask)
* .withCeTask(
* newCeTaskBuilder()
@@ -83,7 +79,6 @@ import static java.util.Objects.requireNonNull;
* .build(QualityGate.EvaluationStatus.OK, "value"))
* .build())
* .execute();
- *
* assertThat(postProjectAnalysisTask.projectAnalysis).isNotNull();
* }
* }
diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/config/PropertyDefinition.java b/sonar-plugin-api/src/main/java/org/sonar/api/config/PropertyDefinition.java
index 611c28431ab..ce894f30de9 100644
--- a/sonar-plugin-api/src/main/java/org/sonar/api/config/PropertyDefinition.java
+++ b/sonar-plugin-api/src/main/java/org/sonar/api/config/PropertyDefinition.java
@@ -34,13 +34,12 @@ import org.apache.commons.lang.math.NumberUtils;
import org.sonar.api.ExtensionPoint;
import org.sonar.api.Property;
import org.sonar.api.PropertyType;
-import org.sonar.api.scanner.ScannerSide;
import org.sonar.api.ce.ComputeEngineSide;
import org.sonar.api.resources.Qualifiers;
+import org.sonar.api.scanner.ScannerSide;
import org.sonar.api.server.ServerSide;
import org.sonarsource.api.sonarlint.SonarLintSide;
-import static com.google.common.base.Preconditions.checkArgument;
import static java.util.Arrays.asList;
import static java.util.Arrays.stream;
import static java.util.Collections.unmodifiableSet;
@@ -54,6 +53,7 @@ import static org.sonar.api.PropertyType.LONG;
import static org.sonar.api.PropertyType.PROPERTY_SET;
import static org.sonar.api.PropertyType.REGULAR_EXPRESSION;
import static org.sonar.api.PropertyType.SINGLE_SELECT_LIST;
+import static org.sonar.api.utils.Preconditions.checkArgument;
/**
* Declare a plugin property. Values are available at runtime through the component {@link Configuration}.
@@ -461,7 +461,7 @@ public final class PropertyDefinition {
* only in General Settings.
*
* @throws IllegalArgumentException only qualifiers {@link Qualifiers#PROJECT PROJECT}, {@link Qualifiers#MODULE MODULE}, {@link Qualifiers#APP APP},
- * {@link Qualifiers#VIEW VIEW} and {@link Qualifiers#SUBVIEW SVW} are allowed.
+ * {@link Qualifiers#VIEW VIEW} and {@link Qualifiers#SUBVIEW SVW} are allowed.
* @throws IllegalArgumentException only qualifiers {@link Qualifiers#PROJECT PROJECT}, {@link Qualifiers#MODULE MODULE},
* {@link Qualifiers#VIEW VIEW} and {@link Qualifiers#SUBVIEW SVW} are allowed.
*/
diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/config/PropertyFieldDefinition.java b/sonar-plugin-api/src/main/java/org/sonar/api/config/PropertyFieldDefinition.java
index 61c0e5bb1df..db1ad3822a3 100644
--- a/sonar-plugin-api/src/main/java/org/sonar/api/config/PropertyFieldDefinition.java
+++ b/sonar-plugin-api/src/main/java/org/sonar/api/config/PropertyFieldDefinition.java
@@ -19,7 +19,6 @@
*/
package org.sonar.api.config;
-import com.google.common.base.Preconditions;
import java.util.ArrayList;
import java.util.List;
import javax.annotation.Nullable;
@@ -28,6 +27,7 @@ import org.sonar.api.PropertyField;
import org.sonar.api.PropertyType;
import static java.util.Arrays.asList;
+import static org.sonar.api.utils.Preconditions.checkArgument;
/**
* @since 3.3
@@ -151,8 +151,8 @@ public final class PropertyFieldDefinition {
}
public PropertyFieldDefinition build() {
- Preconditions.checkArgument(!StringUtils.isEmpty(key), "Key must be set");
- Preconditions.checkArgument(!StringUtils.isEmpty(name), "Name must be set");
+ checkArgument(!StringUtils.isEmpty(key), "Key must be set");
+ checkArgument(!StringUtils.isEmpty(name), "Name must be set");
return new PropertyFieldDefinition(this);
}
}
diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/config/Settings.java b/sonar-plugin-api/src/main/java/org/sonar/api/config/Settings.java
index 10f6cc90af6..b641d5ddca0 100644
--- a/sonar-plugin-api/src/main/java/org/sonar/api/config/Settings.java
+++ b/sonar-plugin-api/src/main/java/org/sonar/api/config/Settings.java
@@ -19,8 +19,8 @@
*/
package org.sonar.api.config;
-import com.google.common.base.Splitter;
import java.util.ArrayList;
+import java.util.Arrays;
import java.util.Date;
import java.util.List;
import java.util.Map;
@@ -31,8 +31,8 @@ import javax.annotation.CheckForNull;
import javax.annotation.Nullable;
import org.apache.commons.lang.ArrayUtils;
import org.apache.commons.lang.StringUtils;
-import org.sonar.api.scanner.ScannerSide;
import org.sonar.api.ce.ComputeEngineSide;
+import org.sonar.api.scanner.ScannerSide;
import org.sonar.api.server.ServerSide;
import org.sonar.api.utils.DateUtils;
import org.sonarsource.api.sonarlint.SonarLintSide;
@@ -160,6 +160,7 @@ public abstract class Settings {
/**
* Effective value as boolean. It is {@code false} if {@link #getString(String)}
* does not return {@code "true"}, even if it's not a boolean representation.
+ *
* @return {@code true} if the effective value is {@code "true"}, else {@code false}.
*/
public boolean getBoolean(String key) {
@@ -169,6 +170,7 @@ public abstract class Settings {
/**
* Effective value as {@code int}.
+ *
* @return the value as {@code int}. If the property does not have value nor default value, then {@code 0} is returned.
* @throws NumberFormatException if value is not empty and is not a parsable integer
*/
@@ -182,6 +184,7 @@ public abstract class Settings {
/**
* Effective value as {@code long}.
+ *
* @return the value as {@code long}. If the property does not have value nor default value, then {@code 0L} is returned.
* @throws NumberFormatException if value is not empty and is not a parsable {@code long}
*/
@@ -225,6 +228,7 @@ public abstract class Settings {
/**
* Effective value as {@code Float}.
+ *
* @return the value as {@code Float}. If the property does not have value nor default value, then {@code null} is returned.
* @throws NumberFormatException if value is not empty and is not a parsable number
*/
@@ -243,6 +247,7 @@ public abstract class Settings {
/**
* Effective value as {@code Double}.
+ *
* @return the value as {@code Double}. If the property does not have value nor default value, then {@code null} is returned.
* @throws NumberFormatException if value is not empty and is not a parsable number
*/
@@ -278,11 +283,9 @@ public abstract class Settings {
return ArrayUtils.EMPTY_STRING_ARRAY;
}
- List<String> values = new ArrayList<>();
- for (String v : Splitter.on(",").trimResults().split(value)) {
- values.add(v.replace("%2C", ","));
- }
- return values.toArray(new String[values.size()]);
+ return Arrays.stream(value.split(",", -1)).map(String::trim)
+ .map(s -> s.replace("%2C", ","))
+ .toArray(String[]::new);
}
return getStringArrayBySeparator(key, ",");
@@ -358,11 +361,10 @@ public abstract class Settings {
* Change a property value in a restricted scope only, depending on execution context. New value
* is <b>never</b> persisted. New value is ephemeral and kept in memory only:
* <ul>
- * <li>during current analysis in the case of scanner stack</li>
- * <li>during processing of current HTTP request in the case of web server stack</li>
- * <li>during execution of current task in the case of Compute Engine stack</li>
+ * <li>during current analysis in the case of scanner stack</li>
+ * <li>during processing of current HTTP request in the case of web server stack</li>
+ * <li>during execution of current task in the case of Compute Engine stack</li>
* </ul>
- *
* Property is temporarily removed if the parameter {@code value} is {@code null}
*/
public Settings setProperty(String key, @Nullable String value) {
diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/config/internal/MultivalueProperty.java b/sonar-plugin-api/src/main/java/org/sonar/api/config/internal/MultivalueProperty.java
index bf0bb1b9e20..dab98c55781 100644
--- a/sonar-plugin-api/src/main/java/org/sonar/api/config/internal/MultivalueProperty.java
+++ b/sonar-plugin-api/src/main/java/org/sonar/api/config/internal/MultivalueProperty.java
@@ -19,7 +19,6 @@
*/
package org.sonar.api.config.internal;
-import com.google.common.annotations.VisibleForTesting;
import java.io.IOException;
import java.io.StringReader;
import java.util.ArrayList;
@@ -127,7 +126,6 @@ public class MultivalueProperty {
* <li>{@code "a,\" \",b" => "ab"]}</li>
* </ul>
*/
- @VisibleForTesting
static String trimFieldsAndRemoveEmptyFields(String str) {
char[] chars = str.toCharArray();
char[] res = new char[chars.length];
diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/internal/MetadataLoader.java b/sonar-plugin-api/src/main/java/org/sonar/api/internal/MetadataLoader.java
index d22a4ec2aa6..f104d0cef64 100644
--- a/sonar-plugin-api/src/main/java/org/sonar/api/internal/MetadataLoader.java
+++ b/sonar-plugin-api/src/main/java/org/sonar/api/internal/MetadataLoader.java
@@ -19,10 +19,12 @@
*/
package org.sonar.api.internal;
-import com.google.common.io.Resources;
import java.io.IOException;
+import java.net.URISyntaxException;
import java.net.URL;
import java.nio.charset.StandardCharsets;
+import java.nio.file.Files;
+import java.nio.file.Paths;
import org.sonar.api.SonarEdition;
import org.sonar.api.utils.System2;
import org.sonar.api.utils.Version;
@@ -46,9 +48,9 @@ public class MetadataLoader {
public static Version loadVersion(System2 system) {
try {
URL url = system.getResource(VERSION_FILE_PATH);
- String versionInFile = Resources.toString(url, StandardCharsets.UTF_8);
+ String versionInFile = new String(Files.readAllBytes(Paths.get(url.toURI())), StandardCharsets.UTF_8);
return Version.parse(versionInFile);
- } catch (IOException e) {
+ } catch (IOException | URISyntaxException e) {
throw new IllegalStateException("Can not load " + VERSION_FILE_PATH + " from classpath", e);
}
}
@@ -59,9 +61,9 @@ public class MetadataLoader {
if (url == null) {
return SonarEdition.COMMUNITY;
}
- String editionInFile = Resources.toString(url, StandardCharsets.UTF_8);
+ String editionInFile = new String(Files.readAllBytes(Paths.get(url.toURI())), StandardCharsets.UTF_8);
return parseEdition(editionInFile);
- } catch (IOException e) {
+ } catch (IOException | URISyntaxException e) {
throw new IllegalStateException("Can not load " + EDITION_FILE_PATH + " from classpath", e);
}
}
diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/internal/SonarRuntimeImpl.java b/sonar-plugin-api/src/main/java/org/sonar/api/internal/SonarRuntimeImpl.java
index 6395546469f..3f69f36bb4e 100644
--- a/sonar-plugin-api/src/main/java/org/sonar/api/internal/SonarRuntimeImpl.java
+++ b/sonar-plugin-api/src/main/java/org/sonar/api/internal/SonarRuntimeImpl.java
@@ -27,8 +27,8 @@ import org.sonar.api.SonarQubeSide;
import org.sonar.api.SonarRuntime;
import org.sonar.api.utils.Version;
-import static com.google.common.base.Preconditions.checkArgument;
import static java.util.Objects.requireNonNull;
+import static org.sonar.api.utils.Preconditions.checkArgument;
/**
* @since 6.0
diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/measures/Metric.java b/sonar-plugin-api/src/main/java/org/sonar/api/measures/Metric.java
index f7e199ff592..ca5f062d66e 100644
--- a/sonar-plugin-api/src/main/java/org/sonar/api/measures/Metric.java
+++ b/sonar-plugin-api/src/main/java/org/sonar/api/measures/Metric.java
@@ -31,9 +31,8 @@ import org.sonar.api.ce.ComputeEngineSide;
import org.sonar.api.scanner.ScannerSide;
import org.sonar.api.server.ServerSide;
-import static com.google.common.base.MoreObjects.firstNonNull;
-import static com.google.common.base.Preconditions.checkArgument;
import static org.apache.commons.lang.StringUtils.isNotBlank;
+import static org.sonar.api.utils.Preconditions.checkArgument;
/**
* Used to define a metric in a plugin. Should be used with {@link Metrics} extension point.
@@ -219,7 +218,7 @@ public class Metric<G extends Serializable> implements Serializable, org.sonar.a
* @param userManaged whether the metric is user managed
*/
private Metric(String key, String name, String description, ValueType type, Integer direction, Boolean qualitative, @Nullable String domain,
- boolean userManaged) {
+ boolean userManaged) {
this.key = key;
this.description = description;
this.type = type;
@@ -739,15 +738,20 @@ public class Metric<G extends Serializable> implements Serializable, org.sonar.a
if (ValueType.PERCENT == this.type) {
this.bestValue = (direction == DIRECTION_BETTER) ? 100.0 : 0.0;
this.worstValue = (direction == DIRECTION_BETTER) ? 0.0 : 100.0;
- this.decimalScale = firstNonNull(decimalScale, DEFAULT_DECIMAL_SCALE);
+ this.decimalScale = coalesce(decimalScale, DEFAULT_DECIMAL_SCALE);
} else if (ValueType.FLOAT == this.type) {
- this.decimalScale = firstNonNull(decimalScale, DEFAULT_DECIMAL_SCALE);
+ this.decimalScale = coalesce(decimalScale, DEFAULT_DECIMAL_SCALE);
}
return new Metric<>(this);
}
}
+ @CheckForNull
+ private static <T> T coalesce(@Nullable T a, @Nullable T b) {
+ return a == null ? b : a;
+ }
+
@Override
public String key() {
return getKey();
diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/resources/AbstractLanguage.java b/sonar-plugin-api/src/main/java/org/sonar/api/resources/AbstractLanguage.java
index 4039fd7d76d..f63df013465 100644
--- a/sonar-plugin-api/src/main/java/org/sonar/api/resources/AbstractLanguage.java
+++ b/sonar-plugin-api/src/main/java/org/sonar/api/resources/AbstractLanguage.java
@@ -19,10 +19,10 @@
*/
package org.sonar.api.resources;
-import com.google.common.base.Preconditions;
-
import java.util.Locale;
+import static org.sonar.api.utils.Preconditions.checkArgument;
+
/**
* Inherit this class to define a new language like PLSQL, PHP or C#
*
@@ -34,7 +34,7 @@ public abstract class AbstractLanguage implements Language {
/**
* Better to use AbstractLanguage(key, name). In this case, key and name will be the same
- *
+ *
* @param key The key of the language. Must not be more than 20 chars.
*/
public AbstractLanguage(String key) {
@@ -44,11 +44,11 @@ public abstract class AbstractLanguage implements Language {
/**
* Should be the constructor used to build an AbstractLanguage.
*
- * @param key the key that will be used to retrieve the language. Must not be more than 20 chars. This key is important as it will be used to teint rules repositories...
+ * @param key the key that will be used to retrieve the language. Must not be more than 20 chars. This key is important as it will be used to teint rules repositories...
* @param name the display name of the language in the interface
*/
public AbstractLanguage(String key, String name) {
- Preconditions.checkArgument(key.length() <= 20, "The following language key exceeds 20 characters: '" + key + "'");
+ checkArgument(key.length() <= 20, "The following language key exceeds 20 characters: '" + key + "'");
this.key = key.toLowerCase(Locale.ENGLISH);
this.name = name;
}
diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/resources/ResourceType.java b/sonar-plugin-api/src/main/java/org/sonar/api/resources/ResourceType.java
index 176bf939a4c..a9a00ff5cb6 100644
--- a/sonar-plugin-api/src/main/java/org/sonar/api/resources/ResourceType.java
+++ b/sonar-plugin-api/src/main/java/org/sonar/api/resources/ResourceType.java
@@ -19,7 +19,6 @@
*/
package org.sonar.api.resources;
-import com.google.common.base.Preconditions;
import java.util.HashMap;
import java.util.Map;
import javax.annotation.Nullable;
@@ -27,6 +26,7 @@ import javax.annotation.concurrent.Immutable;
import static java.util.Objects.requireNonNull;
import static org.apache.commons.lang.StringUtils.isEmpty;
+import static org.sonar.api.utils.Preconditions.checkArgument;
/**
* <p>Experimental extension to declare types of resources.
@@ -36,7 +36,6 @@ import static org.apache.commons.lang.StringUtils.isEmpty;
* the resource being displayed.
* <br>
* Currently, the following properties can be defined:
- *
* <ul>
* <li>"deletable": if set to "true", then this resource can be deleted/purged.</li>
* <li>"supportsMeasureFilters": if set to "true", then this resource can be displayed in measure filters</li>
@@ -148,7 +147,7 @@ public class ResourceType {
*/
public static Builder builder(String qualifier) {
requireNonNull(qualifier);
- Preconditions.checkArgument(qualifier.length() <= 10, "Qualifier is limited to 10 characters");
+ checkArgument(qualifier.length() <= 10, "Qualifier is limited to 10 characters");
return new Builder(qualifier);
}
diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/resources/ResourceTypeTree.java b/sonar-plugin-api/src/main/java/org/sonar/api/resources/ResourceTypeTree.java
index c747bab32b3..d2e44fa8a91 100644
--- a/sonar-plugin-api/src/main/java/org/sonar/api/resources/ResourceTypeTree.java
+++ b/sonar-plugin-api/src/main/java/org/sonar/api/resources/ResourceTypeTree.java
@@ -19,21 +19,21 @@
*/
package org.sonar.api.resources;
-import com.google.common.collect.ArrayListMultimap;
-import com.google.common.collect.ImmutableListMultimap;
-import com.google.common.collect.ListMultimap;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
import java.util.List;
+import java.util.Map;
import java.util.stream.Collectors;
-import org.sonar.api.scanner.ScannerSide;
import org.sonar.api.ce.ComputeEngineSide;
+import org.sonar.api.scanner.ScannerSide;
import org.sonar.api.server.ServerSide;
-import static com.google.common.base.Preconditions.checkArgument;
import static java.util.Collections.unmodifiableList;
import static java.util.Objects.requireNonNull;
+import static org.sonar.api.utils.Preconditions.checkArgument;
/**
* @since 2.14
@@ -44,12 +44,12 @@ import static java.util.Objects.requireNonNull;
public class ResourceTypeTree {
private final List<ResourceType> types;
- private final ListMultimap<String, String> relations;
+ private final Map<String, List<String>> relations;
private final ResourceType root;
private ResourceTypeTree(Builder builder) {
this.types = unmodifiableList(new ArrayList<>(builder.types));
- this.relations = ImmutableListMultimap.copyOf(builder.relations);
+ this.relations = Collections.unmodifiableMap(builder.relations);
this.root = builder.root;
}
@@ -58,7 +58,7 @@ public class ResourceTypeTree {
}
public List<String> getChildren(String qualifier) {
- return relations.get(qualifier);
+ return relations.getOrDefault(qualifier, Collections.emptyList());
}
public ResourceType getRootType() {
@@ -66,10 +66,11 @@ public class ResourceTypeTree {
}
public List<String> getLeaves() {
- return unmodifiableList(relations.values()
+ return relations.values()
.stream()
- .filter(qualifier -> relations.get(qualifier).isEmpty())
- .collect(Collectors.toList()));
+ .flatMap(Collection::stream)
+ .filter(qualifier -> !relations.containsKey(qualifier))
+ .collect(Collectors.toList());
}
@Override
@@ -83,7 +84,8 @@ public class ResourceTypeTree {
public static final class Builder {
private List<ResourceType> types = new ArrayList<>();
- private ListMultimap<String, String> relations = ArrayListMultimap.create();
+ private Map<String, List<String>> relations = new HashMap<>();
+ private List<String> children = new ArrayList<>();
private ResourceType root;
private Builder() {
@@ -100,12 +102,12 @@ public class ResourceTypeTree {
requireNonNull(parentQualifier);
requireNonNull(childrenQualifiers);
checkArgument(childrenQualifiers.length > 0, "childrenQualifiers can't be empty");
- relations.putAll(parentQualifier, Arrays.asList(childrenQualifiers));
+ relations.computeIfAbsent(parentQualifier, x -> new ArrayList<>()).addAll(Arrays.asList(childrenQualifiers));
+ children.addAll(Arrays.asList(childrenQualifiers));
return this;
}
public ResourceTypeTree build() {
- Collection<String> children = relations.values();
for (ResourceType type : types) {
if (!children.contains(type.getQualifier())) {
root = type;
diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/resources/ResourceTypes.java b/sonar-plugin-api/src/main/java/org/sonar/api/resources/ResourceTypes.java
index 9a418c5445b..34ed696ca27 100644
--- a/sonar-plugin-api/src/main/java/org/sonar/api/resources/ResourceTypes.java
+++ b/sonar-plugin-api/src/main/java/org/sonar/api/resources/ResourceTypes.java
@@ -19,7 +19,6 @@
*/
package org.sonar.api.resources;
-import com.google.common.annotations.Beta;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
@@ -37,7 +36,6 @@ import static java.util.Objects.requireNonNull;
/**
* @since 2.14
*/
-@Beta
@ServerSide
@ComputeEngineSide
public class ResourceTypes {
diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/rule/RuleKey.java b/sonar-plugin-api/src/main/java/org/sonar/api/rule/RuleKey.java
index f503dab866b..2ac2f1f79f6 100644
--- a/sonar-plugin-api/src/main/java/org/sonar/api/rule/RuleKey.java
+++ b/sonar-plugin-api/src/main/java/org/sonar/api/rule/RuleKey.java
@@ -19,12 +19,12 @@
*/
package org.sonar.api.rule;
-import com.google.common.base.Preconditions;
import java.io.Serializable;
import javax.annotation.Nullable;
import javax.annotation.concurrent.Immutable;
import static org.apache.commons.lang.StringUtils.isEmpty;
+import static org.sonar.api.utils.Preconditions.checkArgument;
/**
* Key of a rule. Unique among all the rule repositories.
@@ -50,8 +50,8 @@ public class RuleKey implements Serializable, Comparable<RuleKey> {
* Create a key. Parameters are NOT null.
*/
public static RuleKey of(String repository, String rule) {
- Preconditions.checkArgument(!isEmpty(repository), "Repository must be set");
- Preconditions.checkArgument(!isEmpty(rule), "Rule must be set");
+ checkArgument(!isEmpty(repository), "Repository must be set");
+ checkArgument(!isEmpty(rule), "Rule must be set");
return new RuleKey(repository, rule);
}
@@ -61,7 +61,7 @@ public class RuleKey implements Serializable, Comparable<RuleKey> {
*/
public static RuleKey parse(String s) {
int semiColonPos = s.indexOf(':');
- Preconditions.checkArgument(semiColonPos > 0, "Invalid rule key: " + s);
+ checkArgument(semiColonPos > 0, "Invalid rule key: " + s);
String key = s.substring(0, semiColonPos);
String repo = s.substring(semiColonPos + 1);
return RuleKey.of(key, repo);
@@ -81,7 +81,6 @@ public class RuleKey implements Serializable, Comparable<RuleKey> {
return rule;
}
-
@Override
public boolean equals(@Nullable Object o) {
if (this == o) {
diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/rules/AnnotationRuleParser.java b/sonar-plugin-api/src/main/java/org/sonar/api/rules/AnnotationRuleParser.java
index 10f7878994f..5e69f1b054c 100644
--- a/sonar-plugin-api/src/main/java/org/sonar/api/rules/AnnotationRuleParser.java
+++ b/sonar-plugin-api/src/main/java/org/sonar/api/rules/AnnotationRuleParser.java
@@ -19,13 +19,13 @@
*/
package org.sonar.api.rules;
-import com.google.common.base.Function;
-import com.google.common.base.Functions;
-import com.google.common.collect.ImmutableMap;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.Collection;
+import java.util.HashMap;
import java.util.List;
+import java.util.Map;
+import java.util.function.Function;
import org.apache.commons.lang.StringUtils;
import org.sonar.api.PropertyType;
import org.sonar.api.ce.ComputeEngineSide;
@@ -101,16 +101,19 @@ public final class AnnotationRuleParser {
}
}
- private static final Function<Class<?>, PropertyType> TYPE_FOR_CLASS = Functions.forMap(
- ImmutableMap.<Class<?>, PropertyType>builder()
- .put(Integer.class, PropertyType.INTEGER)
- .put(int.class, PropertyType.INTEGER)
- .put(Float.class, PropertyType.FLOAT)
- .put(float.class, PropertyType.FLOAT)
- .put(Boolean.class, PropertyType.BOOLEAN)
- .put(boolean.class, PropertyType.BOOLEAN)
- .build(),
- PropertyType.STRING);
+ private static final Map<Class<?>, PropertyType> TYPE_FOR_CLASS_MAP = new HashMap<>();
+
+ static {
+ TYPE_FOR_CLASS_MAP.put(Integer.class, PropertyType.INTEGER);
+ TYPE_FOR_CLASS_MAP.put(int.class, PropertyType.INTEGER);
+ TYPE_FOR_CLASS_MAP.put(Float.class, PropertyType.FLOAT);
+ TYPE_FOR_CLASS_MAP.put(float.class, PropertyType.FLOAT);
+ TYPE_FOR_CLASS_MAP.put(Boolean.class, PropertyType.BOOLEAN);
+ TYPE_FOR_CLASS_MAP.put(boolean.class, PropertyType.BOOLEAN);
+
+ }
+
+ private static final Function<Class<?>, PropertyType> TYPE_FOR_CLASS = type -> TYPE_FOR_CLASS_MAP.getOrDefault(type, PropertyType.STRING);
static PropertyType guessType(Class<?> type) {
return TYPE_FOR_CLASS.apply(type);
diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/rules/Rule.java b/sonar-plugin-api/src/main/java/org/sonar/api/rules/Rule.java
index b0f200b18ba..2eb4d07f57d 100644
--- a/sonar-plugin-api/src/main/java/org/sonar/api/rules/Rule.java
+++ b/sonar-plugin-api/src/main/java/org/sonar/api/rules/Rule.java
@@ -19,7 +19,6 @@
*/
package org.sonar.api.rules;
-import com.google.common.base.Joiner;
import java.util.ArrayList;
import java.util.Date;
import java.util.LinkedHashSet;
@@ -325,7 +324,7 @@ public class Rule {
*/
public Rule setStatus(String status) {
if (!STATUS_LIST.contains(status)) {
- throw new SonarException("The status of a rule can only contain : " + Joiner.on(", ").join(STATUS_LIST));
+ throw new SonarException("The status of a rule can only contain : " + String.join(", ", STATUS_LIST));
}
this.status = status;
return this;
@@ -408,8 +407,8 @@ public class Rule {
/**
* For internal use only.
*
- * @deprecated since 4.4, use {@link #getCharacteristicKey()}
* @since 4.3
+ * @deprecated since 4.4, use {@link #getCharacteristicKey()}
*/
@CheckForNull
@Deprecated
@@ -420,8 +419,8 @@ public class Rule {
/**
* For internal use only.
*
- * @deprecated since 4.4, use {@link #setCharacteristicKey(String)}
* @since 4.3
+ * @deprecated since 4.4, use {@link #setCharacteristicKey(String)}
*/
@Deprecated
public Rule setCharacteristicId(@Nullable Integer characteristicId) {
@@ -431,8 +430,8 @@ public class Rule {
/**
* For internal use only.
*
- * @deprecated since 4.4, use {@link #getDefaultCharacteristicKey()}
* @since 4.3
+ * @deprecated since 4.4, use {@link #getDefaultCharacteristicKey()}
*/
@CheckForNull
@Deprecated
@@ -443,8 +442,8 @@ public class Rule {
/**
* For internal use only.
*
- * @deprecated since 4.4, use {@link #setDefaultCharacteristicKey(String)}
* @since 4.3
+ * @deprecated since 4.4, use {@link #setDefaultCharacteristicKey(String)}
*/
@Deprecated
public Rule setDefaultCharacteristicId(@Nullable Integer defaultCharacteristicId) {
diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/rules/XMLRuleParser.java b/sonar-plugin-api/src/main/java/org/sonar/api/rules/XMLRuleParser.java
index 179fe5bff4a..e26e23bad8e 100644
--- a/sonar-plugin-api/src/main/java/org/sonar/api/rules/XMLRuleParser.java
+++ b/sonar-plugin-api/src/main/java/org/sonar/api/rules/XMLRuleParser.java
@@ -19,7 +19,6 @@
*/
package org.sonar.api.rules;
-import com.google.common.base.Strings;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
@@ -150,7 +149,7 @@ public final class XMLRuleParser {
tags.add(StringUtils.trim(cursor.collectDescendantText(false)));
}
}
- if (Strings.isNullOrEmpty(rule.getKey())) {
+ if (rule.getKey() == null || rule.getKey().isEmpty()) {
throw new SonarException("Node <key> is missing in <rule>");
}
rule.setTags(tags.toArray(new String[tags.size()]));
diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/server/authentication/Display.java b/sonar-plugin-api/src/main/java/org/sonar/api/server/authentication/Display.java
index 3e570eaa917..83414c82c5d 100644
--- a/sonar-plugin-api/src/main/java/org/sonar/api/server/authentication/Display.java
+++ b/sonar-plugin-api/src/main/java/org/sonar/api/server/authentication/Display.java
@@ -22,8 +22,8 @@ package org.sonar.api.server.authentication;
import javax.annotation.CheckForNull;
import javax.annotation.concurrent.Immutable;
-import static com.google.common.base.Preconditions.checkArgument;
import static org.apache.commons.lang.StringUtils.isNotBlank;
+import static org.sonar.api.utils.Preconditions.checkArgument;
/**
* Display information provided by the Identity Provider to be displayed into the login form.
@@ -47,7 +47,6 @@ public final class Display {
* URL path to the provider icon, as deployed at runtime, for example "/static/authgithub/github.svg" (in this
* case "authgithub" is the plugin key. Source file is "src/main/resources/static/github.svg").
* It can also be an external URL, for example "http://www.mydomain/myincon.png".
- *
* Must not be blank.
* <br>
* The recommended format is SVG with a size of 24x24 pixels.
diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/server/authentication/UserIdentity.java b/sonar-plugin-api/src/main/java/org/sonar/api/server/authentication/UserIdentity.java
index 60e737e27dc..5d398b9d5ad 100644
--- a/sonar-plugin-api/src/main/java/org/sonar/api/server/authentication/UserIdentity.java
+++ b/sonar-plugin-api/src/main/java/org/sonar/api/server/authentication/UserIdentity.java
@@ -26,10 +26,10 @@ import javax.annotation.Nullable;
import javax.annotation.concurrent.Immutable;
import org.sonar.api.user.UserGroupValidation;
-import static com.google.common.base.Preconditions.checkArgument;
import static java.util.Objects.requireNonNull;
import static org.apache.commons.lang.StringUtils.isBlank;
import static org.apache.commons.lang.StringUtils.isNotBlank;
+import static org.sonar.api.utils.Preconditions.checkArgument;
/**
* User information provided by the Identity Provider to be register into the platform.
diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/server/debt/internal/DefaultDebtRemediationFunction.java b/sonar-plugin-api/src/main/java/org/sonar/api/server/debt/internal/DefaultDebtRemediationFunction.java
index feb96c94f2e..e1d9951269f 100644
--- a/sonar-plugin-api/src/main/java/org/sonar/api/server/debt/internal/DefaultDebtRemediationFunction.java
+++ b/sonar-plugin-api/src/main/java/org/sonar/api/server/debt/internal/DefaultDebtRemediationFunction.java
@@ -19,7 +19,6 @@
*/
package org.sonar.api.server.debt.internal;
-import com.google.common.base.MoreObjects;
import javax.annotation.CheckForNull;
import javax.annotation.Nullable;
import org.apache.commons.lang.StringUtils;
@@ -27,7 +26,7 @@ import org.apache.commons.lang.builder.EqualsBuilder;
import org.sonar.api.server.debt.DebtRemediationFunction;
import org.sonar.api.utils.Duration;
-import static com.google.common.base.Preconditions.checkArgument;
+import static org.sonar.api.utils.Preconditions.checkArgument;
public class DefaultDebtRemediationFunction implements DebtRemediationFunction {
@@ -72,7 +71,6 @@ public class DefaultDebtRemediationFunction implements DebtRemediationFunction {
return gapMultiplier();
}
-
@Override
@CheckForNull
public String gapMultiplier() {
@@ -94,7 +92,6 @@ public class DefaultDebtRemediationFunction implements DebtRemediationFunction {
return baseEffort;
}
-
private void validate() {
checkArgument(type != null, "Remediation function type cannot be null");
switch (type) {
@@ -136,13 +133,12 @@ public class DefaultDebtRemediationFunction implements DebtRemediationFunction {
return result;
}
-
@Override
public String toString() {
- return MoreObjects.toStringHelper(DebtRemediationFunction.class)
- .add("type", type)
- .add("gap multiplier", gapMultiplier)
- .add("base effort", baseEffort)
- .toString();
+ return "DebtRemediationFunction{" +
+ "type=" + type + ", " +
+ "gap multiplier=" + gapMultiplier + ", " +
+ "base effort=" + baseEffort
+ + "}";
}
}
diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/server/profile/BuiltInQualityProfilesDefinition.java b/sonar-plugin-api/src/main/java/org/sonar/api/server/profile/BuiltInQualityProfilesDefinition.java
index 71b062c4b61..a7511159608 100644
--- a/sonar-plugin-api/src/main/java/org/sonar/api/server/profile/BuiltInQualityProfilesDefinition.java
+++ b/sonar-plugin-api/src/main/java/org/sonar/api/server/profile/BuiltInQualityProfilesDefinition.java
@@ -19,7 +19,6 @@
*/
package org.sonar.api.server.profile;
-import com.google.common.base.Preconditions;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
@@ -35,17 +34,17 @@ import org.sonar.api.rule.RuleKey;
import org.sonar.api.rule.Severity;
import org.sonar.api.server.ServerSide;
-import static com.google.common.base.Preconditions.checkArgument;
import static java.lang.String.format;
import static java.util.Collections.unmodifiableList;
import static java.util.Collections.unmodifiableMap;
import static org.apache.commons.lang.StringUtils.defaultIfEmpty;
import static org.apache.commons.lang.StringUtils.isNotBlank;
+import static org.sonar.api.utils.Preconditions.checkArgument;
/**
* Define built-in quality profiles which are automatically registered during SonarQube startup.
* We no more provide any facility to load profiles from XML file or annotated classes, but it should
- * be straightforward to implement (adapt code of deprecated {@link org.sonar.api.profiles.AnnotationProfileParser}
+ * be straightforward to implement (adapt code of deprecated {@link org.sonar.api.profiles.AnnotationProfileParser}
* or {@link org.sonar.api.profiles.XMLProfileParser} for example).
*
* @since 6.6
@@ -73,7 +72,7 @@ public interface BuiltInQualityProfilesDefinition {
private void registerProfile(NewBuiltInQualityProfileImpl newProfile) {
String language = newProfile.language();
String name = newProfile.name();
- Preconditions.checkArgument(!profilesByLanguageAndName.computeIfAbsent(language, l -> new LinkedHashMap<>()).containsKey(name),
+ checkArgument(!profilesByLanguageAndName.computeIfAbsent(language, l -> new LinkedHashMap<>()).containsKey(name),
"There is already a quality profile with name '%s' for language '%s'", name, language);
profilesByLanguageAndName.get(language).put(name, new BuiltInQualityProfileImpl(newProfile));
}
@@ -289,6 +288,7 @@ public interface BuiltInQualityProfilesDefinition {
/**
* Override default rule severity in this quality profile. By default the active rule will have the default rule severity.
+ *
* @param severity See {@link Severity} constants.
*/
public NewBuiltInActiveRule overrideSeverity(String severity) {
diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/server/rule/RulesDefinition.java b/sonar-plugin-api/src/main/java/org/sonar/api/server/rule/RulesDefinition.java
index 0894d45dfd1..c5a494dc23b 100644
--- a/sonar-plugin-api/src/main/java/org/sonar/api/server/rule/RulesDefinition.java
+++ b/sonar-plugin-api/src/main/java/org/sonar/api/server/rule/RulesDefinition.java
@@ -19,8 +19,6 @@
*/
package org.sonar.api.server.rule;
-import com.google.common.collect.ImmutableSortedSet;
-import com.google.common.collect.Sets;
import java.io.IOException;
import java.net.URL;
import java.util.ArrayList;
@@ -49,8 +47,6 @@ import org.sonar.api.server.debt.DebtRemediationFunction;
import org.sonar.api.utils.log.Loggers;
import org.sonarsource.api.sonarlint.SonarLintSide;
-import static com.google.common.base.Preconditions.checkArgument;
-import static com.google.common.base.Preconditions.checkState;
import static java.lang.String.format;
import static java.nio.charset.StandardCharsets.UTF_8;
import static java.util.Collections.emptyList;
@@ -59,6 +55,8 @@ import static java.util.Collections.unmodifiableMap;
import static org.apache.commons.lang.StringUtils.defaultIfEmpty;
import static org.apache.commons.lang.StringUtils.isEmpty;
import static org.apache.commons.lang.StringUtils.trimToNull;
+import static org.sonar.api.utils.Preconditions.checkArgument;
+import static org.sonar.api.utils.Preconditions.checkState;
/**
* Defines some coding rules of the same repository. For example the Java Findbugs plugin provides an implementation of
@@ -69,37 +67,28 @@ import static org.apache.commons.lang.StringUtils.trimToNull;
* <h3>How to use</h3>
* <pre>
* public class MyJsRulesDefinition implements RulesDefinition {
- *
* {@literal @}Override
* public void define(Context context) {
* NewRepository repository = context.createRepository("my_js", "js").setName("My Javascript Analyzer");
- *
* // define a rule programmatically. Note that rules
* // could be loaded from files (JSON, XML, ...)
* NewRule x1Rule = repository.createRule("x1")
* .setName("No empty line")
* .setHtmlDescription("Generate an issue on empty lines")
- *
* // optional tags
* .setTags("style", "stupid")
- *
* // optional status. Default value is READY.
* .setStatus(RuleStatus.BETA)
- *
* // default severity when the rule is activated on a Quality profile. Default value is MAJOR.
* .setSeverity(Severity.MINOR);
- *
* // optional type for SonarQube Quality Model. Default is RulesDefinition.Type.CODE_SMELL.
* .setType(RulesDefinition.Type.BUG)
- *
* x1Rule
* .setDebtRemediationFunction(x1Rule.debtRemediationFunctions().linearWithOffset("1h", "30min"));
- *
* x1Rule.createParam("acceptWhitespace")
* .setDefaultValue("false")
* .setType(RuleParamType.BOOLEAN)
* .setDescription("Accept whitespaces on the line");
- *
* // don't forget to call done() to finalize the definition
* repository.done();
* }
@@ -111,13 +100,10 @@ import static org.apache.commons.lang.StringUtils.trimToNull;
* <br>
* <pre>
* public class MyJsRulesDefinition implements RulesDefinition {
- *
* private final RulesDefinitionXmlLoader xmlLoader;
- *
* public MyJsRulesDefinition(RulesDefinitionXmlLoader xmlLoader) {
* this.xmlLoader = xmlLoader;
* }
- *
* {@literal @}Override
* public void define(Context context) {
* NewRepository repository = context.createRepository("my_js", "js").setName("My Javascript Analyzer");
@@ -133,15 +119,12 @@ import static org.apache.commons.lang.StringUtils.trimToNull;
* <br>
* <pre>
* public class MyJsRulesDefinition implements RulesDefinition {
- *
* private final RulesDefinitionXmlLoader xmlLoader;
* private final RulesDefinitionI18nLoader i18nLoader;
- *
* public MyJsRulesDefinition(RulesDefinitionXmlLoader xmlLoader, RulesDefinitionI18nLoader i18nLoader) {
* this.xmlLoader = xmlLoader;
* this.i18nLoader = i18nLoader;
* }
- *
* {@literal @}Override
* public void define(Context context) {
* NewRepository repository = context.createRepository("my_js", "js").setName("My Javascript Analyzer");
@@ -404,7 +387,7 @@ public interface RulesDefinition {
/**
* Creates a repository of rules from external rule engines.
* The repository key will be "external_[engineId]".
- *
+ *
* @since 7.2
*/
public NewRepository createExternalRepository(String engineId, String language) {
@@ -1013,9 +996,9 @@ public interface RulesDefinition {
* <p>
* Deprecated keys should be added with this method in order, oldest first, for documentation purpose.
*
- * @since 7.1
* @throws IllegalArgumentException if {@code repository} or {@code key} is {@code null} or empty.
* @see Rule#deprecatedRuleKeys
+ * @since 7.1
*/
public NewRule addDeprecatedRuleKey(String repository, String key) {
deprecatedRuleKeys.add(RuleKey.of(repository, key));
@@ -1067,15 +1050,17 @@ public interface RulesDefinition {
this.gapDescription = newRule.gapDescription;
this.scope = newRule.scope == null ? RuleScope.MAIN : newRule.scope;
this.type = newRule.type == null ? RuleTagsToTypeConverter.convert(newRule.tags) : newRule.type;
- this.tags = ImmutableSortedSet.copyOf(Sets.difference(newRule.tags, RuleTagsToTypeConverter.RESERVED_TAGS));
- this.securityStandards = ImmutableSortedSet.copyOf(newRule.securityStandards);
+ Set<String> tagsBuilder = new TreeSet<>(newRule.tags);
+ tagsBuilder.removeAll(RuleTagsToTypeConverter.RESERVED_TAGS);
+ this.tags = Collections.unmodifiableSet(tagsBuilder);
+ this.securityStandards = Collections.unmodifiableSet(new TreeSet<>(newRule.securityStandards));
Map<String, Param> paramsBuilder = new HashMap<>();
for (NewParam newParam : newRule.paramsByKey.values()) {
paramsBuilder.put(newParam.key, new Param(newParam));
}
this.params = Collections.unmodifiableMap(paramsBuilder);
this.activatedByDefault = newRule.activatedByDefault;
- this.deprecatedRuleKeys = ImmutableSortedSet.copyOf(newRule.deprecatedRuleKeys);
+ this.deprecatedRuleKeys = Collections.unmodifiableSet(new TreeSet<>(newRule.deprecatedRuleKeys));
}
public Repository repository() {
@@ -1207,35 +1192,34 @@ public interface RulesDefinition {
* <br>
* Consider the following use case scenario:
* <ul>
- * <li>Rule {@code Foo:A} is defined in version 1 of the plugin
+ * <li>Rule {@code Foo:A} is defined in version 1 of the plugin
* <pre>
* NewRepository newRepository = context.createRepository("Foo", "my_language");
* NewRule r = newRepository.createRule("A");
* </pre>
- * </li>
- * <li>Rule's key is renamed to B in version 2 of the plugin
+ * </li>
+ * <li>Rule's key is renamed to B in version 2 of the plugin
* <pre>
* NewRepository newRepository = context.createRepository("Foo", "my_language");
* NewRule r = newRepository.createRule("B")
* .addDeprecatedRuleKey("Foo", "A");
* </pre>
- * </li>
- * <li>All rules, including {@code Foo:B}, are moved to a new repository Bar in version 3 of the plugin
+ * </li>
+ * <li>All rules, including {@code Foo:B}, are moved to a new repository Bar in version 3 of the plugin
* <pre>
* NewRepository newRepository = context.createRepository("Bar", "my_language");
* NewRule r = newRepository.createRule("B")
* .addDeprecatedRuleKey("Foo", "A")
* .addDeprecatedRuleKey("Bar", "B");
* </pre>
- * </li>
+ * </li>
* </ul>
- *
* With all deprecated keys defined in version 3 of the plugin, SonarQube will be able to support "issue re-keying"
* for this rule in all cases:
* <ul>
- * <li>plugin upgrade from v1 to v2,</li>
- * <li>plugin upgrade from v2 to v3</li>
- * <li>AND plugin upgrade from v1 to v3</li>
+ * <li>plugin upgrade from v1 to v2,</li>
+ * <li>plugin upgrade from v2 to v3</li>
+ * <li>AND plugin upgrade from v1 to v3</li>
* </ul>
* <p>
* Finally, repository/key pairs must be unique across all rules and their deprecated keys.
@@ -1247,8 +1231,8 @@ public interface RulesDefinition {
* {@link NewRule#addDeprecatedRuleKey(String, String) addDeprecatedRuleKey}. This allows to describe the history
* of a rule's repositories and keys over time. Oldest repository and key must be specified first.
*
- * @since 7.1
* @see NewRule#addDeprecatedRuleKey(String, String)
+ * @since 7.1
*/
public Set<RuleKey> deprecatedRuleKeys() {
return deprecatedRuleKeys;
diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/server/ws/Request.java b/sonar-plugin-api/src/main/java/org/sonar/api/server/ws/Request.java
index 34c844ab6b1..737a34d9b5a 100644
--- a/sonar-plugin-api/src/main/java/org/sonar/api/server/ws/Request.java
+++ b/sonar-plugin-api/src/main/java/org/sonar/api/server/ws/Request.java
@@ -19,11 +19,10 @@
*/
package org.sonar.api.server.ws;
-import com.google.common.base.Splitter;
-import com.google.common.collect.ImmutableMap;
import java.io.BufferedReader;
import java.io.InputStream;
-import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
import java.util.Date;
import java.util.List;
import java.util.Map;
@@ -31,16 +30,17 @@ import java.util.Optional;
import java.util.function.BiFunction;
import java.util.function.Consumer;
import java.util.function.Supplier;
+import java.util.stream.Collectors;
import javax.annotation.CheckForNull;
import javax.annotation.Nullable;
import org.apache.commons.lang.StringUtils;
import org.sonar.api.utils.DateUtils;
-import static com.google.common.base.Preconditions.checkArgument;
import static java.lang.String.format;
import static java.util.Objects.requireNonNull;
import static org.sonar.api.utils.DateUtils.parseDateQuietly;
import static org.sonar.api.utils.DateUtils.parseDateTimeQuietly;
+import static org.sonar.api.utils.Preconditions.checkArgument;
/**
* @since 4.2
@@ -218,13 +218,11 @@ public abstract class Request {
if (value == null) {
return null;
}
- Iterable<String> values = Splitter.on(',').omitEmptyStrings().trimResults().split(value);
- List<E> result = new ArrayList<>();
- for (String s : values) {
- result.add(Enum.valueOf(enumClass, s));
- }
-
- return result;
+ return Arrays.stream(value.split(","))
+ .map(String::trim)
+ .filter(s -> !s.isEmpty())
+ .map(x -> Enum.valueOf(enumClass, x))
+ .collect(Collectors.toList());
}
@CheckForNull
@@ -319,11 +317,12 @@ public abstract class Request {
public abstract Optional<String> header(String name);
public Map<String, String> getHeaders() {
- return ImmutableMap.of();
+ return Collections.emptyMap();
}
/**
* Allows a web service to call another web service.
+ *
* @see LocalConnector
* @since 5.5
*/
@@ -331,6 +330,7 @@ public abstract class Request {
/**
* Return path of the request
+ *
* @since 6.0
*/
public abstract String getPath();
@@ -353,7 +353,6 @@ public abstract class Request {
/**
* @return the value of the parameter
- *
* @throws IllegalStateException if param is not present.
*/
@CheckForNull
@@ -424,7 +423,6 @@ public abstract class Request {
/**
* @return the value of the parameter
- *
* @throws IllegalStateException if param is not present.
*/
@Override
diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/server/ws/WebService.java b/sonar-plugin-api/src/main/java/org/sonar/api/server/ws/WebService.java
index 0ac828699c4..5d087b3aa8a 100644
--- a/sonar-plugin-api/src/main/java/org/sonar/api/server/ws/WebService.java
+++ b/sonar-plugin-api/src/main/java/org/sonar/api/server/ws/WebService.java
@@ -43,13 +43,12 @@ import org.sonar.api.server.ServerSide;
import org.sonar.api.utils.log.Logger;
import org.sonar.api.utils.log.Loggers;
-import static com.google.common.base.Preconditions.checkArgument;
-import static com.google.common.base.Preconditions.checkState;
-import static com.google.common.base.Strings.isNullOrEmpty;
import static java.lang.String.format;
import static java.util.Arrays.asList;
import static java.util.Arrays.stream;
import static java.util.Objects.requireNonNull;
+import static org.sonar.api.utils.Preconditions.checkArgument;
+import static org.sonar.api.utils.Preconditions.checkState;
/**
* Defines a web service.
@@ -64,7 +63,6 @@ import static java.util.Objects.requireNonNull;
* public void define(Context context) {
* NewController controller = context.createController("api/hello");
* controller.setDescription("Web service example");
- *
* // create the URL /api/hello/show
* controller.createAction("show")
* .setDescription("Entry point")
@@ -80,7 +78,6 @@ import static java.util.Objects.requireNonNull;
* }
* })
* .createParam("key").setDescription("Example key").setRequired(true);
- *
* // important to apply changes
* controller.done();
* }
@@ -396,6 +393,7 @@ public interface WebService extends Definable<WebService.Context> {
/**
* Add predefined parameters related to pagination of results with a maximum page size.
+ *
* @since 7.1
*/
public NewAction addPagingParamsSince(int defaultPageSize, int maxPageSize, String version) {
@@ -523,8 +521,8 @@ public interface WebService extends Definable<WebService.Context> {
this.changelog = newAction.changelog;
checkState(this.handler != null, "RequestHandler is not set on action %s", path);
- logWarningIf(isNullOrEmpty(this.description), "Description is not set on action " + path);
- logWarningIf(isNullOrEmpty(this.since), "Since is not set on action " + path);
+ logWarningIf(this.description == null || this.description.isEmpty(), "Description is not set on action " + path);
+ logWarningIf(this.since == null || this.since.isEmpty(), "Since is not set on action " + path);
logWarningIf(!this.post && this.responseExample == null, "The response example is not set on action " + path);
Map<String, Param> paramsBuilder = new HashMap<>();
@@ -664,8 +662,8 @@ public interface WebService extends Definable<WebService.Context> {
}
/**
- * @since 5.3
* @see Param#since()
+ * @since 5.3
*/
public NewParam setSince(@Nullable String since) {
this.since = since;
@@ -693,8 +691,8 @@ public interface WebService extends Definable<WebService.Context> {
/**
* @param deprecatedSince Version when the old key was replaced/deprecated. Ex: 5.6
- * @since 6.4
* @see Param#deprecatedKey()
+ * @since 6.4
*/
public NewParam setDeprecatedKey(@Nullable String key, @Nullable String deprecatedSince) {
this.deprecatedKey = key;
@@ -708,8 +706,8 @@ public interface WebService extends Definable<WebService.Context> {
}
/**
- * @since 5.6
* @see Param#description()
+ * @since 5.6
*/
public NewParam setDescription(@Nullable String description, Object... descriptionArgument) {
this.description = description == null ? null : String.format(description, descriptionArgument);
@@ -719,8 +717,8 @@ public interface WebService extends Definable<WebService.Context> {
/**
* Is the parameter required or optional ? Default value is false (optional).
*
- * @since 4.4
* @see Param#isRequired()
+ * @since 4.4
*/
public NewParam setRequired(boolean b) {
this.required = b;
@@ -732,8 +730,8 @@ public interface WebService extends Definable<WebService.Context> {
* displayed only when the check-box "Show Internal API" is selected. By default
* a parameter is not internal.
*
- * @since 6.2
* @see Param#isInternal()
+ * @since 6.2
*/
public NewParam setInternal(boolean b) {
this.internal = b;
@@ -741,8 +739,8 @@ public interface WebService extends Definable<WebService.Context> {
}
/**
- * @since 4.4
* @see Param#exampleValue()
+ * @since 4.4
*/
public NewParam setExampleValue(@Nullable Object s) {
this.exampleValue = (s != null) ? s.toString() : null;
@@ -753,8 +751,8 @@ public interface WebService extends Definable<WebService.Context> {
* Exhaustive list of possible values when it makes sense, for example
* list of severities.
*
- * @since 4.4
* @see Param#possibleValues()
+ * @since 4.4
*/
public <T> NewParam setPossibleValues(@Nullable T... values) {
return setPossibleValues(values == null ? Collections.emptyList() : asList(values));
@@ -762,6 +760,7 @@ public interface WebService extends Definable<WebService.Context> {
/**
* Shortcut for {@code setPossibleValues("true", "false", "yes", "no")}
+ *
* @since 4.4
*/
public NewParam setBooleanPossibleValues() {
@@ -772,8 +771,8 @@ public interface WebService extends Definable<WebService.Context> {
* Exhaustive list of possible values when it makes sense, for example
* list of severities.
*
- * @since 4.4
* @see Param#possibleValues()
+ * @since 4.4
*/
public <T> NewParam setPossibleValues(@Nullable Collection<T> values) {
if (values == null || values.isEmpty()) {
@@ -788,8 +787,8 @@ public interface WebService extends Definable<WebService.Context> {
}
/**
- * @since 4.4
* @see Param#defaultValue()
+ * @since 4.4
*/
public NewParam setDefaultValue(@Nullable Object o) {
this.defaultValue = (o != null) ? o.toString() : null;
@@ -797,8 +796,8 @@ public interface WebService extends Definable<WebService.Context> {
}
/**
- * @since 6.4
* @see Param#maxValuesAllowed()
+ * @since 6.4
*/
public NewParam setMaxValuesAllowed(@Nullable Integer maxValuesAllowed) {
this.maxValuesAllowed = maxValuesAllowed;
@@ -806,8 +805,8 @@ public interface WebService extends Definable<WebService.Context> {
}
/**
- * @since 7.0
* @see Param#maximumLength()
+ * @since 7.0
*/
public NewParam setMaximumLength(@Nullable Integer maximumLength) {
this.maximumLength = maximumLength;
@@ -815,8 +814,8 @@ public interface WebService extends Definable<WebService.Context> {
}
/**
- * @since 7.0
* @see Param#minimumLength()
+ * @since 7.0
*/
public NewParam setMinimumLength(@Nullable Integer minimumLength) {
this.minimumLength = minimumLength;
@@ -824,8 +823,8 @@ public interface WebService extends Definable<WebService.Context> {
}
/**
- * @since 7.0
* @see Param#maximumValue()
+ * @since 7.0
*/
public NewParam setMaximumValue(@Nullable Integer maximumValue) {
this.maximumValue = maximumValue;
diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/server/ws/internal/SimpleGetRequest.java b/sonar-plugin-api/src/main/java/org/sonar/api/server/ws/internal/SimpleGetRequest.java
index d600f65766e..757f8ea932c 100644
--- a/sonar-plugin-api/src/main/java/org/sonar/api/server/ws/internal/SimpleGetRequest.java
+++ b/sonar-plugin-api/src/main/java/org/sonar/api/server/ws/internal/SimpleGetRequest.java
@@ -19,12 +19,13 @@
*/
package org.sonar.api.server.ws.internal;
-import com.google.common.base.Splitter;
import java.io.InputStream;
+import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
+import java.util.stream.Collectors;
import javax.annotation.CheckForNull;
import javax.annotation.Nullable;
import org.apache.commons.io.IOUtils;
@@ -89,7 +90,8 @@ public class SimpleGetRequest extends Request {
if (value == null) {
return null;
}
- return Splitter.on(',').omitEmptyStrings().trimResults().splitToList(value);
+
+ return Arrays.stream(value.split(",")).map(String::trim).filter(x -> !x.isEmpty()).collect(Collectors.toList());
}
@Override
diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/server/ws/internal/ValidatingRequest.java b/sonar-plugin-api/src/main/java/org/sonar/api/server/ws/internal/ValidatingRequest.java
index e120e7c3832..5a9ee977497 100644
--- a/sonar-plugin-api/src/main/java/org/sonar/api/server/ws/internal/ValidatingRequest.java
+++ b/sonar-plugin-api/src/main/java/org/sonar/api/server/ws/internal/ValidatingRequest.java
@@ -19,9 +19,8 @@
*/
package org.sonar.api.server.ws.internal;
-import com.google.common.base.CharMatcher;
-import com.google.common.base.Splitter;
import java.io.InputStream;
+import java.util.Arrays;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;
@@ -31,19 +30,19 @@ import org.sonar.api.server.ws.LocalConnector;
import org.sonar.api.server.ws.Request;
import org.sonar.api.server.ws.WebService;
-import static com.google.common.base.Preconditions.checkArgument;
import static java.lang.String.format;
import static java.util.Collections.emptyList;
import static java.util.Collections.singletonList;
import static java.util.Objects.requireNonNull;
import static org.apache.commons.lang.StringUtils.defaultString;
+import static org.sonar.api.utils.Preconditions.checkArgument;
/**
* @since 4.2
*/
public abstract class ValidatingRequest extends Request {
- private static final Splitter COMMA_SPLITTER = Splitter.on(',').omitEmptyStrings().trimResults();
+ private static final String COMMA_SPLITTER = ",";
private WebService.Action action;
private LocalConnector localConnector;
@@ -69,10 +68,9 @@ public abstract class ValidatingRequest extends Request {
@CheckForNull
public String param(String key) {
WebService.Param definition = action.param(key);
-
String rawValue = readParam(key, definition);
String rawValueOrDefault = defaultString(rawValue, definition.defaultValue());
- String value = rawValueOrDefault == null ? null : CharMatcher.WHITESPACE.trimFrom(rawValueOrDefault);
+ String value = rawValueOrDefault == null ? null : trim(rawValueOrDefault);
validateRequiredValue(key, definition, rawValue);
if (value == null) {
return null;
@@ -91,6 +89,23 @@ public abstract class ValidatingRequest extends Request {
return validateValues(values, definition);
}
+ private static String trim(String s) {
+ int begin;
+ for (begin = 0; begin < s.length(); begin++) {
+ if (!Character.isWhitespace(s.charAt(begin))) {
+ break;
+ }
+ }
+
+ int end;
+ for (end = s.length(); end > begin; end--) {
+ if (!Character.isWhitespace(s.charAt(end - 1))) {
+ break;
+ }
+ }
+ return s.substring(begin, end);
+ }
+
@Override
@CheckForNull
public InputStream paramAsInputStream(String key) {
@@ -111,7 +126,10 @@ public abstract class ValidatingRequest extends Request {
if (value == null) {
return null;
}
- List<String> values = COMMA_SPLITTER.splitToList(value);
+ List<String> values = Arrays.stream(value.split(COMMA_SPLITTER))
+ .map(String::trim)
+ .filter(s -> !s.isEmpty())
+ .collect(Collectors.toList());
return validateValues(values, definition);
}
@@ -123,6 +141,7 @@ public abstract class ValidatingRequest extends Request {
return null;
}
return values.stream()
+ .filter(s -> !s.isEmpty())
.map(value -> Enum.valueOf(enumClass, value))
.collect(Collectors.toList());
}
diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/task/TaskDefinition.java b/sonar-plugin-api/src/main/java/org/sonar/api/task/TaskDefinition.java
index 06f781bf264..63dd06c6149 100644
--- a/sonar-plugin-api/src/main/java/org/sonar/api/task/TaskDefinition.java
+++ b/sonar-plugin-api/src/main/java/org/sonar/api/task/TaskDefinition.java
@@ -19,13 +19,14 @@
*/
package org.sonar.api.task;
-import com.google.common.base.Preconditions;
import java.util.regex.Pattern;
import org.apache.commons.lang.StringUtils;
import org.sonar.api.ExtensionPoint;
import org.sonar.api.batch.InstantiationStrategy;
import org.sonar.api.batch.ScannerSide;
+import static org.sonar.api.utils.Preconditions.checkArgument;
+
/**
* Register and describe a {@link TaskExtension}.
*
@@ -117,10 +118,10 @@ public class TaskDefinition implements Comparable<TaskDefinition> {
}
public TaskDefinition build() {
- Preconditions.checkArgument(!StringUtils.isEmpty(key), "Task key must be set");
- Preconditions.checkArgument(Pattern.matches(KEY_PATTERN, key), "Task key '" + key + "' must match " + KEY_PATTERN);
- Preconditions.checkArgument(!StringUtils.isEmpty(description), "Description must be set for task '" + key + "'");
- Preconditions.checkArgument(taskClass != null, "Class must be set for task '" + key + "'");
+ checkArgument(!StringUtils.isEmpty(key), "Task key must be set");
+ checkArgument(Pattern.matches(KEY_PATTERN, key), "Task key '" + key + "' must match " + KEY_PATTERN);
+ checkArgument(!StringUtils.isEmpty(description), "Description must be set for task '" + key + "'");
+ checkArgument(taskClass != null, "Class must be set for task '" + key + "'");
return new TaskDefinition(this);
}
}
diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/user/UserGroupValidation.java b/sonar-plugin-api/src/main/java/org/sonar/api/user/UserGroupValidation.java
index 8a12f28269c..532ddf6b3c6 100644
--- a/sonar-plugin-api/src/main/java/org/sonar/api/user/UserGroupValidation.java
+++ b/sonar-plugin-api/src/main/java/org/sonar/api/user/UserGroupValidation.java
@@ -22,7 +22,7 @@ package org.sonar.api.user;
import org.apache.commons.lang.StringUtils;
import org.sonar.api.security.DefaultGroups;
-import static com.google.common.base.Preconditions.checkArgument;
+import static org.sonar.api.utils.Preconditions.checkArgument;
public class UserGroupValidation {
diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/utils/DateUtils.java b/sonar-plugin-api/src/main/java/org/sonar/api/utils/DateUtils.java
index aa9a8bea943..82fb609df83 100644
--- a/sonar-plugin-api/src/main/java/org/sonar/api/utils/DateUtils.java
+++ b/sonar-plugin-api/src/main/java/org/sonar/api/utils/DateUtils.java
@@ -30,7 +30,7 @@ import java.util.Date;
import javax.annotation.CheckForNull;
import javax.annotation.Nullable;
-import static com.google.common.base.Preconditions.checkArgument;
+import static org.sonar.api.utils.Preconditions.checkArgument;
/**
* Parses and formats <a href="https://docs.oracle.com/javase/8/docs/api/java/text/SimpleDateFormat.html#rfc822timezone">RFC 822</a> dates.
diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/utils/Paging.java b/sonar-plugin-api/src/main/java/org/sonar/api/utils/Paging.java
index 39760f3d88a..2eb9d44e310 100644
--- a/sonar-plugin-api/src/main/java/org/sonar/api/utils/Paging.java
+++ b/sonar-plugin-api/src/main/java/org/sonar/api/utils/Paging.java
@@ -19,7 +19,7 @@
*/
package org.sonar.api.utils;
-import static com.google.common.base.Preconditions.checkArgument;
+import static org.sonar.api.utils.Preconditions.checkArgument;
/**
* @since 3.6
diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/measures/MultisetDistributionFormat.java b/sonar-plugin-api/src/main/java/org/sonar/api/utils/Preconditions.java
index a65140eb491..1a70241d869 100644
--- a/sonar-plugin-api/src/main/java/org/sonar/api/measures/MultisetDistributionFormat.java
+++ b/sonar-plugin-api/src/main/java/org/sonar/api/utils/Preconditions.java
@@ -17,34 +17,36 @@
* 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.measures;
+package org.sonar.api.utils;
-import com.google.common.collect.Multiset;
-import org.sonar.api.utils.KeyValueFormat;
+public class Preconditions {
+ public static void checkArgument(boolean condition, String message) {
+ if (!condition) {
+ throw new IllegalArgumentException(message);
+ }
+ }
-/**
- * Format internal {@link com.google.common.collect.Multiset} of {@link CountDistributionBuilder}
- * and {@link RangeDistributionBuilder}
- */
-class MultisetDistributionFormat {
+ public static void checkArgument(boolean condition) {
+ if (!condition) {
+ throw new IllegalArgumentException();
+ }
+ }
- private MultisetDistributionFormat() {
- // only statics
+ public static void checkArgument(boolean condition, String format, Object... args) {
+ if (!condition) {
+ throw new IllegalArgumentException(String.format(format, args));
+ }
+ }
+
+ public static void checkState(boolean condition, String message) {
+ if (!condition) {
+ throw new IllegalStateException(message);
+ }
}
- static String format(Multiset countBag) {
- StringBuilder sb = new StringBuilder();
- boolean first = true;
- for (Object obj : countBag.elementSet()) {
- if (!first) {
- sb.append(KeyValueFormat.PAIR_SEPARATOR);
- }
- sb.append(obj.toString());
- sb.append(KeyValueFormat.FIELD_SEPARATOR);
- // -1 allows to include zero values
- sb.append(countBag.count(obj) - 1);
- first = false;
+ public static void checkState(boolean condition, String format, Object... args) {
+ if (!condition) {
+ throw new IllegalStateException(String.format(format, args));
}
- return sb.toString();
}
}
diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/utils/UriReader.java b/sonar-plugin-api/src/main/java/org/sonar/api/utils/UriReader.java
index 920ec7543ac..e190a78c29f 100644
--- a/sonar-plugin-api/src/main/java/org/sonar/api/utils/UriReader.java
+++ b/sonar-plugin-api/src/main/java/org/sonar/api/utils/UriReader.java
@@ -19,20 +19,19 @@
*/
package org.sonar.api.utils;
-import com.google.common.base.Preconditions;
-import com.google.common.base.Throwables;
-import com.google.common.io.Files;
import java.io.File;
import java.io.IOException;
import java.net.URI;
import java.nio.charset.Charset;
+import java.nio.file.Files;
+import java.nio.file.Paths;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Locale;
import java.util.Map;
import java.util.stream.Stream;
-import org.sonar.api.scanner.ScannerSide;
import org.sonar.api.ce.ComputeEngineSide;
+import org.sonar.api.scanner.ScannerSide;
import org.sonar.api.server.ServerSide;
/**
@@ -103,24 +102,24 @@ public class UriReader {
@Override
public String[] getSupportedSchemes() {
- return new String[]{"file"};
+ return new String[] {"file"};
}
@Override
protected byte[] readBytes(URI uri) {
try {
- return Files.toByteArray(new File(uri));
+ return Files.readAllBytes(Paths.get(uri));
} catch (IOException e) {
- throw Throwables.propagate(e);
+ throw new RuntimeException(e);
}
}
@Override
protected String readString(URI uri, Charset charset) {
try {
- return Files.toString(new File(uri), charset);
+ return new String(Files.readAllBytes(Paths.get(uri)), charset);
} catch (IOException e) {
- throw Throwables.propagate(e);
+ throw new RuntimeException(e);
}
}
diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/utils/Version.java b/sonar-plugin-api/src/main/java/org/sonar/api/utils/Version.java
index 69823aeda21..ab5acd9ca4b 100644
--- a/sonar-plugin-api/src/main/java/org/sonar/api/utils/Version.java
+++ b/sonar-plugin-api/src/main/java/org/sonar/api/utils/Version.java
@@ -19,8 +19,7 @@
*/
package org.sonar.api.utils;
-import com.google.common.base.Splitter;
-import java.util.List;
+import java.util.regex.Pattern;
import javax.annotation.concurrent.Immutable;
import static java.lang.Integer.parseInt;
@@ -53,8 +52,7 @@ public class Version implements Comparable<Version> {
private static final int DEFAULT_PATCH = 0;
private static final String DEFAULT_QUALIFIER = "";
private static final String QUALIFIER_SEPARATOR = "-";
- private static final char SEQUENCE_SEPARATOR = '.';
- private static final Splitter SEQUENCE_SPLITTER = Splitter.on(SEQUENCE_SEPARATOR);
+ private static final String SEQUENCE_SEPARATOR = ".";
private final int major;
private final int minor;
@@ -85,6 +83,7 @@ public class Version implements Comparable<Version> {
/**
* Build number if the fourth field, for example {@code 12345} for "6.3.0.12345".
* If absent, then value is zero.
+ *
* @since 6.3
*/
public long buildNumber() {
@@ -101,19 +100,19 @@ public class Version implements Comparable<Version> {
/**
* Convert a {@link String} to a Version. Supported formats:
* <ul>
- * <li>1</li>
- * <li>1.2</li>
- * <li>1.2.3</li>
- * <li>1-beta-1</li>
- * <li>1.2-beta-1</li>
- * <li>1.2.3-beta-1</li>
- * <li>1.2.3.4567</li>
- * <li>1.2.3.4567-beta-1</li>
+ * <li>1</li>
+ * <li>1.2</li>
+ * <li>1.2.3</li>
+ * <li>1-beta-1</li>
+ * <li>1.2-beta-1</li>
+ * <li>1.2.3-beta-1</li>
+ * <li>1.2.3.4567</li>
+ * <li>1.2.3.4567-beta-1</li>
* </ul>
* Note that the optional qualifier is the part after the first "-".
*
* @throws IllegalArgumentException if parameter is badly formatted, for example
- * if it defines 5 integer-sequences.
+ * if it defines 5 integer-sequences.
*/
public static Version parse(String text) {
String s = trimToEmpty(text);
@@ -121,20 +120,20 @@ public class Version implements Comparable<Version> {
if (!qualifier.isEmpty()) {
s = substringBefore(s, QUALIFIER_SEPARATOR);
}
- List<String> fields = SEQUENCE_SPLITTER.splitToList(s);
+ String[] fields = s.split(Pattern.quote(SEQUENCE_SEPARATOR));
int major = 0;
int minor = 0;
int patch = DEFAULT_PATCH;
long buildNumber = DEFAULT_BUILD_NUMBER;
- int size = fields.size();
+ int size = fields.length;
if (size > 0) {
- major = parseFieldAsInt(fields.get(0));
+ major = parseFieldAsInt(fields[0]);
if (size > 1) {
- minor = parseFieldAsInt(fields.get(1));
+ minor = parseFieldAsInt(fields[1]);
if (size > 2) {
- patch = parseFieldAsInt(fields.get(2));
+ patch = parseFieldAsInt(fields[2]);
if (size > 3) {
- buildNumber = parseFieldAsLong(fields.get(3));
+ buildNumber = parseFieldAsLong(fields[3]);
if (size > 4) {
throw new IllegalArgumentException("Maximum 4 fields are accepted: " + text);
}
diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/utils/command/Command.java b/sonar-plugin-api/src/main/java/org/sonar/api/utils/command/Command.java
index d8e2713facc..a8eed2a6f7a 100644
--- a/sonar-plugin-api/src/main/java/org/sonar/api/utils/command/Command.java
+++ b/sonar-plugin-api/src/main/java/org/sonar/api/utils/command/Command.java
@@ -19,8 +19,6 @@
*/
package org.sonar.api.utils.command;
-import com.google.common.base.Joiner;
-import com.google.common.base.Preconditions;
import java.io.File;
import java.util.ArrayList;
import java.util.Collections;
@@ -32,6 +30,7 @@ import org.sonar.api.utils.System2;
import static java.util.Collections.unmodifiableList;
import static java.util.Collections.unmodifiableMap;
+import static org.sonar.api.utils.Preconditions.checkArgument;
/**
* @since 2.7
@@ -46,7 +45,7 @@ public class Command {
private final System2 system;
Command(String executable, System2 system) {
- Preconditions.checkArgument(!StringUtils.isBlank(executable), "Command executable can not be blank");
+ checkArgument(!StringUtils.isBlank(executable), "Command executable can not be blank");
this.executable = executable;
this.env = new HashMap<>(system.envVariables());
this.system = system;
@@ -138,7 +137,6 @@ public class Command {
/**
* Set to <code>true</code> if a new shell should be used to execute the command.
* This is useful when the executed command is a script with no execution rights (+x on unix).
- *
* On windows, the command will be executed with <code>cmd /C executable</code>.
* On other platforms, the command will be executed with <code>sh executable</code>.
*
@@ -166,11 +164,11 @@ public class Command {
}
public String toCommandLine() {
- return Joiner.on(" ").join(toStrings(false));
+ return String.join(" ", toStrings(false));
}
@Override
public String toString() {
- return Joiner.on(" ").join(toStrings(true));
+ return String.join(" ", toStrings(true));
}
}
diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/utils/internal/AlwaysIncreasingSystem2.java b/sonar-plugin-api/src/main/java/org/sonar/api/utils/internal/AlwaysIncreasingSystem2.java
index 5044da2ab0c..35334080778 100644
--- a/sonar-plugin-api/src/main/java/org/sonar/api/utils/internal/AlwaysIncreasingSystem2.java
+++ b/sonar-plugin-api/src/main/java/org/sonar/api/utils/internal/AlwaysIncreasingSystem2.java
@@ -24,7 +24,7 @@ import java.util.concurrent.atomic.AtomicLong;
import java.util.function.Supplier;
import org.sonar.api.utils.System2;
-import static com.google.common.base.Preconditions.checkArgument;
+import static org.sonar.api.utils.Preconditions.checkArgument;
/**
* A subclass of {@link System2} which implementation of {@link System2#now()} always return a bigger value than the
diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/utils/log/LogInterceptors.java b/sonar-plugin-api/src/main/java/org/sonar/api/utils/log/LogInterceptors.java
index 7c69e871c49..ff2ba8f901b 100644
--- a/sonar-plugin-api/src/main/java/org/sonar/api/utils/log/LogInterceptors.java
+++ b/sonar-plugin-api/src/main/java/org/sonar/api/utils/log/LogInterceptors.java
@@ -19,7 +19,7 @@
*/
package org.sonar.api.utils.log;
-import com.google.common.base.Preconditions;
+import static org.sonar.api.utils.Preconditions.checkArgument;
class LogInterceptors {
@@ -33,7 +33,7 @@ class LogInterceptors {
}
static void set(LogInterceptor li) {
- Preconditions.checkArgument(li != null);
+ checkArgument(li != null);
instance = li;
}
}
diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/web/Dashboard.java b/sonar-plugin-api/src/main/java/org/sonar/api/web/Dashboard.java
index 3d95ed5d99d..cdb095f0e1c 100644
--- a/sonar-plugin-api/src/main/java/org/sonar/api/web/Dashboard.java
+++ b/sonar-plugin-api/src/main/java/org/sonar/api/web/Dashboard.java
@@ -19,12 +19,12 @@
*/
package org.sonar.api.web;
-import com.google.common.collect.ArrayListMultimap;
-import com.google.common.collect.ListMultimap;
+import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
+import java.util.stream.Collectors;
/**
* Definition of a dashboard.
@@ -40,7 +40,7 @@ public final class Dashboard {
private String description;
private DashboardLayout layout = DashboardLayout.TWO_COLUMNS;
- private ListMultimap<Integer, Widget> widgetsByColumn = ArrayListMultimap.create();
+ private Map<Integer, List<Widget>> widgetsByColumn = new HashMap<>();
private boolean activated = true;
private boolean global = false;
@@ -56,7 +56,6 @@ public final class Dashboard {
/**
* Add a widget with the given parameters, and return the newly created {@link Widget} object if one wants to add parameters to it.
- *
* <p>The widget ids are listed by the web service /api/widgets
*
* @param widgetId id of an existing widget
@@ -68,12 +67,12 @@ public final class Dashboard {
}
Widget widget = new Widget(widgetId);
- widgetsByColumn.put(columnId, widget);
+ widgetsByColumn.computeIfAbsent(columnId, x -> new ArrayList<>()).add(widget);
return widget;
}
public Collection<Widget> getWidgets() {
- return widgetsByColumn.values();
+ return widgetsByColumn.values().stream().flatMap(List::stream).collect(Collectors.toList());
}
public List<Widget> getWidgetsOfColumn(int columnId) {
diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/web/ServletFilter.java b/sonar-plugin-api/src/main/java/org/sonar/api/web/ServletFilter.java
index d1ca30eea26..eb1fc0e8149 100644
--- a/sonar-plugin-api/src/main/java/org/sonar/api/web/ServletFilter.java
+++ b/sonar-plugin-api/src/main/java/org/sonar/api/web/ServletFilter.java
@@ -32,10 +32,10 @@ import javax.servlet.Filter;
import org.sonar.api.ExtensionPoint;
import org.sonar.api.server.ServerSide;
-import static com.google.common.base.Preconditions.checkArgument;
import static java.util.Arrays.asList;
import static java.util.Collections.unmodifiableList;
import static org.apache.commons.lang.StringUtils.substringBeforeLast;
+import static org.sonar.api.utils.Preconditions.checkArgument;
/**
* @since 3.1
diff --git a/sonar-plugin-api/src/test/java/org/sonar/api/batch/sensor/internal/SensorContextTesterTest.java b/sonar-plugin-api/src/test/java/org/sonar/api/batch/sensor/internal/SensorContextTesterTest.java
index 2defae48754..493d7133cfd 100644
--- a/sonar-plugin-api/src/test/java/org/sonar/api/batch/sensor/internal/SensorContextTesterTest.java
+++ b/sonar-plugin-api/src/test/java/org/sonar/api/batch/sensor/internal/SensorContextTesterTest.java
@@ -26,7 +26,6 @@ import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ExpectedException;
import org.junit.rules.TemporaryFolder;
-import org.mockito.Mockito;
import org.sonar.api.batch.bootstrap.ProjectDefinition;
import org.sonar.api.batch.fs.InputFile;
import org.sonar.api.batch.fs.internal.DefaultFileSystem;
@@ -53,8 +52,6 @@ import org.sonar.api.rules.RuleType;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.tuple;
import static org.assertj.core.data.MapEntry.entry;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.when;
public class SensorContextTesterTest {
diff --git a/sonar-plugin-api/src/test/java/org/sonar/api/server/rule/RuleTagsToTypeConverterTest.java b/sonar-plugin-api/src/test/java/org/sonar/api/server/rule/RuleTagsToTypeConverterTest.java
index 34c199020ec..ac20d1742d6 100644
--- a/sonar-plugin-api/src/test/java/org/sonar/api/server/rule/RuleTagsToTypeConverterTest.java
+++ b/sonar-plugin-api/src/test/java/org/sonar/api/server/rule/RuleTagsToTypeConverterTest.java
@@ -22,7 +22,7 @@ package org.sonar.api.server.rule;
import java.util.Collections;
import org.junit.Test;
import org.sonar.api.rules.RuleType;
-import org.sonar.test.TestUtils;
+import org.sonar.api.utils.TestUtils;
import static java.util.Arrays.asList;
import static org.assertj.core.api.Assertions.assertThat;
diff --git a/sonar-plugin-api/src/test/java/org/sonar/api/server/rule/RulesDefinitionXmlLoaderTest.java b/sonar-plugin-api/src/test/java/org/sonar/api/server/rule/RulesDefinitionXmlLoaderTest.java
index 5c0bef70f42..61111aa3847 100644
--- a/sonar-plugin-api/src/test/java/org/sonar/api/server/rule/RulesDefinitionXmlLoaderTest.java
+++ b/sonar-plugin-api/src/test/java/org/sonar/api/server/rule/RulesDefinitionXmlLoaderTest.java
@@ -32,7 +32,7 @@ import org.sonar.api.rules.RuleType;
import org.sonar.api.server.debt.DebtRemediationFunction;
import static org.assertj.core.api.Assertions.assertThat;
-import static org.sonar.test.ExceptionCauseMatcher.hasType;
+import static org.sonar.api.utils.ExceptionCauseMatcher.hasType;
public class RulesDefinitionXmlLoaderTest {
diff --git a/sonar-plugin-api/src/test/java/org/sonar/api/utils/ExceptionCauseMatcher.java b/sonar-plugin-api/src/test/java/org/sonar/api/utils/ExceptionCauseMatcher.java
new file mode 100644
index 00000000000..dd4659ea175
--- /dev/null
+++ b/sonar-plugin-api/src/test/java/org/sonar/api/utils/ExceptionCauseMatcher.java
@@ -0,0 +1,91 @@
+/*
+ * 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.utils;
+
+import java.util.Objects;
+import javax.annotation.CheckForNull;
+import javax.annotation.Nullable;
+import javax.annotation.concurrent.Immutable;
+import org.hamcrest.Description;
+import org.hamcrest.Matcher;
+import org.hamcrest.TypeSafeMatcher;
+
+/**
+ * Matchers designed to be used as an argument of {@link org.junit.rules.ExpectedException#expectCause(Matcher)} such as:
+ *
+ * <pre>
+ * expectedException.expect(VisitException.class);
+ * expectedException.expectCause(hasType(IllegalArgumentException.class).andMessage("file and otherFile Components can not be the same"));
+ * </pre>
+ *
+ * Class strongly inspired from {@code CauseMatcher} class from {@code http://blog.codeleak.pl/2014/03/junit-expectedexception-rule-beyond.html}
+ */
+@Immutable
+public class ExceptionCauseMatcher extends TypeSafeMatcher<Throwable> {
+ private static final String EXPECT_NO_MESSAGE_CONSTANT = "RQXG8QTUCXOT7HZ3APPKBKUE5";
+
+ private final Class<? extends Throwable> type;
+ @CheckForNull
+ private final String expectedMessage;
+
+ private ExceptionCauseMatcher(Class<? extends Throwable> type, @Nullable String expectedMessage) {
+ this.type = type;
+ this.expectedMessage = expectedMessage;
+ }
+
+ public static ExceptionCauseMatcher hasType(Class<? extends Throwable> type) {
+ return new ExceptionCauseMatcher(type, null);
+ }
+
+ public ExceptionCauseMatcher andMessage(String expectedMessage) {
+ return new ExceptionCauseMatcher(type, Objects.requireNonNull(expectedMessage));
+ }
+
+ public ExceptionCauseMatcher andNoMessage() {
+ return new ExceptionCauseMatcher(type, EXPECT_NO_MESSAGE_CONSTANT);
+ }
+
+ @Override
+ protected boolean matchesSafely(Throwable item) {
+ if (!type.isAssignableFrom(item.getClass())) {
+ return false;
+ }
+ if (expectedMessage == null) {
+ return true;
+ }
+ if (EXPECT_NO_MESSAGE_CONSTANT.equals(expectedMessage)) {
+ return item.getMessage() == null;
+ }
+ return item.getMessage().contains(expectedMessage);
+ }
+
+ @Override
+ public void describeTo(Description description) {
+ description.appendText("of type ")
+ .appendValue(type);
+ if (EXPECT_NO_MESSAGE_CONSTANT.equals(expectedMessage)) {
+ description.appendText(" and no message");
+ } else if (expectedMessage != null) {
+ description.appendText(" and message ")
+ .appendValue(expectedMessage);
+ }
+ description.appendText(" but");
+ }
+}
diff --git a/sonar-plugin-api/src/test/java/org/sonar/api/utils/KeyValueFormatTest.java b/sonar-plugin-api/src/test/java/org/sonar/api/utils/KeyValueFormatTest.java
index 8b33f98db60..25b86dc8f9a 100644
--- a/sonar-plugin-api/src/test/java/org/sonar/api/utils/KeyValueFormatTest.java
+++ b/sonar-plugin-api/src/test/java/org/sonar/api/utils/KeyValueFormatTest.java
@@ -28,7 +28,6 @@ import java.util.Map;
import java.util.TreeMap;
import org.junit.Test;
import org.sonar.api.rules.RulePriority;
-import org.sonar.test.TestUtils;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.entry;
@@ -36,7 +35,7 @@ import static org.assertj.core.api.Assertions.entry;
public class KeyValueFormatTest {
@Test
- public void test_parser() throws Exception {
+ public void test_parser() {
KeyValueFormat.FieldParser reader = new KeyValueFormat.FieldParser("abc=def;ghi=jkl");
assertThat(reader.nextKey()).isEqualTo("abc");
assertThat(reader.nextVal()).isEqualTo("def");
diff --git a/sonar-plugin-api/src/test/java/org/sonar/api/utils/PathUtilsTest.java b/sonar-plugin-api/src/test/java/org/sonar/api/utils/PathUtilsTest.java
index 80371dc5aa2..ccf21a2e713 100644
--- a/sonar-plugin-api/src/test/java/org/sonar/api/utils/PathUtilsTest.java
+++ b/sonar-plugin-api/src/test/java/org/sonar/api/utils/PathUtilsTest.java
@@ -19,15 +19,13 @@
*/
package org.sonar.api.utils;
+import java.io.File;
+import java.io.IOException;
import org.apache.commons.io.FilenameUtils;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.TemporaryFolder;
-import java.io.File;
-import java.io.IOException;
-import org.sonar.test.TestUtils;
-
import static org.assertj.core.api.Assertions.assertThat;
import static org.junit.Assert.fail;
import static org.mockito.Mockito.mock;
diff --git a/sonar-plugin-api/src/test/java/org/sonar/api/utils/TestUtils.java b/sonar-plugin-api/src/test/java/org/sonar/api/utils/TestUtils.java
new file mode 100644
index 00000000000..3d83da239e5
--- /dev/null
+++ b/sonar-plugin-api/src/test/java/org/sonar/api/utils/TestUtils.java
@@ -0,0 +1,55 @@
+/*
+ * 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.utils;
+
+import java.lang.reflect.Constructor;
+import java.lang.reflect.Modifier;
+
+/**
+ * Utilities for unit tests
+ *
+ * @since 2.2
+ */
+public final class TestUtils {
+
+ private TestUtils() {
+ }
+
+ /**
+ * Asserts that all constructors are private, usually for helper classes with
+ * only static methods. If a constructor does not have any parameters, then
+ * it's instantiated.
+ */
+ public static boolean hasOnlyPrivateConstructors(Class clazz) {
+ boolean ok = true;
+ for (Constructor constructor : clazz.getDeclaredConstructors()) {
+ ok &= Modifier.isPrivate(constructor.getModifiers());
+ if (constructor.getParameterTypes().length == 0) {
+ constructor.setAccessible(true);
+ try {
+ constructor.newInstance();
+ } catch (Exception e) {
+ throw new IllegalStateException(String.format("Fail to instantiate %s", clazz), e);
+ }
+ }
+ }
+ return ok;
+ }
+}
diff --git a/sonar-plugin-api/src/test/java/org/sonar/api/utils/command/CommandExecutorTest.java b/sonar-plugin-api/src/test/java/org/sonar/api/utils/command/CommandExecutorTest.java
index e08477d66e1..77a5ab3890c 100644
--- a/sonar-plugin-api/src/test/java/org/sonar/api/utils/command/CommandExecutorTest.java
+++ b/sonar-plugin-api/src/test/java/org/sonar/api/utils/command/CommandExecutorTest.java
@@ -56,18 +56,10 @@ public class CommandExecutorTest {
public void should_consume_StdOut_and_StdErr() throws Exception {
// too many false-positives on MS windows
if (!SystemUtils.IS_OS_WINDOWS) {
- final StringBuilder stdOutBuilder = new StringBuilder();
- StreamConsumer stdOutConsumer = new StreamConsumer() {
- public void consumeLine(String line) {
- stdOutBuilder.append(line).append(SystemUtils.LINE_SEPARATOR);
- }
- };
- final StringBuilder stdErrBuilder = new StringBuilder();
- StreamConsumer stdErrConsumer = new StreamConsumer() {
- public void consumeLine(String line) {
- stdErrBuilder.append(line).append(SystemUtils.LINE_SEPARATOR);
- }
- };
+ StringBuilder stdOutBuilder = new StringBuilder();
+ StreamConsumer stdOutConsumer = line -> stdOutBuilder.append(line).append(SystemUtils.LINE_SEPARATOR);
+ StringBuilder stdErrBuilder = new StringBuilder();
+ StreamConsumer stdErrConsumer = line -> stdErrBuilder.append(line).append(SystemUtils.LINE_SEPARATOR);
Command command = Command.create(getScript("output")).setDirectory(workDir);
int exitCode = CommandExecutor.create().execute(command, stdOutConsumer, stdErrConsumer, 1000L);
assertThat(exitCode).isEqualTo(0);
@@ -97,16 +89,11 @@ public class CommandExecutorTest {
CommandExecutor.create().execute(command, NOP_CONSUMER, BAD_CONSUMER, 1500L);
}
- private static final StreamConsumer NOP_CONSUMER = new StreamConsumer() {
- public void consumeLine(String line) {
- // nop
- }
+ private static final StreamConsumer NOP_CONSUMER = line -> {
};
- private static final StreamConsumer BAD_CONSUMER = new StreamConsumer() {
- public void consumeLine(String line) {
- throw new RuntimeException();
- }
+ private static final StreamConsumer BAD_CONSUMER = line -> {
+ throw new RuntimeException();
};
@Test
@@ -129,7 +116,7 @@ public class CommandExecutorTest {
public void should_stop_after_timeout() throws IOException {
try {
String executable = getScript("forever");
- CommandExecutor.create().execute(Command.create(executable).setDirectory(workDir), 1000L);
+ CommandExecutor.create().execute(Command.create(executable).setDirectory(workDir), 100);
fail();
} catch (TimeoutException e) {
// ok
@@ -140,7 +127,7 @@ public class CommandExecutorTest {
public void should_stop_after_timeout_and_new_shell() throws IOException {
try {
String executable = getScript("forever");
- CommandExecutor.create().execute(Command.create(executable).setNewShell(true).setDirectory(workDir), 1000L);
+ CommandExecutor.create().execute(Command.create(executable).setNewShell(true).setDirectory(workDir), 100);
fail();
} catch (TimeoutException e) {
// ok
diff --git a/sonar-plugin-api/src/test/java/org/sonar/api/utils/log/ConsoleFormatterTest.java b/sonar-plugin-api/src/test/java/org/sonar/api/utils/log/ConsoleFormatterTest.java
index 412a6fe52d5..b25ac2e93a2 100644
--- a/sonar-plugin-api/src/test/java/org/sonar/api/utils/log/ConsoleFormatterTest.java
+++ b/sonar-plugin-api/src/test/java/org/sonar/api/utils/log/ConsoleFormatterTest.java
@@ -20,7 +20,7 @@
package org.sonar.api.utils.log;
import org.junit.Test;
-import org.sonar.test.TestUtils;
+import org.sonar.api.utils.TestUtils;
import static org.assertj.core.api.Assertions.assertThat;
diff --git a/sonar-plugin-api/src/test/java/org/sonar/api/utils/log/LogInterceptorsTest.java b/sonar-plugin-api/src/test/java/org/sonar/api/utils/log/LogInterceptorsTest.java
index e15f2ef0334..5dd0b4cff2b 100644
--- a/sonar-plugin-api/src/test/java/org/sonar/api/utils/log/LogInterceptorsTest.java
+++ b/sonar-plugin-api/src/test/java/org/sonar/api/utils/log/LogInterceptorsTest.java
@@ -20,7 +20,7 @@
package org.sonar.api.utils.log;
import org.junit.Test;
-import org.sonar.test.TestUtils;
+import org.sonar.api.utils.TestUtils;
import static org.assertj.core.api.Assertions.assertThat;