]> source.dussan.org Git - sonarqube.git/commitdiff
Remove use of Guava in main sources of sonar-plugin-api
authorDuarte Meneses <duarte.meneses@sonarsource.com>
Tue, 4 Jun 2019 13:24:54 +0000 (08:24 -0500)
committerSonarTech <sonartech@sonarsource.com>
Fri, 12 Jul 2019 18:21:13 +0000 (20:21 +0200)
74 files changed:
sonar-plugin-api/build.gradle
sonar-plugin-api/src/main/java/org/sonar/api/batch/fs/internal/DefaultFileSystem.java
sonar-plugin-api/src/main/java/org/sonar/api/batch/fs/internal/DefaultInputFile.java
sonar-plugin-api/src/main/java/org/sonar/api/batch/rule/internal/DefaultActiveRules.java
sonar-plugin-api/src/main/java/org/sonar/api/batch/rule/internal/DefaultRules.java
sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/code/internal/DefaultSignificantCode.java
sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/coverage/internal/DefaultCoverage.java
sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/cpd/internal/DefaultCpdTokens.java
sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/error/internal/DefaultAnalysisError.java
sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/highlighting/internal/DefaultHighlighting.java
sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/internal/DefaultStorable.java
sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/internal/InMemorySensorStorage.java
sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/internal/SensorContextTester.java
sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/issue/internal/AbstractDefaultIssue.java
sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/issue/internal/DefaultExternalIssue.java
sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/issue/internal/DefaultIssue.java
sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/issue/internal/DefaultIssueLocation.java
sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/measure/internal/DefaultMeasure.java
sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/rule/internal/DefaultAdHocRule.java
sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/symbol/internal/DefaultSymbolTable.java
sonar-plugin-api/src/main/java/org/sonar/api/ce/measure/RangeDistributionBuilder.java
sonar-plugin-api/src/main/java/org/sonar/api/ce/measure/test/TestComponent.java
sonar-plugin-api/src/main/java/org/sonar/api/ce/measure/test/TestIssue.java
sonar-plugin-api/src/main/java/org/sonar/api/ce/measure/test/TestMeasure.java
sonar-plugin-api/src/main/java/org/sonar/api/ce/measure/test/TestMeasureComputerContext.java
sonar-plugin-api/src/main/java/org/sonar/api/ce/measure/test/TestMeasureComputerDefinition.java
sonar-plugin-api/src/main/java/org/sonar/api/ce/posttask/PostProjectAnalysisTaskTester.java
sonar-plugin-api/src/main/java/org/sonar/api/config/PropertyDefinition.java
sonar-plugin-api/src/main/java/org/sonar/api/config/PropertyFieldDefinition.java
sonar-plugin-api/src/main/java/org/sonar/api/config/Settings.java
sonar-plugin-api/src/main/java/org/sonar/api/config/internal/MultivalueProperty.java
sonar-plugin-api/src/main/java/org/sonar/api/internal/MetadataLoader.java
sonar-plugin-api/src/main/java/org/sonar/api/internal/SonarRuntimeImpl.java
sonar-plugin-api/src/main/java/org/sonar/api/measures/Metric.java
sonar-plugin-api/src/main/java/org/sonar/api/measures/MultisetDistributionFormat.java [deleted file]
sonar-plugin-api/src/main/java/org/sonar/api/resources/AbstractLanguage.java
sonar-plugin-api/src/main/java/org/sonar/api/resources/ResourceType.java
sonar-plugin-api/src/main/java/org/sonar/api/resources/ResourceTypeTree.java
sonar-plugin-api/src/main/java/org/sonar/api/resources/ResourceTypes.java
sonar-plugin-api/src/main/java/org/sonar/api/rule/RuleKey.java
sonar-plugin-api/src/main/java/org/sonar/api/rules/AnnotationRuleParser.java
sonar-plugin-api/src/main/java/org/sonar/api/rules/Rule.java
sonar-plugin-api/src/main/java/org/sonar/api/rules/XMLRuleParser.java
sonar-plugin-api/src/main/java/org/sonar/api/server/authentication/Display.java
sonar-plugin-api/src/main/java/org/sonar/api/server/authentication/UserIdentity.java
sonar-plugin-api/src/main/java/org/sonar/api/server/debt/internal/DefaultDebtRemediationFunction.java
sonar-plugin-api/src/main/java/org/sonar/api/server/profile/BuiltInQualityProfilesDefinition.java
sonar-plugin-api/src/main/java/org/sonar/api/server/rule/RulesDefinition.java
sonar-plugin-api/src/main/java/org/sonar/api/server/ws/Request.java
sonar-plugin-api/src/main/java/org/sonar/api/server/ws/WebService.java
sonar-plugin-api/src/main/java/org/sonar/api/server/ws/internal/SimpleGetRequest.java
sonar-plugin-api/src/main/java/org/sonar/api/server/ws/internal/ValidatingRequest.java
sonar-plugin-api/src/main/java/org/sonar/api/task/TaskDefinition.java
sonar-plugin-api/src/main/java/org/sonar/api/user/UserGroupValidation.java
sonar-plugin-api/src/main/java/org/sonar/api/utils/DateUtils.java
sonar-plugin-api/src/main/java/org/sonar/api/utils/Paging.java
sonar-plugin-api/src/main/java/org/sonar/api/utils/Preconditions.java [new file with mode: 0644]
sonar-plugin-api/src/main/java/org/sonar/api/utils/UriReader.java
sonar-plugin-api/src/main/java/org/sonar/api/utils/Version.java
sonar-plugin-api/src/main/java/org/sonar/api/utils/command/Command.java
sonar-plugin-api/src/main/java/org/sonar/api/utils/internal/AlwaysIncreasingSystem2.java
sonar-plugin-api/src/main/java/org/sonar/api/utils/log/LogInterceptors.java
sonar-plugin-api/src/main/java/org/sonar/api/web/Dashboard.java
sonar-plugin-api/src/main/java/org/sonar/api/web/ServletFilter.java
sonar-plugin-api/src/test/java/org/sonar/api/batch/sensor/internal/SensorContextTesterTest.java
sonar-plugin-api/src/test/java/org/sonar/api/server/rule/RuleTagsToTypeConverterTest.java
sonar-plugin-api/src/test/java/org/sonar/api/server/rule/RulesDefinitionXmlLoaderTest.java
sonar-plugin-api/src/test/java/org/sonar/api/utils/ExceptionCauseMatcher.java [new file with mode: 0644]
sonar-plugin-api/src/test/java/org/sonar/api/utils/KeyValueFormatTest.java
sonar-plugin-api/src/test/java/org/sonar/api/utils/PathUtilsTest.java
sonar-plugin-api/src/test/java/org/sonar/api/utils/TestUtils.java [new file with mode: 0644]
sonar-plugin-api/src/test/java/org/sonar/api/utils/command/CommandExecutorTest.java
sonar-plugin-api/src/test/java/org/sonar/api/utils/log/ConsoleFormatterTest.java
sonar-plugin-api/src/test/java/org/sonar/api/utils/log/LogInterceptorsTest.java

