diff options
11 files changed, 70 insertions, 59 deletions
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 index a67dd38eb84..cd949bcb49b 100644 --- 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 @@ -19,6 +19,8 @@ */ package org.sonar.api.utils; +import javax.annotation.Nullable; + public class Preconditions { private Preconditions() { // static only @@ -48,6 +50,12 @@ public class Preconditions { } } + public static void checkNotNull(@Nullable Object obj) { + if (obj == null) { + throw new NullPointerException(); + } + } + public static void checkState(boolean condition, String format, Object... args) { if (!condition) { throw new IllegalStateException(String.format(format, args)); diff --git a/sonar-scanner-engine/build.gradle b/sonar-scanner-engine/build.gradle index 65821d1555a..9617be77217 100644 --- a/sonar-scanner-engine/build.gradle +++ b/sonar-scanner-engine/build.gradle @@ -19,7 +19,6 @@ dependencies { compile 'commons-codec:commons-codec' compile 'commons-lang:commons-lang' compile 'com.google.code.gson:gson' - compile 'com.google.guava:guava' compile 'org.apache.commons:commons-csv' compile 'org.freemarker:freemarker' compile 'org.slf4j:jcl-over-slf4j' diff --git a/sonar-scanner-engine/src/main/java/org/sonar/scanner/DefaultFileLinesContext.java b/sonar-scanner-engine/src/main/java/org/sonar/scanner/DefaultFileLinesContext.java index a61ff027f10..b3e35cd4547 100644 --- a/sonar-scanner-engine/src/main/java/org/sonar/scanner/DefaultFileLinesContext.java +++ b/sonar-scanner-engine/src/main/java/org/sonar/scanner/DefaultFileLinesContext.java @@ -19,9 +19,7 @@ */ package org.sonar.scanner; -import com.google.common.base.MoreObjects; -import com.google.common.base.Preconditions; -import com.google.common.collect.ImmutableMap; +import java.util.Collections; import java.util.HashMap; import java.util.Map; import java.util.Map.Entry; @@ -34,6 +32,7 @@ import org.sonar.api.measures.FileLinesContext; import org.sonar.api.utils.KeyValueFormat; import static java.util.stream.Collectors.toMap; +import static org.sonar.api.utils.Preconditions.checkArgument; public class DefaultFileLinesContext implements FileLinesContext { private final InputFile inputFile; @@ -60,8 +59,8 @@ public class DefaultFileLinesContext implements FileLinesContext { } private void checkLineRange(int line) { - Preconditions.checkArgument(line > 0, "Line number should be positive for file %s.", inputFile); - Preconditions.checkArgument(line <= inputFile.lines(), "Line %s is out of range for file %s. File has %s lines.", line, inputFile, inputFile.lines()); + checkArgument(line > 0, "Line number should be positive for file %s.", inputFile); + checkArgument(line <= inputFile.lines(), "Line %s is out of range for file %s. File has %s lines.", line, inputFile, inputFile.lines()); } @Override @@ -96,7 +95,7 @@ public class DefaultFileLinesContext implements FileLinesContext { .forMetric(metricFinder.findByKey(metricKey)) .withValue(data) .save(); - entry.setValue(ImmutableMap.copyOf(lines)); + entry.setValue(Collections.unmodifiableMap(lines)); } } } @@ -117,14 +116,12 @@ public class DefaultFileLinesContext implements FileLinesContext { * @see #save() */ private static boolean shouldSave(Map<Integer, Object> lines) { - return !(lines instanceof ImmutableMap); + return lines instanceof HashMap; } @Override public String toString() { - return MoreObjects.toStringHelper(this) - .add("map", map) - .toString(); + return this.getClass().getSimpleName() + "{" + map.toString() + "}"; } } diff --git a/sonar-scanner-engine/src/main/java/org/sonar/scanner/issue/ignore/IgnoreIssuesFilter.java b/sonar-scanner-engine/src/main/java/org/sonar/scanner/issue/ignore/IgnoreIssuesFilter.java index 6626bb685d9..0a97ff5b3ee 100644 --- a/sonar-scanner-engine/src/main/java/org/sonar/scanner/issue/ignore/IgnoreIssuesFilter.java +++ b/sonar-scanner-engine/src/main/java/org/sonar/scanner/issue/ignore/IgnoreIssuesFilter.java @@ -19,21 +19,24 @@ */ package org.sonar.scanner.issue.ignore; -import com.google.common.collect.LinkedHashMultimap; -import com.google.common.collect.Multimap; +import java.util.Collections; +import java.util.HashMap; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; import org.sonar.api.batch.fs.InputComponent; +import org.sonar.api.batch.fs.internal.DefaultInputFile; import org.sonar.api.scan.issue.filter.FilterableIssue; import org.sonar.api.scan.issue.filter.IssueFilter; import org.sonar.api.scan.issue.filter.IssueFilterChain; import org.sonar.api.utils.WildcardPattern; import org.sonar.api.utils.log.Logger; import org.sonar.api.utils.log.Loggers; -import org.sonar.api.batch.fs.internal.DefaultInputFile; import org.sonar.scanner.issue.DefaultFilterableIssue; public class IgnoreIssuesFilter implements IssueFilter { - private Multimap<InputComponent, WildcardPattern> rulePatternByComponent = LinkedHashMultimap.create(); + private Map<InputComponent, List<WildcardPattern>> rulePatternByComponent = new HashMap<>(); private static final Logger LOG = Loggers.get(IgnoreIssuesFilter.class); @@ -56,12 +59,12 @@ public class IgnoreIssuesFilter implements IssueFilter { if ("*".equals(rulePattern.toString())) { inputFile.setIgnoreAllIssues(true); } else { - rulePatternByComponent.put(inputFile, rulePattern); + rulePatternByComponent.computeIfAbsent(inputFile, x -> new LinkedList<>()).add(rulePattern); } } private boolean hasRuleMatchFor(InputComponent component, FilterableIssue issue) { - for (WildcardPattern pattern : rulePatternByComponent.get(component)) { + for (WildcardPattern pattern : rulePatternByComponent.getOrDefault(component, Collections.emptyList())) { if (pattern.match(issue.ruleKey().toString())) { LOG.debug("Issue {} ignored by exclusion pattern {}", issue, pattern); return true; diff --git a/sonar-scanner-engine/src/main/java/org/sonar/scanner/issue/ignore/pattern/AbstractPatternInitializer.java b/sonar-scanner-engine/src/main/java/org/sonar/scanner/issue/ignore/pattern/AbstractPatternInitializer.java index 3fac8b8ed86..cac93aab98f 100644 --- a/sonar-scanner-engine/src/main/java/org/sonar/scanner/issue/ignore/pattern/AbstractPatternInitializer.java +++ b/sonar-scanner-engine/src/main/java/org/sonar/scanner/issue/ignore/pattern/AbstractPatternInitializer.java @@ -25,8 +25,6 @@ import org.apache.commons.lang.StringUtils; import org.sonar.api.config.Configuration; import org.sonar.api.utils.MessageException; -import static com.google.common.base.MoreObjects.firstNonNull; - public abstract class AbstractPatternInitializer { private Configuration settings; private List<IssuePattern> multicriteriaPatterns; @@ -65,7 +63,7 @@ public abstract class AbstractPatternInitializer { if (StringUtils.isBlank(ruleKeyPattern)) { throw MessageException.of("Issue exclusions are misconfigured. Rule key pattern is mandatory for each entry of '" + getMulticriteriaConfigurationKey() + "'"); } - IssuePattern pattern = new IssuePattern(firstNonNull(filePathPattern, "*"), firstNonNull(ruleKeyPattern, "*")); + IssuePattern pattern = new IssuePattern(filePathPattern != null ? filePathPattern : "*", ruleKeyPattern != null ? ruleKeyPattern : "*"); multicriteriaPatterns.add(pattern); } diff --git a/sonar-scanner-engine/src/main/java/org/sonar/scanner/rule/QProfile.java b/sonar-scanner-engine/src/main/java/org/sonar/scanner/rule/QProfile.java index 908503a1017..d207b0b1cbc 100644 --- a/sonar-scanner-engine/src/main/java/org/sonar/scanner/rule/QProfile.java +++ b/sonar-scanner-engine/src/main/java/org/sonar/scanner/rule/QProfile.java @@ -19,9 +19,7 @@ */ package org.sonar.scanner.rule; -import com.google.common.base.MoreObjects; import java.util.Date; - import javax.annotation.concurrent.Immutable; @Immutable @@ -74,11 +72,14 @@ public class QProfile { @Override public String toString() { - return MoreObjects.toStringHelper(this) - .add("key", key) - .add("name", name) - .add("language", language) - .add("rulesUpdatedAt", rulesUpdatedAt) + return new StringBuilder() + .append(this.getClass().getSimpleName()) + .append("{") + .append("key=").append(key) + .append("name=").append(name) + .append("language=").append(language) + .append("rulesUpdatedAt=").append(rulesUpdatedAt) + .append("}") .toString(); } diff --git a/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/DefaultInputModuleHierarchy.java b/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/DefaultInputModuleHierarchy.java index db0d7cfeb23..dab028f77f4 100644 --- a/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/DefaultInputModuleHierarchy.java +++ b/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/DefaultInputModuleHierarchy.java @@ -19,27 +19,28 @@ */ package org.sonar.scanner.scan; -import com.google.common.collect.ImmutableMultimap; import java.nio.file.Path; +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 javax.annotation.CheckForNull; import javax.annotation.concurrent.Immutable; -import org.sonar.api.scan.filesystem.PathResolver; import org.sonar.api.batch.fs.internal.AbstractProjectOrModule; import org.sonar.api.batch.fs.internal.DefaultInputModule; +import org.sonar.api.scan.filesystem.PathResolver; import org.sonar.scanner.fs.InputModuleHierarchy; @Immutable public class DefaultInputModuleHierarchy implements InputModuleHierarchy { private final DefaultInputModule root; private final Map<DefaultInputModule, DefaultInputModule> parents; - private final ImmutableMultimap<DefaultInputModule, DefaultInputModule> children; + private final Map<DefaultInputModule, List<DefaultInputModule>> children; public DefaultInputModuleHierarchy(DefaultInputModule root) { - this.children = new ImmutableMultimap.Builder<DefaultInputModule, DefaultInputModule>().build(); + this.children = Collections.emptyMap(); this.parents = Collections.emptyMap(); this.root = root; } @@ -48,13 +49,13 @@ public class DefaultInputModuleHierarchy implements InputModuleHierarchy { * Map of child->parent. Neither the Keys or values can be null. */ public DefaultInputModuleHierarchy(DefaultInputModule root, Map<DefaultInputModule, DefaultInputModule> parents) { - ImmutableMultimap.Builder<DefaultInputModule, DefaultInputModule> childrenBuilder = new ImmutableMultimap.Builder<>(); + Map<DefaultInputModule, List<DefaultInputModule>> childrenBuilder = new HashMap<>(); for (Map.Entry<DefaultInputModule, DefaultInputModule> e : parents.entrySet()) { - childrenBuilder.put(e.getValue(), e.getKey()); + childrenBuilder.computeIfAbsent(e.getValue(), x -> new ArrayList<>()).add(e.getKey()); } - this.children = childrenBuilder.build(); + this.children = Collections.unmodifiableMap(childrenBuilder); this.parents = Collections.unmodifiableMap(new HashMap<>(parents)); this.root = root; } @@ -66,7 +67,7 @@ public class DefaultInputModuleHierarchy implements InputModuleHierarchy { @Override public Collection<DefaultInputModule> children(DefaultInputModule component) { - return children.get(component); + return children.getOrDefault(component, Collections.emptyList()); } @Override diff --git a/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/ProjectReactorValidator.java b/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/ProjectReactorValidator.java index f639e0f02fd..3dd68273a3c 100644 --- a/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/ProjectReactorValidator.java +++ b/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/ProjectReactorValidator.java @@ -19,7 +19,6 @@ */ package org.sonar.scanner.scan; -import com.google.common.base.Joiner; import java.util.ArrayList; import java.util.Arrays; import java.util.List; @@ -82,7 +81,8 @@ public class ProjectReactorValidator { validateLegacyBranch(validationMessages, deprecatedBranchName); if (!validationMessages.isEmpty()) { - throw MessageException.of("Validation of project reactor failed:\n o " + Joiner.on("\n o ").join(validationMessages)); + throw MessageException.of("Validation of project reactor failed:\n o " + + String.join("\n o ", validationMessages)); } } diff --git a/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/filesystem/InputComponentStore.java b/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/filesystem/InputComponentStore.java index 2be7dd48056..d961ae54785 100644 --- a/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/filesystem/InputComponentStore.java +++ b/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/filesystem/InputComponentStore.java @@ -19,16 +19,14 @@ */ package org.sonar.scanner.scan.filesystem; -import com.google.common.base.Preconditions; -import com.google.common.collect.LinkedHashMultimap; -import com.google.common.collect.SetMultimap; -import com.google.common.collect.Table; -import com.google.common.collect.TreeBasedTable; import java.util.Collection; import java.util.Collections; import java.util.HashMap; +import java.util.LinkedHashMap; +import java.util.LinkedHashSet; import java.util.Map; import java.util.Optional; +import java.util.Set; import java.util.SortedSet; import java.util.TreeSet; import java.util.stream.Stream; @@ -41,6 +39,9 @@ import org.sonar.api.batch.fs.internal.DefaultInputModule; import org.sonar.api.batch.fs.internal.predicates.FileExtensionPredicate; import org.sonar.scanner.scan.branch.BranchConfiguration; +import static org.sonar.api.utils.Preconditions.checkNotNull; +import static org.sonar.api.utils.Preconditions.checkState; + /** * Store of all files and dirs. Inclusion and * exclusion patterns are already applied. @@ -50,12 +51,12 @@ public class InputComponentStore extends DefaultFileSystem.Cache { private final SortedSet<String> globalLanguagesCache = new TreeSet<>(); private final Map<String, SortedSet<String>> languagesCache = new HashMap<>(); private final Map<String, InputFile> globalInputFileCache = new HashMap<>(); - private final Table<String, String, InputFile> inputFileByModuleCache = TreeBasedTable.create(); + private final Map<String, Map<String, InputFile>> inputFileByModuleCache = new LinkedHashMap<>(); private final Map<InputFile, String> inputModuleKeyByFileCache = new HashMap<>(); private final Map<String, DefaultInputModule> inputModuleCache = new HashMap<>(); private final Map<String, InputComponent> inputComponents = 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 final BranchConfiguration branchConfiguration; public InputComponentStore(BranchConfiguration branchConfiguration) { @@ -91,18 +92,18 @@ public class InputComponentStore extends DefaultFileSystem.Cache { } public Iterable<InputFile> filesByModule(String moduleKey) { - return inputFileByModuleCache.row(moduleKey).values(); + return inputFileByModuleCache.getOrDefault(moduleKey, Collections.emptyMap()).values(); } public InputComponentStore put(String moduleKey, InputFile inputFile) { DefaultInputFile file = (DefaultInputFile) inputFile; addToLanguageCache(moduleKey, file); - inputFileByModuleCache.put(moduleKey, file.getModuleRelativePath(), inputFile); + inputFileByModuleCache.computeIfAbsent(moduleKey, x -> new HashMap<>()).put(file.getModuleRelativePath(), inputFile); inputModuleKeyByFileCache.put(inputFile, moduleKey); globalInputFileCache.put(file.getProjectRelativePath(), inputFile); inputComponents.put(inputFile.key(), inputFile); - filesByNameCache.put(inputFile.filename(), inputFile); - filesByExtensionCache.put(FileExtensionPredicate.getExtension(inputFile), inputFile); + filesByNameCache.computeIfAbsent(inputFile.filename(), x -> new LinkedHashSet<>()).add(inputFile); + filesByExtensionCache.computeIfAbsent(FileExtensionPredicate.getExtension(inputFile), x -> new LinkedHashSet<>()).add(inputFile); return this; } @@ -116,7 +117,8 @@ public class InputComponentStore extends DefaultFileSystem.Cache { @CheckForNull public InputFile getFile(String moduleKey, String relativePath) { - return inputFileByModuleCache.get(moduleKey, relativePath); + return inputFileByModuleCache.getOrDefault(moduleKey, Collections.emptyMap()) + .get(relativePath); } @Override @@ -132,21 +134,21 @@ public class InputComponentStore extends DefaultFileSystem.Cache { public void put(DefaultInputModule inputModule) { String key = inputModule.key(); - Preconditions.checkNotNull(inputModule); - Preconditions.checkState(!inputComponents.containsKey(key), "Module '%s' already indexed", key); - Preconditions.checkState(!inputModuleCache.containsKey(key), "Module '%s' already indexed", key); + checkNotNull(inputModule); + checkState(!inputComponents.containsKey(key), "Module '%s' already indexed", key); + checkState(!inputModuleCache.containsKey(key), "Module '%s' already indexed", key); inputComponents.put(key, inputModule); inputModuleCache.put(key, inputModule); } @Override public Iterable<InputFile> getFilesByName(String filename) { - return filesByNameCache.get(filename); + return filesByNameCache.getOrDefault(filename, Collections.emptySet()); } @Override public Iterable<InputFile> getFilesByExtension(String extension) { - return filesByExtensionCache.get(extension); + return filesByExtensionCache.getOrDefault(extension, Collections.emptySet()); } @Override diff --git a/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/filesystem/LanguageDetection.java b/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/filesystem/LanguageDetection.java index 57fbb86e23d..bb96632ca57 100644 --- a/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/filesystem/LanguageDetection.java +++ b/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/filesystem/LanguageDetection.java @@ -19,14 +19,15 @@ */ package org.sonar.scanner.scan.filesystem; -import com.google.common.base.Joiner; import java.nio.file.Path; import java.text.MessageFormat; import java.util.ArrayList; +import java.util.Arrays; import java.util.Collections; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; +import java.util.stream.Collectors; import javax.annotation.CheckForNull; import javax.annotation.concurrent.ThreadSafe; import org.apache.commons.lang.StringUtils; @@ -116,7 +117,8 @@ public class LanguageDetection { } private static String getDetails(String detectedLanguage, PathPattern[] patterns) { - return getFileLangPatternPropKey(detectedLanguage) + " : " + Joiner.on(",").join(patterns); + return getFileLangPatternPropKey(detectedLanguage) + " : " + + Arrays.stream(patterns).map(PathPattern::toString).collect(Collectors.joining(",")); } static String sanitizeExtension(String suffix) { diff --git a/sonar-scanner-engine/src/test/java/org/sonar/scanner/DefaultFileLinesContextTest.java b/sonar-scanner-engine/src/test/java/org/sonar/scanner/DefaultFileLinesContextTest.java index d5a5698b48e..d41193132a9 100644 --- a/sonar-scanner-engine/src/test/java/org/sonar/scanner/DefaultFileLinesContextTest.java +++ b/sonar-scanner-engine/src/test/java/org/sonar/scanner/DefaultFileLinesContextTest.java @@ -56,7 +56,7 @@ public class DefaultFileLinesContextTest { private DefaultInputFile file; @Before - public void setUp() throws Exception { + public void setUp() { MetricFinder metricFinder = mock(MetricFinder.class); org.sonar.api.batch.measure.Metric<String> hitsMetric = mock(org.sonar.api.batch.measure.Metric.class); when(hitsMetric.valueType()).thenReturn(String.class); @@ -83,7 +83,7 @@ public class DefaultFileLinesContextTest { fileLineMeasures.setIntValue(HITS_METRIC_KEY, 3, 0); fileLineMeasures.save(); - assertThat(fileLineMeasures.toString()).isEqualTo("DefaultFileLinesContext{map={hits={1=2, 3=0}}}"); + assertThat(fileLineMeasures.toString()).isEqualTo("DefaultFileLinesContext{{hits={1=2, 3=0}}}"); ArgumentCaptor<DefaultMeasure> captor = ArgumentCaptor.forClass(DefaultMeasure.class); verify(sensorStorage).store(captor.capture()); |