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.

ServerIssueRepository.java 5.4KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146
  1. /*
  2. * SonarQube, open source software quality management tool.
  3. * Copyright (C) 2008-2014 SonarSource
  4. * mailto:contact AT sonarsource DOT com
  5. *
  6. * SonarQube 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. * SonarQube 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.batch.issue.tracking;
  21. import com.google.common.base.Function;
  22. import java.util.Collections;
  23. import java.util.LinkedList;
  24. import java.util.List;
  25. import javax.annotation.Nullable;
  26. import org.sonar.api.batch.AnalysisMode;
  27. import org.sonar.api.batch.BatchSide;
  28. import org.sonar.api.batch.InstantiationStrategy;
  29. import org.sonar.api.batch.fs.InputFile;
  30. import org.sonar.api.batch.fs.InputFile.Status;
  31. import org.sonar.api.utils.log.Logger;
  32. import org.sonar.api.utils.log.Loggers;
  33. import org.sonar.api.utils.log.Profiler;
  34. import org.sonar.batch.index.BatchComponent;
  35. import org.sonar.batch.index.BatchComponentCache;
  36. import org.sonar.batch.index.Cache;
  37. import org.sonar.batch.index.Caches;
  38. import org.sonar.batch.protocol.input.BatchInput.ServerIssue;
  39. import org.sonar.batch.repository.ServerIssuesLoader;
  40. import org.sonar.batch.scan.ImmutableProjectReactor;
  41. import org.sonar.batch.scan.filesystem.InputPathCache;
  42. import org.sonar.core.component.ComponentKeys;
  43. @InstantiationStrategy(InstantiationStrategy.PER_BATCH)
  44. @BatchSide
  45. public class ServerIssueRepository {
  46. private static final Logger LOG = Loggers.get(ServerIssueRepository.class);
  47. private final Caches caches;
  48. private Cache<ServerIssue> issuesCache;
  49. private final ServerIssuesLoader previousIssuesLoader;
  50. private final ImmutableProjectReactor reactor;
  51. private final BatchComponentCache resourceCache;
  52. private final AnalysisMode analysisMode;
  53. public ServerIssueRepository(Caches caches, ServerIssuesLoader previousIssuesLoader, ImmutableProjectReactor reactor, BatchComponentCache resourceCache,
  54. AnalysisMode analysisMode) {
  55. this.caches = caches;
  56. this.previousIssuesLoader = previousIssuesLoader;
  57. this.reactor = reactor;
  58. this.resourceCache = resourceCache;
  59. this.analysisMode = analysisMode;
  60. }
  61. public void load() {
  62. if (analysisMode.isIncremental()) {
  63. return;
  64. }
  65. Profiler profiler = Profiler.create(LOG).startInfo("Load server issues");
  66. this.issuesCache = caches.createCache("previousIssues");
  67. caches.registerValueCoder(ServerIssue.class, new ServerIssueValueCoder());
  68. boolean fromCache = previousIssuesLoader.load(reactor.getRoot().getKeyWithBranch(), new SaveIssueConsumer(), false);
  69. stopDebug(profiler, "Load server issues", fromCache);
  70. }
  71. public Iterable<ServerIssue> byComponent(BatchComponent component) {
  72. if (analysisMode.isIncremental()) {
  73. if (!component.isFile()) {
  74. throw new UnsupportedOperationException("Incremental mode should only get issues on files");
  75. }
  76. InputFile inputFile = (InputFile) component.inputComponent();
  77. if (inputFile.status() == Status.ADDED) {
  78. return Collections.emptyList();
  79. }
  80. Profiler profiler = Profiler.create(LOG).startInfo("Load server issues for " + component.resource().getPath());
  81. ServerIssueConsumer consumer = new ServerIssueConsumer();
  82. boolean fromCache = previousIssuesLoader.load(component.key(), consumer, true);
  83. stopDebug(profiler, "Load server issues for " + component.resource().getPath(), fromCache);
  84. return consumer.issueList;
  85. } else {
  86. return issuesCache.values(component.batchId());
  87. }
  88. }
  89. private static void stopDebug(Profiler profiler, String msg, boolean fromCache) {
  90. if (fromCache) {
  91. profiler.stopDebug(msg + " (done from cache)");
  92. } else {
  93. profiler.stopDebug(msg + " (done)");
  94. }
  95. }
  96. private class SaveIssueConsumer implements Function<ServerIssue, Void> {
  97. @Override
  98. public Void apply(@Nullable ServerIssue issue) {
  99. if (issue == null) {
  100. return null;
  101. }
  102. String componentKey = ComponentKeys.createEffectiveKey(issue.getModuleKey(), issue.hasPath() ? issue.getPath() : null);
  103. BatchComponent r = resourceCache.get(componentKey);
  104. if (r == null) {
  105. // Deleted resource
  106. issuesCache.put(0, issue.getKey(), issue);
  107. } else {
  108. issuesCache.put(r.batchId(), issue.getKey(), issue);
  109. }
  110. return null;
  111. }
  112. }
  113. private static class ServerIssueConsumer implements Function<ServerIssue, Void> {
  114. List<ServerIssue> issueList = new LinkedList<>();
  115. @Override
  116. public Void apply(@Nullable ServerIssue issue) {
  117. if (issue == null) {
  118. return null;
  119. }
  120. issueList.add(issue);
  121. return null;
  122. }
  123. }
  124. public Iterable<ServerIssue> issuesOnMissingComponents() {
  125. if (analysisMode.isIncremental()) {
  126. throw new UnsupportedOperationException("Only issues of analyzed components are loaded in incremental mode");
  127. }
  128. return issuesCache.values(0);
  129. }
  130. }