index 08ed5c8e6c8f82c4674518d3990f732f7480a60c..3c2b3d3a0da992858051b3a4a4457698cf45cef2 100644 (file)
@@ -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 {
index a69479c6b110d64ae60102d1c87afe94dd9545b2..3b9b7ac22e93dbb8b157194ee8d424937be085d2 100644 (file)
  */
 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
index cf72686859d9124e7bfa20f284af11a6be9c7449..5dbcf99c541b1a91b279bdb9c27ee5aace1e3194 100644 (file)
@@ -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);
   }
index 732955e332e4dc263dfdc10198b6449e9bb4831d..845137acf609bf1aa2ed2ff8102566fb9caffe60 100644 (file)
  */
 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
index 048973a68919c3cbf24c0007350742112822c589..def001211e7063cd6c56c69cdb6d71a1b0773e90 100644 (file)
  */
 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());
   }
 }
index 830ce69db4062ad694d2263d26eae4d6b1f3fb9c..40ea16bd42b21755815b7cf5a22a3269d6696733 100644 (file)
@@ -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<>();
index d7546cae28de9da394aa28609ac7847f818dcc84..94fc18873611bb48b60e5af21b861a08a5477ef7 100644 (file)
@@ -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 {
 
index f6907ba68ba58f18dca155fcad870aeab0178feb..a2c592c37b58194f0328034e48561873b8295135 100644 (file)
@@ -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);
index a95838d903b9737a2735c5265bb86e4f6555b575..3a9073a5095baeb89601ae4d94dba66c3166fdaa 100644 (file)
@@ -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;
   }
