aboutsummaryrefslogtreecommitdiffstats
path: root/server
diff options
context:
space:
mode:
authorSébastien Lesaint <sebastien.lesaint@sonarsource.com>2015-11-09 10:49:46 +0100
committerSébastien Lesaint <sebastien.lesaint@sonarsource.com>2015-11-09 16:34:20 +0100
commit71f5c0a0a6071760312a7e69a83ef5e49d36b22e (patch)
treed2d91590e33122642c765efa20d15b6d068e7ef5 /server
parent54efd097b74af0fccad20f19555652ce693d6020 (diff)
downloadsonarqube-71f5c0a0a6071760312a7e69a83ef5e49d36b22e.tar.gz
sonarqube-71f5c0a0a6071760312a7e69a83ef5e49d36b22e.zip
SONAR-6990 merge ReportTreeRootHolder into TreeRootHolder
+ add methods to get Component by key from TreeRootHolder
Diffstat (limited to 'server')
-rw-r--r--server/sonar-server/src/main/java/org/sonar/server/computation/component/MutableTreeRootHolder.java1
-rw-r--r--server/sonar-server/src/main/java/org/sonar/server/computation/component/ReportTreeRootHolder.java31
-rw-r--r--server/sonar-server/src/main/java/org/sonar/server/computation/component/ReportTreeRootHolderImpl.java56
-rw-r--r--server/sonar-server/src/main/java/org/sonar/server/computation/component/TreeRootHolder.java25
-rw-r--r--server/sonar-server/src/main/java/org/sonar/server/computation/component/TreeRootHolderImpl.java84
-rw-r--r--server/sonar-server/src/main/java/org/sonar/server/computation/container/ReportComputeEngineContainerPopulator.java4
-rw-r--r--server/sonar-server/src/main/java/org/sonar/server/computation/issue/TrackerRawInputFactory.java13
-rw-r--r--server/sonar-server/src/main/java/org/sonar/server/computation/step/LoadDuplicationsFromReportStep.java6
-rw-r--r--server/sonar-server/src/main/java/org/sonar/server/computation/step/PersistDuplicationsStep.java24
-rw-r--r--server/sonar-server/src/main/java/org/sonar/server/computation/step/PersistTestsStep.java8
-rw-r--r--server/sonar-server/src/test/java/org/sonar/server/computation/batch/TreeRootHolderRule.java71
-rw-r--r--server/sonar-server/src/test/java/org/sonar/server/computation/component/MutableTreeRootHolderRule.java3
-rw-r--r--server/sonar-server/src/test/java/org/sonar/server/computation/component/ReportTreeRootHolderImplTest.java80
-rw-r--r--server/sonar-server/src/test/java/org/sonar/server/computation/component/TreeRootHolderImplTest.java169
-rw-r--r--server/sonar-server/src/test/java/org/sonar/server/computation/issue/ComponentIssuesRepositoryRule.java12
-rw-r--r--server/sonar-server/src/test/java/org/sonar/server/computation/step/LoadDuplicationsFromReportStepTest.java2
16 files changed, 321 insertions, 268 deletions
diff --git a/server/sonar-server/src/main/java/org/sonar/server/computation/component/MutableTreeRootHolder.java b/server/sonar-server/src/main/java/org/sonar/server/computation/component/MutableTreeRootHolder.java
index cfb79c72184..4fb9331412e 100644
--- a/server/sonar-server/src/main/java/org/sonar/server/computation/component/MutableTreeRootHolder.java
+++ b/server/sonar-server/src/main/java/org/sonar/server/computation/component/MutableTreeRootHolder.java
@@ -28,6 +28,7 @@ public interface MutableTreeRootHolder extends TreeRootHolder {
* @param newRoot a {@link Component}, can not be {@code null}
*
* @throws NullPointerException if {@code newRoot} is {@code null}
+ * @throws IllegalStateException if root {@link Component} has already been set
*/
MutableTreeRootHolder setRoot(Component newRoot);
}
diff --git a/server/sonar-server/src/main/java/org/sonar/server/computation/component/ReportTreeRootHolder.java b/server/sonar-server/src/main/java/org/sonar/server/computation/component/ReportTreeRootHolder.java
deleted file mode 100644
index d33c264d555..00000000000
--- a/server/sonar-server/src/main/java/org/sonar/server/computation/component/ReportTreeRootHolder.java
+++ /dev/null
@@ -1,31 +0,0 @@
-/*
- * SonarQube, open source software quality management tool.
- * Copyright (C) 2008-2014 SonarSource
- * mailto:contact AT sonarsource DOT com
- *
- * SonarQube 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.
- *
- * SonarQube 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.server.computation.component;
-
-public interface ReportTreeRootHolder extends TreeRootHolder {
-
- /**
- * Return a component by its batch reference
- *
- * @throws IllegalStateException if the holder is empty (ie. there is no root yet)
- * @throws IllegalArgumentException if there's no component for the reference
- */
- Component getComponentByRef(int ref);
-}
diff --git a/server/sonar-server/src/main/java/org/sonar/server/computation/component/ReportTreeRootHolderImpl.java b/server/sonar-server/src/main/java/org/sonar/server/computation/component/ReportTreeRootHolderImpl.java
deleted file mode 100644
index 5a6e9449bee..00000000000
--- a/server/sonar-server/src/main/java/org/sonar/server/computation/component/ReportTreeRootHolderImpl.java
+++ /dev/null
@@ -1,56 +0,0 @@
-/*
- * SonarQube, open source software quality management tool.
- * Copyright (C) 2008-2014 SonarSource
- * mailto:contact AT sonarsource DOT com
- *
- * SonarQube 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.
- *
- * SonarQube 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.server.computation.component;
-
-import java.util.HashMap;
-import java.util.Map;
-
-import static com.google.common.base.Preconditions.checkArgument;
-import static org.sonar.server.computation.component.ComponentVisitor.Order.POST_ORDER;
-
-public class ReportTreeRootHolderImpl extends TreeRootHolderImpl implements ReportTreeRootHolder {
- private Map<Integer, Component> componentsByRef = new HashMap<>();
-
- @Override
- public MutableTreeRootHolder setRoot(Component newRoot) {
- super.setRoot(newRoot);
- feedComponentsByRef(newRoot);
- return this;
- }
-
- private void feedComponentsByRef(Component newRoot) {
- new DepthTraversalTypeAwareCrawler(
- new TypeAwareVisitorAdapter(CrawlerDepthLimit.FILE, POST_ORDER) {
- @Override
- public void visitAny(Component component) {
- componentsByRef.put(component.getReportAttributes().getRef(), component);
- }
- }).visit(newRoot);
- }
-
- @Override
- public Component getComponentByRef(int ref) {
- // makes sure the root is set, hence componentsByRef is populated
- getRoot();
- Component component = componentsByRef.get(ref);
- checkArgument(component != null, String.format("Component '%s' hasn't been found", ref));
- return component;
- }
-}
diff --git a/server/sonar-server/src/main/java/org/sonar/server/computation/component/TreeRootHolder.java b/server/sonar-server/src/main/java/org/sonar/server/computation/component/TreeRootHolder.java
index 4b990fc9845..59b3c327883 100644
--- a/server/sonar-server/src/main/java/org/sonar/server/computation/component/TreeRootHolder.java
+++ b/server/sonar-server/src/main/java/org/sonar/server/computation/component/TreeRootHolder.java
@@ -26,4 +26,29 @@ public interface TreeRootHolder {
* @throws IllegalStateException if the holder is empty (ie. there is no root yet)
*/
Component getRoot();
+
+ /**
+ * Return a component by its batch reference
+ *
+ * @throws IllegalStateException if the holder is empty (ie. there is no root yet)
+ * @throws IllegalArgumentException if there's no {@link Component} with the specified reference
+ */
+ Component getComponentByRef(int ref);
+
+ /**
+ * Retrieves the component with the specified key in the {@link Component} tree in the holder.
+ *
+ * @throws NullPointerException if {@code key} is {@code null}
+ * @throws IllegalStateException if the holder is empty (ie. there is not root yet)
+ * @throws IllegalArgumentException if there is no {@link Component} with the specified key in the tree
+ */
+ Component getComponentByKey(String key);
+
+ /**
+ * Checks whether the {@link Component} with the specified key exists in the tree.
+ *
+ * @throws NullPointerException if {@code key} is {@code null}
+ * @throws IllegalStateException if the holder is empty (ie. there is not root yet)
+ */
+ boolean hasComponentWithKey(String key);
}
diff --git a/server/sonar-server/src/main/java/org/sonar/server/computation/component/TreeRootHolderImpl.java b/server/sonar-server/src/main/java/org/sonar/server/computation/component/TreeRootHolderImpl.java
index 21588209a1e..1e410a5b80c 100644
--- a/server/sonar-server/src/main/java/org/sonar/server/computation/component/TreeRootHolderImpl.java
+++ b/server/sonar-server/src/main/java/org/sonar/server/computation/component/TreeRootHolderImpl.java
@@ -19,26 +19,104 @@
*/
package org.sonar.server.computation.component;
+import com.google.common.collect.ImmutableMap;
+import java.util.Map;
+import javax.annotation.CheckForNull;
+
+import static com.google.common.base.Preconditions.checkArgument;
import static com.google.common.base.Preconditions.checkState;
import static java.util.Objects.requireNonNull;
+import static org.sonar.server.computation.component.ComponentVisitor.Order.POST_ORDER;
/**
* Holds the reference to the root of the {@link Component} tree for the current CE run.
*/
public class TreeRootHolderImpl implements MutableTreeRootHolder {
+ @CheckForNull
+ private Map<Integer, Component> componentsByRef;
+ @CheckForNull
+ private Map<String, Component> componentsByKey;
private Component root;
@Override
- public MutableTreeRootHolder setRoot(Component newRoot) {
- this.root = requireNonNull(newRoot);
+ public MutableTreeRootHolder setRoot(Component root) {
+ checkState(this.root == null, "root can not be set twice in holder");
+ this.root = requireNonNull(root, "root can not be null");
return this;
}
@Override
public Component getRoot() {
- checkState(this.root != null, "Root has not been created yet");
+ checkInitialized();
return this.root;
}
+ @Override
+ public Component getComponentByRef(int ref) {
+ checkInitialized();
+ ensureComponentByRefIsPopulated();
+ Component component = componentsByRef.get(ref);
+ checkArgument(component != null, "Component with ref '%s' can't be found", ref);
+ return component;
+ }
+
+ private void ensureComponentByRefIsPopulated() {
+ if (componentsByRef != null) {
+ return;
+ }
+
+ final ImmutableMap.Builder<Integer, Component> builder = ImmutableMap.builder();
+ new DepthTraversalTypeAwareCrawler(
+ new TypeAwareVisitorAdapter(CrawlerDepthLimit.FILE, POST_ORDER) {
+ @Override
+ public void visitAny(Component component) {
+ builder.put(component.getReportAttributes().getRef(), component);
+ }
+ }).visit(this.root);
+ this.componentsByRef = builder.build();
+ }
+
+ @Override
+ public Component getComponentByKey(String key) {
+ checkKeyArgument(key);
+ checkInitialized();
+ ensureComponentByKeyIsPopulated();
+ Component component = componentsByKey.get(key);
+ checkArgument(component != null, "Component with key '%s' can't be found", key);
+ return component;
+ }
+
+ @Override
+ public boolean hasComponentWithKey(String key) {
+ checkKeyArgument(key);
+ checkInitialized();
+ ensureComponentByKeyIsPopulated();
+
+ return componentsByKey.containsKey(key);
+ }
+
+ private void checkInitialized() {
+ checkState(this.root != null, "Holder has not been initialized yet");
+ }
+
+ private static void checkKeyArgument(String key) {
+ requireNonNull(key, "key can not be null");
+ }
+
+ private void ensureComponentByKeyIsPopulated() {
+ if (componentsByKey != null) {
+ return;
+ }
+
+ final ImmutableMap.Builder<String, Component> builder = ImmutableMap.builder();
+ new DepthTraversalTypeAwareCrawler(
+ new TypeAwareVisitorAdapter(CrawlerDepthLimit.LEAVES, POST_ORDER) {
+ @Override
+ public void visitAny(Component component) {
+ builder.put(component.getKey(), component);
+ }
+ }).visit(this.root);
+ this.componentsByKey = builder.build();
+ }
}
diff --git a/server/sonar-server/src/main/java/org/sonar/server/computation/container/ReportComputeEngineContainerPopulator.java b/server/sonar-server/src/main/java/org/sonar/server/computation/container/ReportComputeEngineContainerPopulator.java
index f74ac8ba1ec..b625ee51faf 100644
--- a/server/sonar-server/src/main/java/org/sonar/server/computation/container/ReportComputeEngineContainerPopulator.java
+++ b/server/sonar-server/src/main/java/org/sonar/server/computation/container/ReportComputeEngineContainerPopulator.java
@@ -27,8 +27,8 @@ import org.sonar.server.computation.analysis.AnalysisMetadataHolderImpl;
import org.sonar.server.computation.batch.BatchReportDirectoryHolderImpl;
import org.sonar.server.computation.batch.BatchReportReaderImpl;
import org.sonar.server.computation.component.DbIdsRepositoryImpl;
-import org.sonar.server.computation.component.ReportTreeRootHolderImpl;
import org.sonar.server.computation.component.SettingsRepositoryImpl;
+import org.sonar.server.computation.component.TreeRootHolderImpl;
import org.sonar.server.computation.debt.DebtModelHolderImpl;
import org.sonar.server.computation.duplication.DuplicationRepositoryImpl;
import org.sonar.server.computation.event.EventRepositoryImpl;
@@ -117,7 +117,7 @@ public final class ReportComputeEngineContainerPopulator implements ContainerPop
// holders
AnalysisMetadataHolderImpl.class,
BatchReportDirectoryHolderImpl.class,
- ReportTreeRootHolderImpl.class,
+ TreeRootHolderImpl.class,
PeriodsHolderImpl.class,
QualityGateHolderImpl.class,
DebtModelHolderImpl.class,
diff --git a/server/sonar-server/src/main/java/org/sonar/server/computation/issue/TrackerRawInputFactory.java b/server/sonar-server/src/main/java/org/sonar/server/computation/issue/TrackerRawInputFactory.java
index fca45414d4c..053a71d81d8 100644
--- a/server/sonar-server/src/main/java/org/sonar/server/computation/issue/TrackerRawInputFactory.java
+++ b/server/sonar-server/src/main/java/org/sonar/server/computation/issue/TrackerRawInputFactory.java
@@ -19,6 +19,9 @@
*/
package org.sonar.server.computation.issue;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
import org.sonar.api.issue.Issue;
import org.sonar.api.rule.RuleKey;
import org.sonar.api.utils.log.Loggers;
@@ -32,25 +35,21 @@ import org.sonar.db.protobuf.DbCommons;
import org.sonar.db.protobuf.DbIssues;
import org.sonar.server.computation.batch.BatchReportReader;
import org.sonar.server.computation.component.Component;
-import org.sonar.server.computation.component.ReportTreeRootHolder;
+import org.sonar.server.computation.component.TreeRootHolder;
import org.sonar.server.computation.issue.commonrule.CommonRuleEngine;
import org.sonar.server.computation.source.SourceLinesRepository;
import org.sonar.server.rule.CommonRuleKeys;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.List;
-
import static com.google.common.collect.Lists.newArrayList;
public class TrackerRawInputFactory {
- private final ReportTreeRootHolder treeRootHolder;
+ private final TreeRootHolder treeRootHolder;
private final BatchReportReader reportReader;
private final SourceLinesRepository sourceLinesRepository;
private final CommonRuleEngine commonRuleEngine;
- public TrackerRawInputFactory(ReportTreeRootHolder treeRootHolder, BatchReportReader reportReader,
+ public TrackerRawInputFactory(TreeRootHolder treeRootHolder, BatchReportReader reportReader,
SourceLinesRepository sourceLinesRepository, CommonRuleEngine commonRuleEngine) {
this.treeRootHolder = treeRootHolder;
this.reportReader = reportReader;
diff --git a/server/sonar-server/src/main/java/org/sonar/server/computation/step/LoadDuplicationsFromReportStep.java b/server/sonar-server/src/main/java/org/sonar/server/computation/step/LoadDuplicationsFromReportStep.java
index 8fea5413b15..3006266bfc2 100644
--- a/server/sonar-server/src/main/java/org/sonar/server/computation/step/LoadDuplicationsFromReportStep.java
+++ b/server/sonar-server/src/main/java/org/sonar/server/computation/step/LoadDuplicationsFromReportStep.java
@@ -25,7 +25,7 @@ import org.sonar.server.computation.batch.BatchReportReader;
import org.sonar.server.computation.component.Component;
import org.sonar.server.computation.component.CrawlerDepthLimit;
import org.sonar.server.computation.component.DepthTraversalTypeAwareCrawler;
-import org.sonar.server.computation.component.ReportTreeRootHolder;
+import org.sonar.server.computation.component.TreeRootHolder;
import org.sonar.server.computation.component.TypeAwareVisitorAdapter;
import org.sonar.server.computation.duplication.DuplicationRepository;
import org.sonar.server.computation.duplication.TextBlock;
@@ -36,11 +36,11 @@ import static org.sonar.server.computation.component.ComponentVisitor.Order.POST
* Loads duplication information from the report and loads them into the {@link DuplicationRepository}.
*/
public class LoadDuplicationsFromReportStep implements ComputationStep {
- private final ReportTreeRootHolder treeRootHolder;
+ private final TreeRootHolder treeRootHolder;
private final BatchReportReader batchReportReader;
private final DuplicationRepository duplicationRepository;
- public LoadDuplicationsFromReportStep(ReportTreeRootHolder treeRootHolder, BatchReportReader batchReportReader, DuplicationRepository duplicationRepository) {
+ public LoadDuplicationsFromReportStep(TreeRootHolder treeRootHolder, BatchReportReader batchReportReader, DuplicationRepository duplicationRepository) {
this.treeRootHolder = treeRootHolder;
this.batchReportReader = batchReportReader;
this.duplicationRepository = duplicationRepository;
diff --git a/server/sonar-server/src/main/java/org/sonar/server/computation/step/PersistDuplicationsStep.java b/server/sonar-server/src/main/java/org/sonar/server/computation/step/PersistDuplicationsStep.java
index 74671bcbae4..901df0b3347 100644
--- a/server/sonar-server/src/main/java/org/sonar/server/computation/step/PersistDuplicationsStep.java
+++ b/server/sonar-server/src/main/java/org/sonar/server/computation/step/PersistDuplicationsStep.java
@@ -32,7 +32,7 @@ import org.sonar.server.computation.component.Component;
import org.sonar.server.computation.component.CrawlerDepthLimit;
import org.sonar.server.computation.component.DbIdsRepository;
import org.sonar.server.computation.component.DepthTraversalTypeAwareCrawler;
-import org.sonar.server.computation.component.ReportTreeRootHolder;
+import org.sonar.server.computation.component.TreeRootHolder;
import org.sonar.server.computation.component.TypeAwareVisitorAdapter;
import org.sonar.server.computation.duplication.CrossProjectDuplicate;
import org.sonar.server.computation.duplication.Duplicate;
@@ -51,11 +51,11 @@ public class PersistDuplicationsStep implements ComputationStep {
private final DbClient dbClient;
private final DbIdsRepository dbIdsRepository;
- private final ReportTreeRootHolder treeRootHolder;
+ private final TreeRootHolder treeRootHolder;
private final DuplicationRepository duplicationRepository;
- public PersistDuplicationsStep(DbClient dbClient, DbIdsRepository dbIdsRepository, ReportTreeRootHolder treeRootHolder,
- DuplicationRepository duplicationRepository) {
+ public PersistDuplicationsStep(DbClient dbClient, DbIdsRepository dbIdsRepository, TreeRootHolder treeRootHolder,
+ DuplicationRepository duplicationRepository) {
this.dbClient = dbClient;
this.dbIdsRepository = dbIdsRepository;
this.treeRootHolder = treeRootHolder;
@@ -68,7 +68,7 @@ public class PersistDuplicationsStep implements ComputationStep {
try {
MetricDto duplicationMetric = dbClient.metricDao().selectOrFailByKey(session, CoreMetrics.DUPLICATIONS_DATA_KEY);
new DepthTraversalTypeAwareCrawler(new DuplicationVisitor(session, duplicationMetric))
- .visit(treeRootHolder.getRoot());
+ .visit(treeRootHolder.getRoot());
session.commit();
} finally {
MyBatis.closeQuietly(session);
@@ -97,10 +97,10 @@ public class PersistDuplicationsStep implements ComputationStep {
private void saveDuplications(Component component, Iterable<Duplication> duplications) {
String duplicationXml = createXmlDuplications(component.getKey(), duplications);
MeasureDto measureDto = new MeasureDto()
- .setMetricId(duplicationMetric.getId())
- .setData(duplicationXml)
- .setComponentId(dbIdsRepository.getComponentId(component))
- .setSnapshotId(dbIdsRepository.getSnapshotId(component));
+ .setMetricId(duplicationMetric.getId())
+ .setData(duplicationXml)
+ .setComponentId(dbIdsRepository.getComponentId(component))
+ .setSnapshotId(dbIdsRepository.getSnapshotId(component));
dbClient.measureDao().insert(session, measureDto);
}
@@ -142,9 +142,9 @@ public class PersistDuplicationsStep implements ComputationStep {
private void appendDuplication(StringBuilder xml, String componentKey, TextBlock textBlock) {
int length = textBlock.getEnd() - textBlock.getStart() + 1;
xml.append("<b s=\"").append(textBlock.getStart())
- .append("\" l=\"").append(length)
- .append("\" r=\"").append(StringEscapeUtils.escapeXml(componentKey))
- .append("\"/>");
+ .append("\" l=\"").append(length)
+ .append("\" r=\"").append(StringEscapeUtils.escapeXml(componentKey))
+ .append("\"/>");
}
}
diff --git a/server/sonar-server/src/main/java/org/sonar/server/computation/step/PersistTestsStep.java b/server/sonar-server/src/main/java/org/sonar/server/computation/step/PersistTestsStep.java
index a0b8974485d..cb96a8e02f1 100644
--- a/server/sonar-server/src/main/java/org/sonar/server/computation/step/PersistTestsStep.java
+++ b/server/sonar-server/src/main/java/org/sonar/server/computation/step/PersistTestsStep.java
@@ -36,11 +36,11 @@ import java.util.Set;
import org.apache.ibatis.session.ResultContext;
import org.apache.ibatis.session.ResultHandler;
import org.sonar.api.utils.System2;
-import org.sonar.core.util.Uuids;
import org.sonar.api.utils.log.Logger;
import org.sonar.api.utils.log.Loggers;
import org.sonar.batch.protocol.output.BatchReport;
import org.sonar.core.util.CloseableIterator;
+import org.sonar.core.util.Uuids;
import org.sonar.db.DbClient;
import org.sonar.db.DbSession;
import org.sonar.db.MyBatis;
@@ -52,7 +52,7 @@ import org.sonar.server.computation.component.Component;
import org.sonar.server.computation.component.ComponentVisitor;
import org.sonar.server.computation.component.CrawlerDepthLimit;
import org.sonar.server.computation.component.DepthTraversalTypeAwareCrawler;
-import org.sonar.server.computation.component.ReportTreeRootHolder;
+import org.sonar.server.computation.component.TreeRootHolder;
import org.sonar.server.computation.component.TypeAwareVisitorAdapter;
public class PersistTestsStep implements ComputationStep {
@@ -62,9 +62,9 @@ public class PersistTestsStep implements ComputationStep {
private final DbClient dbClient;
private final System2 system;
private final BatchReportReader reportReader;
- private final ReportTreeRootHolder treeRootHolder;
+ private final TreeRootHolder treeRootHolder;
- public PersistTestsStep(DbClient dbClient, System2 system, BatchReportReader reportReader, ReportTreeRootHolder treeRootHolder) {
+ public PersistTestsStep(DbClient dbClient, System2 system, BatchReportReader reportReader, TreeRootHolder treeRootHolder) {
this.dbClient = dbClient;
this.system = system;
this.reportReader = reportReader;
diff --git a/server/sonar-server/src/test/java/org/sonar/server/computation/batch/TreeRootHolderRule.java b/server/sonar-server/src/test/java/org/sonar/server/computation/batch/TreeRootHolderRule.java
index 92335b9abde..865f9145966 100644
--- a/server/sonar-server/src/test/java/org/sonar/server/computation/batch/TreeRootHolderRule.java
+++ b/server/sonar-server/src/test/java/org/sonar/server/computation/batch/TreeRootHolderRule.java
@@ -19,77 +19,42 @@
*/
package org.sonar.server.computation.batch;
-import java.util.HashMap;
-import java.util.Map;
-import org.junit.rules.TestRule;
-import org.junit.runner.Description;
-import org.junit.runners.model.Statement;
+import org.junit.rules.ExternalResource;
import org.sonar.server.computation.component.Component;
-import org.sonar.server.computation.component.CrawlerDepthLimit;
-import org.sonar.server.computation.component.DepthTraversalTypeAwareCrawler;
-import org.sonar.server.computation.component.MutableTreeRootHolder;
-import org.sonar.server.computation.component.ReportTreeRootHolder;
import org.sonar.server.computation.component.TreeRootHolder;
-import org.sonar.server.computation.component.TypeAwareVisitorAdapter;
+import org.sonar.server.computation.component.TreeRootHolderImpl;
-import static com.google.common.base.Preconditions.checkArgument;
-import static com.google.common.base.Preconditions.checkState;
-import static java.util.Objects.requireNonNull;
-import static org.sonar.server.computation.component.ComponentVisitor.Order.POST_ORDER;
-
-public class TreeRootHolderRule implements TestRule, MutableTreeRootHolder, ReportTreeRootHolder {
- private Component root;
- private Map<Integer, Component> componentsByRef = new HashMap<>();
+public class TreeRootHolderRule extends ExternalResource implements TreeRootHolder {
+ protected TreeRootHolderImpl delegate = new TreeRootHolderImpl();
@Override
- public Statement apply(final Statement statement, Description description) {
- return new Statement() {
- @Override
- public void evaluate() throws Throwable {
- try {
- statement.evaluate();
- } finally {
- clear();
- }
- }
- };
+ protected void after() {
+ this.delegate = null;
}
- private void clear() {
- this.root = null;
- this.componentsByRef.clear();
+ public TreeRootHolderRule setRoot(Component newRoot) {
+ delegate = new TreeRootHolderImpl();
+ delegate.setRoot(newRoot);
+ return this;
}
@Override
public Component getRoot() {
- checkInitialized();
-
- return root;
+ return delegate.getRoot();
}
@Override
public Component getComponentByRef(int ref) {
- checkInitialized();
-
- Component component = componentsByRef.get(ref);
- checkArgument(component != null, "Component with ref '%s' hasn't been found", ref);
- return component;
+ return delegate.getComponentByRef(ref);
}
- private void checkInitialized() {
- checkState(root != null, "Root has not been set in %s", TreeRootHolder.class.getSimpleName());
+ @Override
+ public Component getComponentByKey(String key) {
+ return delegate.getComponentByKey(key);
}
- public TreeRootHolderRule setRoot(Component newRoot) {
- this.root = requireNonNull(newRoot);
- if (newRoot.getType().isReportType()) {
- new DepthTraversalTypeAwareCrawler(new TypeAwareVisitorAdapter(CrawlerDepthLimit.FILE, POST_ORDER) {
- @Override
- public void visitAny(Component component) {
- componentsByRef.put(component.getReportAttributes().getRef(), component);
- }
- }).visit(root);
- }
- return this;
+ @Override
+ public boolean hasComponentWithKey(String key) {
+ return delegate.hasComponentWithKey(key);
}
}
diff --git a/server/sonar-server/src/test/java/org/sonar/server/computation/component/MutableTreeRootHolderRule.java b/server/sonar-server/src/test/java/org/sonar/server/computation/component/MutableTreeRootHolderRule.java
index f2309b75722..b9124c96c47 100644
--- a/server/sonar-server/src/test/java/org/sonar/server/computation/component/MutableTreeRootHolderRule.java
+++ b/server/sonar-server/src/test/java/org/sonar/server/computation/component/MutableTreeRootHolderRule.java
@@ -24,6 +24,7 @@ import org.sonar.server.computation.batch.TreeRootHolderRule;
public class MutableTreeRootHolderRule extends TreeRootHolderRule implements MutableTreeRootHolder {
@Override
public MutableTreeRootHolderRule setRoot(Component newRoot) {
- return (MutableTreeRootHolderRule)super.setRoot(newRoot);
+ delegate.setRoot(newRoot);
+ return this;
}
}
diff --git a/server/sonar-server/src/test/java/org/sonar/server/computation/component/ReportTreeRootHolderImplTest.java b/server/sonar-server/src/test/java/org/sonar/server/computation/component/ReportTreeRootHolderImplTest.java
deleted file mode 100644
index 62e17c73ab3..00000000000
--- a/server/sonar-server/src/test/java/org/sonar/server/computation/component/ReportTreeRootHolderImplTest.java
+++ /dev/null
@@ -1,80 +0,0 @@
-/*
- * SonarQube, open source software quality management tool.
- * Copyright (C) 2008-2014 SonarSource
- * mailto:contact AT sonarsource DOT com
- *
- * SonarQube 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.
- *
- * SonarQube 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.server.computation.component;
-
-import org.junit.Rule;
-import org.junit.Test;
-import org.junit.rules.ExpectedException;
-
-import static org.assertj.core.api.Assertions.assertThat;
-
-public class ReportTreeRootHolderImplTest {
-
- @Rule
- public ExpectedException thrown = ExpectedException.none();
-
- ReportTreeRootHolderImpl treeRootHolder = new ReportTreeRootHolderImpl();
- Component project = ReportComponent.DUMB_PROJECT;
-
- @Test
- public void setRoot_throws_NPE_if_arg_is_null() {
- thrown.expect(NullPointerException.class);
- treeRootHolder.setRoot(null);
- }
-
- @Test
- public void getRoot_throws_ISE_if_root_has_not_been_set_yet() {
- thrown.expect(IllegalStateException.class);
- treeRootHolder.getRoot();
- }
-
- @Test
- public void verify_setRoot_getRoot() {
- treeRootHolder.setRoot(project);
- assertThat(treeRootHolder.getRoot()).isSameAs(project);
- }
-
- @Test
- public void get_by_ref() {
- Component file = ReportComponent.builder(Component.Type.FILE, 4).build();
- Component directory = ReportComponent.builder(Component.Type.DIRECTORY, 3).addChildren(file).build();
- Component module = ReportComponent.builder(Component.Type.MODULE, 2).addChildren(directory).build();
- Component project = ReportComponent.builder(Component.Type.PROJECT, 1).addChildren(module).build();
- treeRootHolder.setRoot(project);
-
- assertThat(treeRootHolder.getComponentByRef(1)).isEqualTo(project);
- assertThat(treeRootHolder.getComponentByRef(2)).isEqualTo(module);
- assertThat(treeRootHolder.getComponentByRef(3)).isEqualTo(directory);
- assertThat(treeRootHolder.getComponentByRef(4)).isEqualTo(file);
- }
-
- @Test
- public void fail_to_get_by_ref_if_root_not_set() {
- thrown.expect(IllegalStateException.class);
- treeRootHolder.getComponentByRef(project.getReportAttributes().getRef());
- }
-
- @Test
- public void fail_to_get_by_ref_if_ref_not_found() {
- thrown.expect(IllegalArgumentException.class);
- treeRootHolder.setRoot(project);
- treeRootHolder.getComponentByRef(123);
- }
-}
diff --git a/server/sonar-server/src/test/java/org/sonar/server/computation/component/TreeRootHolderImplTest.java b/server/sonar-server/src/test/java/org/sonar/server/computation/component/TreeRootHolderImplTest.java
index 069d77ea7b7..ecce5f0a22d 100644
--- a/server/sonar-server/src/test/java/org/sonar/server/computation/component/TreeRootHolderImplTest.java
+++ b/server/sonar-server/src/test/java/org/sonar/server/computation/component/TreeRootHolderImplTest.java
@@ -24,31 +24,182 @@ import org.junit.Test;
import org.junit.rules.ExpectedException;
import static org.assertj.core.api.Assertions.assertThat;
+import static org.sonar.server.computation.component.Component.Type.DIRECTORY;
+import static org.sonar.server.computation.component.Component.Type.FILE;
+import static org.sonar.server.computation.component.Component.Type.MODULE;
+import static org.sonar.server.computation.component.Component.Type.PROJECT;
+import static org.sonar.server.computation.component.Component.Type.PROJECT_VIEW;
+import static org.sonar.server.computation.component.Component.Type.VIEW;
+import static org.sonar.server.computation.component.ReportComponent.DUMB_PROJECT;
public class TreeRootHolderImplTest {
+ private static final ReportComponent SOME_REPORT_COMPONENT_TREE = ReportComponent.builder(PROJECT, 1)
+ .addChildren(
+ ReportComponent.builder(MODULE, 2)
+ .addChildren(ReportComponent.builder(DIRECTORY, 3)
+ .addChildren(
+ ReportComponent.builder(FILE, 4).build()
+ )
+ .build())
+ .build()
+ )
+ .build();
+ private static final ViewsComponent SOME_VIEWS_COMPONENT_TREE = ViewsComponent.builder(VIEW, 1)
+ .addChildren(
+ ViewsComponent.builder(VIEW, 2)
+ .addChildren(ViewsComponent.builder(PROJECT_VIEW, 3).build())
+ .build()
+ )
+ .build();
+
@Rule
- public ExpectedException thrown = ExpectedException.none();
+ public ExpectedException expectedException = ExpectedException.none();
- TreeRootHolderImpl treeRootHolder = new TreeRootHolderImpl();
- Component project = ReportComponent.DUMB_PROJECT;
+ private TreeRootHolderImpl underTest = new TreeRootHolderImpl();
@Test
public void setRoot_throws_NPE_if_arg_is_null() {
- thrown.expect(NullPointerException.class);
- treeRootHolder.setRoot(null);
+ expectedException.expect(NullPointerException.class);
+ expectedException.expectMessage("root can not be null");
+
+ underTest.setRoot(null);
+ }
+
+ @Test
+ public void setRoot_throws_ISE_when_called_twice() {
+ underTest.setRoot(DUMB_PROJECT);
+
+ expectedException.expect(IllegalStateException.class);
+ expectedException.expectMessage("root can not be set twice in holder");
+
+ underTest.setRoot(DUMB_PROJECT);
}
@Test
public void getRoot_throws_ISE_if_root_has_not_been_set_yet() {
- thrown.expect(IllegalStateException.class);
- treeRootHolder.getRoot();
+ expectNotInitialized_ISE();
+
+ underTest.getRoot();
+ }
+
+ @Test
+ public void getComponentByRef_throws_ISE_if_root_has_not_been_set() {
+ expectNotInitialized_ISE();
+
+ underTest.getComponentByRef(12);
+ }
+
+ @Test
+ public void getComponentByRef_returns_any_report_component_in_the_tree() {
+ underTest.setRoot(SOME_REPORT_COMPONENT_TREE);
+
+ for (int i = 1; i <= 4; i++) {
+ assertThat(underTest.getComponentByRef(i).getReportAttributes().getRef()).isEqualTo(i);
+ }
+ }
+
+ @Test
+ public void getComponentByRef_throws_IAE_if_holder_does_not_contain_specified_component() {
+ underTest.setRoot(SOME_REPORT_COMPONENT_TREE);
+
+ expectedException.expect(IllegalArgumentException.class);
+ expectedException.expectMessage("Component with ref '6' can't be found");
+
+ underTest.getComponentByRef(6);
+ }
+
+ @Test
+ public void getComponentByRef_throws_IAE_if_holder_contains_View_tree() {
+ underTest.setRoot(SOME_VIEWS_COMPONENT_TREE);
+
+ expectedException.expect(IllegalArgumentException.class);
+ expectedException.expectMessage("Component with ref '1' can't be found");
+
+ underTest.getComponentByRef(1);
+ }
+
+ @Test
+ public void getComponentByKey_throws_NPE_if_key_is_null() {
+ expectedException.expect(NullPointerException.class);
+ expectedException.expectMessage("key can not be null");
+
+ underTest.getComponentByKey(null);
+ }
+
+ @Test
+ public void getComponentByKey_throws_ISE_if_root_has_not_been_set() {
+ expectNotInitialized_ISE();
+
+ underTest.getComponentByKey("key");
+ }
+
+ @Test
+ public void getComponentByKey_returns_any_report_component_in_the_tree() {
+ underTest.setRoot(SOME_REPORT_COMPONENT_TREE);
+
+ for (int i = 1; i <= 4; i++) {
+ String key = "key_" + i;
+ assertThat(underTest.getComponentByKey(key).getKey()).isEqualTo(key);
+ }
+ }
+
+ @Test
+ public void getComponentByKey_returns_any_views_component_in_the_tree() {
+ underTest.setRoot(SOME_VIEWS_COMPONENT_TREE);
+
+ for (int i = 1; i <= 3; i++) {
+ String key = String.valueOf(i);
+ assertThat(underTest.getComponentByKey(key).getKey()).isEqualTo(key);
+ }
}
@Test
public void verify_setRoot_getRoot() {
- treeRootHolder.setRoot(project);
- assertThat(treeRootHolder.getRoot()).isSameAs(project);
+ underTest.setRoot(DUMB_PROJECT);
+ assertThat(underTest.getRoot()).isSameAs(DUMB_PROJECT);
+ }
+
+ @Test
+ public void hasComponentWithKey_throws_NPE_if_key_is_null() {
+ expectedException.expect(NullPointerException.class);
+ expectedException.expectMessage("key can not be null");
+
+ underTest.hasComponentWithKey(null);
+ }
+
+ @Test
+ public void hasComponentWithKey_throws_ISE_if_root_has_not_been_set() {
+ expectNotInitialized_ISE();
+
+ underTest.hasComponentWithKey("key");
+ }
+
+ @Test
+ public void hasComponentWithKey_returns_true_for_any_report_component_in_the_tree() {
+ underTest.setRoot(SOME_REPORT_COMPONENT_TREE);
+
+ for (int i = 1; i <= 4; i++) {
+ String key = "key_" + i;
+ assertThat(underTest.hasComponentWithKey(key)).isTrue();
+ }
+ assertThat(underTest.hasComponentWithKey("toto")).isFalse();
+ }
+
+ @Test
+ public void hasComponentWithKey_returns_true_for_any_views_component_in_the_tree() {
+ underTest.setRoot(SOME_VIEWS_COMPONENT_TREE);
+
+ for (int i = 1; i <= 3; i++) {
+ String key = String.valueOf(i);
+ assertThat(underTest.hasComponentWithKey(key)).isTrue();
+ }
+ assertThat(underTest.hasComponentWithKey("toto")).isFalse();
+ }
+
+ private void expectNotInitialized_ISE() {
+ expectedException.expect(IllegalStateException.class);
+ expectedException.expectMessage("Holder has not been initialized yet");
}
}
diff --git a/server/sonar-server/src/test/java/org/sonar/server/computation/issue/ComponentIssuesRepositoryRule.java b/server/sonar-server/src/test/java/org/sonar/server/computation/issue/ComponentIssuesRepositoryRule.java
index dd1950d026f..9946698c565 100644
--- a/server/sonar-server/src/test/java/org/sonar/server/computation/issue/ComponentIssuesRepositoryRule.java
+++ b/server/sonar-server/src/test/java/org/sonar/server/computation/issue/ComponentIssuesRepositoryRule.java
@@ -25,7 +25,7 @@ import javax.annotation.CheckForNull;
import org.junit.rules.ExternalResource;
import org.sonar.core.issue.DefaultIssue;
import org.sonar.server.computation.component.Component;
-import org.sonar.server.computation.component.ReportTreeRootHolder;
+import org.sonar.server.computation.component.TreeRootHolder;
import static com.google.common.base.Preconditions.checkArgument;
import static com.google.common.base.Preconditions.checkNotNull;
@@ -34,7 +34,7 @@ import static java.util.Objects.requireNonNull;
public class ComponentIssuesRepositoryRule extends ExternalResource implements MutableComponentIssuesRepository, ComponentIssuesRepository {
- private final ReportTreeRootHolder reportTreeRootHolder;
+ private final TreeRootHolder treeRootHolder;
@CheckForNull
private List<DefaultIssue> issues;
@@ -42,8 +42,8 @@ public class ComponentIssuesRepositoryRule extends ExternalResource implements M
@CheckForNull
private Component component;
- public ComponentIssuesRepositoryRule(ReportTreeRootHolder reportTreeRootHolder) {
- this.reportTreeRootHolder = reportTreeRootHolder;
+ public ComponentIssuesRepositoryRule(TreeRootHolder treeRootHolder) {
+ this.treeRootHolder = treeRootHolder;
}
@Override
@@ -54,7 +54,7 @@ public class ComponentIssuesRepositoryRule extends ExternalResource implements M
public void setIssues(int componentRef, List<DefaultIssue> issues) {
this.issues = requireNonNull(issues, "issues cannot be null");
- Component component = reportTreeRootHolder.getComponentByRef(componentRef);
+ Component component = treeRootHolder.getComponentByRef(componentRef);
checkArgument(component != null, String.format("Component '%s' does not exists in the report ", componentRef));
this.component = component;
}
@@ -67,7 +67,7 @@ public class ComponentIssuesRepositoryRule extends ExternalResource implements M
public List<DefaultIssue> getIssues(int componentRef) {
checkState(this.component != null && this.issues != null, "Issues have not been initialized");
- Component component = reportTreeRootHolder.getComponentByRef(componentRef);
+ Component component = treeRootHolder.getComponentByRef(componentRef);
checkArgument(component != null, String.format("Component '%s' does not exists in the report ", componentRef));
checkArgument(component == this.component,
String.format("Only issues from component '%s' are available, but wanted component is '%s'.",
diff --git a/server/sonar-server/src/test/java/org/sonar/server/computation/step/LoadDuplicationsFromReportStepTest.java b/server/sonar-server/src/test/java/org/sonar/server/computation/step/LoadDuplicationsFromReportStepTest.java
index 0da0ba15dd4..a57e5807d24 100644
--- a/server/sonar-server/src/test/java/org/sonar/server/computation/step/LoadDuplicationsFromReportStepTest.java
+++ b/server/sonar-server/src/test/java/org/sonar/server/computation/step/LoadDuplicationsFromReportStepTest.java
@@ -136,7 +136,7 @@ public class LoadDuplicationsFromReportStepTest {
reportReader.putDuplications(FILE_1_REF, createDuplication(singleLineTextRange(line), createInProjectDuplicate(666, line + 1)));
expectedException.expect(IllegalArgumentException.class);
- expectedException.expectMessage("Component with ref '666' hasn't been found");
+ expectedException.expectMessage("Component with ref '666' can't be found");
underTest.execute();
}