You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

InputComponentStore.java 5.9KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158
  1. /*
  2. * SonarQube
  3. * Copyright (C) 2009-2019 SonarSource SA
  4. * mailto:info AT sonarsource DOT com
  5. *
  6. * This program is free software; you can redistribute it and/or
  7. * modify it under the terms of the GNU Lesser General Public
  8. * License as published by the Free Software Foundation; either
  9. * version 3 of the License, or (at your option) any later version.
  10. *
  11. * This program is distributed in the hope that it will be useful,
  12. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  14. * Lesser General Public License for more details.
  15. *
  16. * You should have received a copy of the GNU Lesser General Public License
  17. * along with this program; if not, write to the Free Software Foundation,
  18. * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
  19. */
  20. package org.sonar.scanner.scan.filesystem;
  21. import com.google.common.base.Preconditions;
  22. import com.google.common.collect.LinkedHashMultimap;
  23. import com.google.common.collect.SetMultimap;
  24. import com.google.common.collect.Table;
  25. import com.google.common.collect.TreeBasedTable;
  26. import java.util.Collection;
  27. import java.util.Collections;
  28. import java.util.HashMap;
  29. import java.util.Map;
  30. import java.util.SortedSet;
  31. import java.util.TreeSet;
  32. import java.util.stream.Stream;
  33. import javax.annotation.CheckForNull;
  34. import org.sonar.api.batch.fs.InputComponent;
  35. import org.sonar.api.batch.fs.InputFile;
  36. import org.sonar.api.batch.fs.internal.DefaultInputFile;
  37. import org.sonar.api.batch.fs.internal.DefaultInputModule;
  38. import org.sonar.api.batch.fs.internal.FileExtensionPredicate;
  39. import org.sonar.scanner.scan.branch.BranchConfiguration;
  40. /**
  41. * Store of all files and dirs. Inclusion and
  42. * exclusion patterns are already applied.
  43. */
  44. public class InputComponentStore {
  45. private final SortedSet<String> globalLanguagesCache = new TreeSet<>();
  46. private final Map<String, SortedSet<String>> languagesCache = new HashMap<>();
  47. private final Map<String, InputFile> globalInputFileCache = new HashMap<>();
  48. private final Table<String, String, InputFile> inputFileByModuleCache = TreeBasedTable.create();
  49. // indexed by key with branch
  50. private final Map<String, DefaultInputModule> inputModuleCache = new HashMap<>();
  51. private final Map<String, InputComponent> inputComponents = new HashMap<>();
  52. private final SetMultimap<String, InputFile> filesByNameCache = LinkedHashMultimap.create();
  53. private final SetMultimap<String, InputFile> filesByExtensionCache = LinkedHashMultimap.create();
  54. private final BranchConfiguration branchConfiguration;
  55. public InputComponentStore(BranchConfiguration branchConfiguration) {
  56. this.branchConfiguration = branchConfiguration;
  57. }
  58. public Collection<InputComponent> all() {
  59. return inputComponents.values();
  60. }
  61. private Stream<DefaultInputFile> allFilesToPublishStream() {
  62. return inputFileByModuleCache.values().stream()
  63. .map(f -> (DefaultInputFile) f)
  64. .filter(DefaultInputFile::isPublished);
  65. }
  66. public Iterable<DefaultInputFile> allFilesToPublish() {
  67. return allFilesToPublishStream()::iterator;
  68. }
  69. public Iterable<DefaultInputFile> allChangedFilesToPublish() {
  70. return allFilesToPublishStream()
  71. .filter(f -> !branchConfiguration.isShortOrPullRequest() || f.status() != InputFile.Status.SAME)
  72. ::iterator;
  73. }
  74. public Collection<InputFile> allFiles() {
  75. return globalInputFileCache.values();
  76. }
  77. public InputComponent getByKey(String key) {
  78. return inputComponents.get(key);
  79. }
  80. public Iterable<InputFile> filesByModule(String moduleKey) {
  81. return inputFileByModuleCache.row(moduleKey).values();
  82. }
  83. public InputComponentStore put(String moduleKey, InputFile inputFile) {
  84. DefaultInputFile file = (DefaultInputFile) inputFile;
  85. addToLanguageCache(moduleKey, file);
  86. inputFileByModuleCache.put(moduleKey, file.getModuleRelativePath(), inputFile);
  87. globalInputFileCache.put(file.getProjectRelativePath(), inputFile);
  88. inputComponents.put(inputFile.key(), inputFile);
  89. filesByNameCache.put(inputFile.filename(), inputFile);
  90. filesByExtensionCache.put(FileExtensionPredicate.getExtension(inputFile), inputFile);
  91. return this;
  92. }
  93. private void addToLanguageCache(String moduleKey, DefaultInputFile inputFile) {
  94. String language = inputFile.language();
  95. if (language != null) {
  96. globalLanguagesCache.add(language);
  97. languagesCache.computeIfAbsent(moduleKey, k -> new TreeSet<>()).add(language);
  98. }
  99. }
  100. @CheckForNull
  101. public InputFile getFile(String moduleKey, String relativePath) {
  102. return inputFileByModuleCache.get(moduleKey, relativePath);
  103. }
  104. @CheckForNull
  105. public InputFile getFile(String relativePath) {
  106. return globalInputFileCache.get(relativePath);
  107. }
  108. @CheckForNull
  109. public DefaultInputModule getModule(String moduleKeyWithBranch) {
  110. return inputModuleCache.get(moduleKeyWithBranch);
  111. }
  112. public void put(DefaultInputModule inputModule) {
  113. String key = inputModule.key();
  114. String keyWithBranch = inputModule.getKeyWithBranch();
  115. Preconditions.checkNotNull(inputModule);
  116. Preconditions.checkState(!inputComponents.containsKey(key), "Module '%s' already indexed", key);
  117. Preconditions.checkState(!inputModuleCache.containsKey(keyWithBranch), "Module '%s' already indexed", keyWithBranch);
  118. inputComponents.put(key, inputModule);
  119. inputModuleCache.put(keyWithBranch, inputModule);
  120. }
  121. public Iterable<InputFile> getFilesByName(String filename) {
  122. return filesByNameCache.get(filename);
  123. }
  124. public Iterable<InputFile> getFilesByExtension(String extension) {
  125. return filesByExtensionCache.get(extension);
  126. }
  127. public SortedSet<String> getLanguages() {
  128. return globalLanguagesCache;
  129. }
  130. public SortedSet<String> getLanguages(String moduleKey) {
  131. return languagesCache.getOrDefault(moduleKey, Collections.emptySortedSet());
  132. }
  133. public Collection<DefaultInputModule> allModules() {
  134. return inputModuleCache.values();
  135. }
  136. }