index 20ee23ad2839d8525b964fd3c98fc77255392067..89dea63e1cf8547c1fa06899481bf9a46b149f2a 100644 (file)
@@ -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");
   }
 }
index 2b0684acfbb27dd1af718a0613b78a78b6933dcc..822ffbc2a400a8a86b09d70ab9357f8db8c51fbf 100644 (file)
  */
 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;
   }
index e14f8ab26c23a6a77b677a65b130bb2e082998e2..74b238c4b63840247798fecfa919bb430078111a 100644 (file)
  */
 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();
index edf595685d42fbdc549dfb3f873feea95dce22d3..70f5d5091318d93418dca929456ee166a987c888 100644 (file)
@@ -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)
index 39f01a319fca04734b82a9dea47ec1aaa7eda2c2..4f24641c57fcb459e273714ff16eaab8cbb2a1f7 100644 (file)
@@ -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());
index db1f22102ebf396c0673a8fef6686ed82c0594d2..c402d6bcc284e04646c913daa0fa5b5207efb8d7 100644 (file)
@@ -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;
   }
index 770562eb1d20ade45a7ec71513a14dc2acea9827..2f59ddd944ab867279d464de98cd5929e23a0562 100644 (file)
@@ -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;
   }
index 01f73c2a95475048fde800193442138fc3798b78..124e7876b3fb59242d6d40ade460fd764ac09723 100644 (file)
  */
 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;
index fd0bfaad581081ff15d6b9888a989f20b634f235..b359e2d20cd3024c76923ac9aa017eff8c54ac13 100644 (file)
@@ -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);
   }
 
index 8204ccc909f54120faa5a6d24b6deb5a38567ec8..7ccf8aef768a4e36c0044aca81a28df9f32afaa5 100644 (file)
@@ -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;
index 90f4daeb8baf9c01f3d5b08f03959ecb076636be..087681a5aa8c6894cd969095bd090b2a29f493f0 100644 (file)
@@ -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");
   }
 }
index 57548342ae4487199a47b1a8e525c5f00b3aef4b..09605d5ee670ab16684219484e867e1cf7982b66 100644 (file)
@@ -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) {
index 4cc799ec322d5b6cd75374b9eb09ae131c655b3f..9a698e8d4048e180f55a48c2055f0f0d3cfabf2b 100644 (file)
@@ -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 {
index f2b16910e0e0a1fe68266006b55700b54973a53c..1b8173fac8b5ada82ecbf63e5e18c3eb8893714c 100644 (file)
@@ -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 {
index 10299aae0e3168c116405cb85511221716437dbf..5454dce79e407410b712752b23586e3ab1a0e30a 100644 (file)
@@ -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 {
index 1489eb18fa5911ded594008a1c68747c6108179a..e8015be203164afb53b42f08fdcba071042b4a5d 100644 (file)
@@ -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));
     }
   }
 
index 8eec9324106ec8cf499de9fdd91d3a44cb2d93ee..a932efa6e0038658a3a6c1468b124fcd6227eb06 100644 (file)
@@ -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 {
 
index e50157cf9d0819fe5b284937a6e1e7d589d9b433..db4576c053d6cc4a900a2924c66e755328a26023 100644 (file)
@@ -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();
  *   }
  * }
index 611c28431ab7c4b08ebda29c0dcc0b2a6142c505..ce894f30de9753f9715f3302cae5b93735131edd 100644 (file)
@@ -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.
      */
index 61c0e5bb1dfc7205645e9766f500ba59129e307c..db1ad3822a37be565a47447e1792d8a7edbff36b 100644 (file)
@@ -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);
     }
   }
index 10f6cc90af6b020d3b97a4fe2232083d0a0c3ca5..b641d5ddca08203e8a6000c118535add1d97f921 100644 (file)
@@ -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) {
index bf0bb1b9e2073515f44dfc2bf3b4279e15731d65..dab98c557817ccbfee2116f9f2d6550e98676729 100644 (file)
@@ -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];
index d22a4ec2aa612b523518fbd27e327bd17feceb54..f104d0cef649bab4f3364f9ea6dd564e64f3e00d 100644 (file)
  */
 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);
     }
   }
