Skip to content

Commit

Permalink
SONAR-6589 replace usage of ComputationContext.getRoot with TreeRootH…
Browse files Browse the repository at this point in the history
…older

also, ComponentTree is now computed as a step in BuildComponentTreeStep
  • Loading branch information
sns-seb committed Jun 1, 2015
1 parent 3735440 commit a2663cf
Show file tree
Hide file tree
Showing 22 changed files with 599 additions and 202 deletions.
Expand Up @@ -22,14 +22,13 @@
import org.sonar.server.computation.component.Component;
import org.sonar.server.computation.component.ComponentTreeBuilder;

public class ComputationContext implements org.sonar.server.computation.context.ComputationContext {
public class ComputationContext {
private final Component component;

public ComputationContext(ComponentTreeBuilder componentTreeBuilder) {
this.component = componentTreeBuilder.build();
}

@Override
public Component getRoot() {
return component;
}
Expand Down
Expand Up @@ -21,8 +21,7 @@

public interface ComponentTreeBuilder {
/**
* Builds the tree of components for the specified ComputationContext and returns the Component of the root of this
* tree.
* Builds the tree of components and returns the Component of the root of this tree.
*/
Component build();
}
@@ -0,0 +1,33 @@
/*
* 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 MutableTreeRootHolder extends TreeRootHolder {

/**
* Sets the root of the component tree in the TreeRootHolder. Settings a root more than once is allowed but it can
* never be set to {@code null}.
*
* @param newRoot a {@link Component}, can not be {@code null}
*
* @throws NullPointerException if {@code newRoot} is {@code null}
*/
void setRoot(Component newRoot);
}
Expand Up @@ -17,12 +17,13 @@
* 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.context;

import org.sonar.server.computation.component.Component;

public interface ComputationContext {
package org.sonar.server.computation.component;

public interface TreeRootHolder {
/**
* The root of the tree of Component representing the component in the current BatchReport.
*
* @throws IllegalStateException if the holder is empty (ie. there is no root yet)
*/
Component getRoot();

}
@@ -0,0 +1,42 @@
/*
* 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.Objects;

/**
* Holds the reference to the root of the {@link Component} tree for the current CE run.
*/
public class TreeRootHolderImpl implements MutableTreeRootHolder {
private Component root;

@Override
public void setRoot(Component newRoot) {
this.root = Objects.requireNonNull(newRoot);
}

@Override
public Component getRoot() {
if (this.root == null) {
throw new IllegalStateException("Root has not been created yet");
}
return this.root;
}
}
Expand Up @@ -37,6 +37,7 @@
import org.sonar.server.computation.batch.BatchReportReaderImpl;
import org.sonar.server.computation.batch.ReportExtractor;
import org.sonar.server.computation.component.DbComponentsRefCache;
import org.sonar.server.computation.component.TreeRootHolderImpl;
import org.sonar.server.computation.event.EventRepositoryImpl;
import org.sonar.server.computation.component.ProjectSettingsRepository;
import org.sonar.server.computation.issue.IssueCache;
Expand Down Expand Up @@ -113,6 +114,8 @@ private static List componentClasses() {
ReportExtractor.class,
BatchReportReaderImpl.class,

TreeRootHolderImpl.class,

// repositories
PlatformLanguageRepository.class,
MeasureRepositoryImpl.class,
Expand Down
@@ -0,0 +1,72 @@
/*
* 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.step;

import com.google.common.base.Function;
import com.google.common.collect.Iterables;
import javax.annotation.Nonnull;
import org.sonar.batch.protocol.output.BatchReport;
import org.sonar.server.computation.ComputationContext;
import org.sonar.server.computation.batch.BatchReportReader;
import org.sonar.server.computation.component.Component;
import org.sonar.server.computation.component.ComponentImpl;
import org.sonar.server.computation.component.MutableTreeRootHolder;

/**
* Populates the {@link MutableTreeRootHolder} from the {@link BatchReportReader}
*/
public class BuildComponentTreeStep implements ComputationStep {
private final BatchReportReader reportReader;
private final MutableTreeRootHolder mutableTreeRootHolder;

public BuildComponentTreeStep(BatchReportReader reportReader, MutableTreeRootHolder mutableTreeRootHolder) {
this.reportReader = reportReader;
this.mutableTreeRootHolder = mutableTreeRootHolder;
}

@Override
public void execute(ComputationContext context) {
mutableTreeRootHolder.setRoot(buildComponentRoot());
}

private Component buildComponentRoot() {
int rootComponentRef = reportReader.readMetadata().getRootComponentRef();
BatchReport.Component component = reportReader.readComponent(rootComponentRef);
return new ComponentImpl(component, buildChildren(component));
}

private Iterable<Component> buildChildren(BatchReport.Component component) {
return Iterables.transform(
component.getChildRefList(),
new Function<Integer, Component>() {
@Override
public Component apply(@Nonnull Integer componentRef) {
BatchReport.Component component = reportReader.readComponent(componentRef);
return new ComponentImpl(component, buildChildren(component));
}
}
);
}

@Override
public String getDescription() {
return "Builds the Component tree";
}
}
Expand Up @@ -36,6 +36,9 @@ public class ComputationSteps {
*/
public List<Class<? extends ComputationStep>> orderedStepClasses() {
return Arrays.asList(
// Builds Component tree
BuildComponentTreeStep.class,

PopulateComponentsUuidAndKeyStep.class,
ValidateProjectStep.class,

Expand Down
Expand Up @@ -26,22 +26,25 @@
import org.sonar.server.computation.batch.BatchReportReader;
import org.sonar.server.computation.component.Component;
import org.sonar.server.computation.component.DepthTraversalTypeAwareVisitor;
import org.sonar.server.computation.component.TreeRootHolder;
import org.sonar.server.computation.issue.IssueComputation;

public class ParseReportStep implements ComputationStep {

private final IssueComputation issueComputation;
private final BatchReportReader reportReader;
private final TreeRootHolder treeRootHolder;

public ParseReportStep(IssueComputation issueComputation, BatchReportReader reportReader) {
public ParseReportStep(IssueComputation issueComputation, BatchReportReader reportReader, TreeRootHolder treeRootHolder) {
this.issueComputation = issueComputation;
this.reportReader = reportReader;
this.treeRootHolder = treeRootHolder;
}

@Override
public void execute(ComputationContext context) {
IssueDepthTraversalTypeAwareVisitor visitor = new IssueDepthTraversalTypeAwareVisitor();
visitor.visit(context.getRoot());
visitor.visit(treeRootHolder.getRoot());
processDeletedComponents(visitor);
issueComputation.afterReportProcessing();
}
Expand Down
Expand Up @@ -36,25 +36,28 @@
import org.sonar.server.computation.batch.BatchReportReader;
import org.sonar.server.computation.component.Component;
import org.sonar.server.computation.component.DbComponentsRefCache;
import org.sonar.server.computation.component.TreeRootHolder;
import org.sonar.server.db.DbClient;

public class PersistComponentsStep implements ComputationStep {

private final DbClient dbClient;
private final DbComponentsRefCache dbComponentsRefCache;
private final BatchReportReader reportReader;
private final TreeRootHolder treeRootHolder;

public PersistComponentsStep(DbClient dbClient, DbComponentsRefCache dbComponentsRefCache, BatchReportReader reportReader) {
public PersistComponentsStep(DbClient dbClient, DbComponentsRefCache dbComponentsRefCache, BatchReportReader reportReader, TreeRootHolder treeRootHolder) {
this.dbClient = dbClient;
this.dbComponentsRefCache = dbComponentsRefCache;
this.reportReader = reportReader;
this.treeRootHolder = treeRootHolder;
}

@Override
public void execute(ComputationContext context) {
DbSession session = dbClient.openSession(false);
try {
Component root = context.getRoot();
Component root = treeRootHolder.getRoot();
List<ComponentDto> components = dbClient.componentDao().selectComponentsFromProjectKey(session, root.getKey());
Map<String, ComponentDto> componentDtosByKey = componentDtosByKey(components);
ComponentContext componentContext = new ComponentContext(session, componentDtosByKey);
Expand Down
Expand Up @@ -49,6 +49,7 @@
import org.sonar.server.computation.component.Component;
import org.sonar.server.computation.component.DbComponentsRefCache;
import org.sonar.server.computation.component.DepthTraversalTypeAwareVisitor;
import org.sonar.server.computation.component.TreeRootHolder;
import org.sonar.server.db.DbClient;
import org.sonar.server.source.db.FileSourceDb;
import org.sonar.server.source.db.FileSourceDb.Test.TestStatus;
Expand All @@ -62,20 +63,22 @@ public class PersistTestsStep implements ComputationStep {
private final System2 system;
private final DbComponentsRefCache dbComponentsRefCache;
private final BatchReportReader reportReader;
private final TreeRootHolder treeRootHolder;

public PersistTestsStep(DbClient dbClient, System2 system, DbComponentsRefCache dbComponentsRefCache, BatchReportReader reportReader) {
public PersistTestsStep(DbClient dbClient, System2 system, DbComponentsRefCache dbComponentsRefCache, BatchReportReader reportReader, TreeRootHolder treeRootHolder) {
this.dbClient = dbClient;
this.system = system;
this.dbComponentsRefCache = dbComponentsRefCache;
this.reportReader = reportReader;
this.treeRootHolder = treeRootHolder;
}

@Override
public void execute(final ComputationContext context) {
DbSession session = dbClient.openSession(true);
try {
TestDepthTraversalTypeAwareVisitor visitor = new TestDepthTraversalTypeAwareVisitor(context, session, dbComponentsRefCache);
visitor.visit(context.getRoot());
TestDepthTraversalTypeAwareVisitor visitor = new TestDepthTraversalTypeAwareVisitor(session, dbComponentsRefCache);
visitor.visit(treeRootHolder.getRoot());
session.commit();
if (visitor.hasUnprocessedCoverageDetails) {
String projectKey = dbComponentsRefCache.getByRef(reportReader.readMetadata().getRootComponentRef()).getKey();
Expand All @@ -98,14 +101,14 @@ private class TestDepthTraversalTypeAwareVisitor extends DepthTraversalTypeAware
final String projectUuid;
boolean hasUnprocessedCoverageDetails = false;

public TestDepthTraversalTypeAwareVisitor(ComputationContext context, DbSession session, DbComponentsRefCache dbComponentsRefCache) {
public TestDepthTraversalTypeAwareVisitor(DbSession session, DbComponentsRefCache dbComponentsRefCache) {
super(Component.Type.FILE, Order.PRE_ORDER);
this.session = session;
this.dbComponentsRefCache = dbComponentsRefCache;
this.existingFileSourcesByUuid = new HashMap<>();
this.projectUuid = context.getRoot().getUuid();
this.projectUuid = treeRootHolder.getRoot().getUuid();
session.select("org.sonar.core.source.db.FileSourceMapper.selectHashesForProject",
ImmutableMap.of("projectUuid", context.getRoot().getUuid(), "dataType", Type.TEST),
ImmutableMap.of("projectUuid", treeRootHolder.getRoot().getUuid(), "dataType", Type.TEST),
new ResultHandler() {
@Override
public void handleResult(ResultContext context) {
Expand Down
Expand Up @@ -33,6 +33,7 @@
import org.sonar.server.computation.batch.BatchReportReader;
import org.sonar.server.computation.component.Component;
import org.sonar.server.computation.component.ComponentImpl;
import org.sonar.server.computation.component.TreeRootHolder;
import org.sonar.server.db.DbClient;

/**
Expand All @@ -42,10 +43,12 @@ public class PopulateComponentsUuidAndKeyStep implements ComputationStep {

private final DbClient dbClient;
private final BatchReportReader reportReader;
private final TreeRootHolder treeRootHolder;

public PopulateComponentsUuidAndKeyStep(DbClient dbClient, BatchReportReader reportReader) {
public PopulateComponentsUuidAndKeyStep(DbClient dbClient, BatchReportReader reportReader, TreeRootHolder treeRootHolder) {
this.dbClient = dbClient;
this.reportReader = reportReader;
this.treeRootHolder = treeRootHolder;
}

@Override
Expand All @@ -65,7 +68,7 @@ public void execute(ComputationContext context) {

ComponentContext componentContext = new ComponentContext(reportReader, componentUuidsByKey, branch);

Component root = context.getRoot();
Component root = treeRootHolder.getRoot();
processProject(componentContext, root, projectKey);
processChildren(componentContext, root, root);
session.commit();
Expand Down

0 comments on commit a2663cf

Please sign in to comment.