index 6395546469f20e9eb3cbcc8db1ff7a1b1ed6aa0a..3f69f36bb4e37471b1238f7d557bacc854148843 100644 (file)
@@ -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
index f7e199ff592ed29016cd7017636f7c3997fc0131..ca5f062d66e1611485b86a4a699755631111cd12 100644 (file)
@@ -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/measures/MultisetDistributionFormat.java b/sonar-plugin-api/src/main/java/org/sonar/api/measures/MultisetDistributionFormat.java
deleted file mode 100644 (file)
index a65140e..0000000
+++ /dev/null
@@ -1,50 +0,0 @@
-/*
- * SonarQube
- * Copyright (C) 2009-2019 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
- */
-package org.sonar.api.measures;
-
-import com.google.common.collect.Multiset;
-import org.sonar.api.utils.KeyValueFormat;
-
-/**
- * Format internal {@link com.google.common.collect.Multiset} of {@link CountDistributionBuilder}
- * and {@link RangeDistributionBuilder}
- */
-class MultisetDistributionFormat {
-
-  private MultisetDistributionFormat() {
-    // only statics
-  }
-
-  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;
-    }
-    return sb.toString();
-  }
-}
index 4039fd7d76daebb9f04076dddd3c88af6a3ba767..f63df01346507a457a93fa15176733b0da26a661 100644 (file)
  */
 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;
   }
index 176bf939a4cec9eeff64edef2491fa4b54a2867b..a9a00ff5cb6a9cd909851363745fb9c54f4f8022 100644 (file)
@@ -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);
   }
 
index c747bab32b3c6ddd0dd3805c761c48e0db7739b7..d2e44fa8a913ca1bb21d3bc4ad370e5fb0144ed1 100644 (file)
  */
 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;
index 9a418c5445bbb5a7769f464e6449f45b3863dd7e..34ed696ca27482b8ed2fcc6289ad4144dbcd0181 100644 (file)
@@ -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 {
index f503dab866b60c5a4d73d4908ec29de20f20a0a3..2ac2f1f79f6b4f89472af19166c94894a338f1ff 100644 (file)
  */
 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) {
index 10f7878994fba664a1f50cf1adfe8d3367d2d618..5e69f1b054c82784b4fff43827becf0dc8d2b017 100644 (file)
  */
 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);
index b0f200b18ba218ff474cfc8b0753802ba8f6a887..2eb4d07f57d6000bc6d97d554bf2b997590a8b5f 100644 (file)
@@ -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) {
index 179fe5bff4a124acfb2f3b851502a2fcbda5b795..e26e23bad8edc4b27b1841f6b6267fb0e5bd583c 100644 (file)
@@ -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()]));
index 3e570eaa9178396fd77a313a801c35234278ee32..83414c82c5d584af1330b9e7bc26211470446ac7 100644 (file)
@@ -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.
index 60e737e27dcb187d14afb411132bf7ca1615c5d2..5d398b9d5adca016ff2d2ea5d34c9c49e8bc2c32 100644 (file)
@@ -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.
index feb96c94f2e8f91c6deed40ab476853ba03dd88f..e1d9951269fcc1d66b94b01f566ee69e86fac133 100644 (file)
@@ -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
+      + "}";
   }
 }
index 71b062c4b61ef796499cf57b82a67122c6c288da..a7511159608a617038348aa1efdc6c8df7f63294 100644 (file)
@@ -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) {
index 0894d45dfd1bac3ffae121b305065bbeb5417b10..c5a494dc23bdd91678665137d8e01f5e13cd5d4f 100644 (file)
@@ -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;
index 34c844ab6b1516c92d3d4c51d23ca708ddcd79f3..737a34d9b5aa2e38dc5e784160f4c16906792906 100644 (file)
  */
 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
index 0ac828699c4af278444a40cfc365590fd4fe2b56..5d087b3aa8a32ed0e16fdaff50fa6c52c3ed3bc2 100644 (file)
@@ -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;
index d600f65766eca70b6b9dd40cb97e3dfcc2576f70..757f8ea932c0038179ae6211bacd88820679c415 100644 (file)
  */
 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
index e120e7c383214a982af66704e7f6821f39d51bca..5a9ee977497aec7a4706505d17c9a5972b1c59f2 100644 (file)
@@ -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());
   }
index 06f781bf26430f3dfd89a6677d26bc7d826fddc6..63dd06c61494c57ac19efd1fb8af29291047ccdb 100644 (file)
  */
 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);
     }
   }
index 8a12f28269cbbe86ca1ec740b8c7a52635651fe8..532ddf6b3c6e6a6d692d6340e5daf9779bc70a2e 100644 (file)
@@ -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 {
 
index aa9a8bea9434e627a71d6c5504719df3b8c4fecc..82fb609df833f41bc28d67d45128be8a5223639c 100644 (file)
@@ -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.
index 39760f3d88a043064316ec3fc98399226cbb4b84..2eb9d44e31096460037f004de4273b6ae52c95a0 100644 (file)
@@ -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/utils/Preconditions.java b/sonar-plugin-api/src/main/java/org/sonar/api/utils/Preconditions.java
new file mode 100644 (file)
index 0000000..1a70241
--- /dev/null
@@ -0,0 +1,52 @@
+/*
+ * 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;
+
+public class Preconditions {
+  public static void checkArgument(boolean condition, String message) {
+    if (!condition) {
+      throw new IllegalArgumentException(message);
+    }
+  }
+
+  public static void checkArgument(boolean condition) {
+    if (!condition) {
+      throw new IllegalArgumentException();
+    }
+  }
+
+  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);
+    }
+  }
+
+  public static void checkState(boolean condition, String format, Object... args) {
+    if (!condition) {
+      throw new IllegalStateException(String.format(format, args));
+    }
+  }
+}
index 920ec7543aca2f346f5e5cbcdec0b76b500cc484..e190a78c29fa552c1fb3ce26e2df9eaaab14ef51 100644 (file)
  */
 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);
       }
     }
 
index 69823aeda21e339a1653c7663f0b0d25a6d2517d..ab5acd9ca4b620164eff4fc0f39df72450d6bc69 100644 (file)
@@ -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);
             }
index d8e2713facc31c44e623a81ef8cff38fe3f31625..a8eed2a6f7a15151326b83f63d206d0c72cb28fe 100644 (file)
@@ -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));
   }
 }
index 5044da2ab0ceffd0cdf53be4ce629db861341aeb..35334080778b573d4b29b4bf1d01a4d1a356acdc 100644 (file)
@@ -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
index 7c69e871c4987fef4ba646efcbddcf94a0fbcafa..ff2ba8f901b87fa867033664a866d514b1668167 100644 (file)
@@ -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;
   }
 }
index 3d95ed5d99d75e3c768584dbc020f4e290bb8481..cdb095f0e1c15b7541c10c02fbcee8ed03c79c61 100644 (file)
  */
 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) {
index d1ca30eea26256284850c1b5510bd2ac8640da9f..eb1fc0e814992c40ec346eec67784bea71b098da 100644 (file)
@@ -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
index 2defae48754aa42abe6469efc1ac8bab3603a2ef..493d7133cfd34e0ebf7adc6d1bd6d190d5102c01 100644 (file)
@@ -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 {
 
index 34c199020ec0a8f3c8396496f7929e099c12fc0e..ac20d1742d624bdf6337f65a2c2532b8afa21c4d 100644 (file)
@@ -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;
index 5c0bef70f42f676a4b68c3d2eddad65954e0693b..61111aa3847b78eae71f9138517ef5915ff2955d 100644 (file)
@@ -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 (file)
index 0000000..dd4659e
--- /dev/null
@@ -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");
+  }
+}
index 8b33f98db60cd64ec5912478453d83f93ff66f3b..25b86dc8f9a4ef2bd58e4b631c0989d175bd4fb6 100644 (file)
@@ -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");
index 80371dc5aa208e3b0fa811421a5815ee3e3c331a..ccf21a2e7135c1738810487942a2545c82a18680 100644 (file)
  */
 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 (file)
index 0000000..3d83da2
--- /dev/null
@@ -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;
+  }
+}
index e08477d66e154f50f5955262ec76bbb99228a80c..77a5ab3890ca3a7981e59af1fdde9db8ff149cd9 100644 (file)
@@ -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
index 412a6fe52d5186b1231a118bde31aefcddc95c83..b25ac2e93a226f0f3d0b03bafaf768ddd1e61428 100644 (file)
@@ -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;
 
index e15f2ef03341c9817bee91b69ff11b3fd40237ab..5dd0b4cff2bf81dfc2a9daa8f253b72ed6e5d907 100644 (file)
@@ -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;