import org.sonar.server.computation.ComputationContext;
import org.sonar.server.computation.component.Component;
import org.sonar.server.computation.component.ComponentImpl;
+import org.sonar.server.computation.component.DepthTraversalTypeAwareVisitor;
import org.sonar.server.db.DbClient;
/**
@Override
public void execute(ComputationContext context) {
- DbSession session = dbClient.openSession(false);
- try {
- BatchReportReader reportReader = context.getReportReader();
- String branch = context.getReportMetadata().hasBranch() ? context.getReportMetadata().getBranch() : null;
- BatchReport.Component project = reportReader.readComponent(context.getReportMetadata().getRootComponentRef());
- String projectKey = ComponentKeys.createKey(project.getKey(), branch);
+ new ComponentDepthTraversalTypeAwareVisitor(context).visit(context.getRoot());
+ }
- Map<String, String> componentUuidByKey = new HashMap<>();
- List<ComponentDto> components = dbClient.componentDao().selectComponentsFromProjectKey(session, projectKey);
- for (ComponentDto componentDto : components) {
- componentUuidByKey.put(componentDto.getKey(), componentDto.uuid());
- }
+ @Override
+ public String getDescription() {
+ return "Feed components uuid";
+ }
+
+ private class ComponentDepthTraversalTypeAwareVisitor extends DepthTraversalTypeAwareVisitor {
- ComponentContext componentContext = new ComponentContext(reportReader, componentUuidByKey, branch);
+ private final BatchReportReader reportReader;
+ private final Map<String, String> componentUuidByKey;
- Component root = context.getRoot();
- processProject(componentContext, root, projectKey);
- processChildren(componentContext, root, root);
- session.commit();
- } finally {
- session.close();
+ @Nullable
+ private final String branch;
+
+ private Component nearestModule;
+
+ public ComponentDepthTraversalTypeAwareVisitor(ComputationContext context) {
+ super(Component.Type.FILE, Order.PRE_ORDER);
+ this.componentUuidByKey = new HashMap<>();
+ this.branch = context.getReportMetadata().hasBranch() ? context.getReportMetadata().getBranch() : null;
+ this.reportReader = context.getReportReader();
+ this.nearestModule = null;
}
- }
- private void recursivelyProcessComponent(ComponentContext componentContext, Component component, Component module) {
- switch (component.getType()) {
- case MODULE:
- processModule(componentContext, component);
- processChildren(componentContext, component, component);
- break;
- case DIRECTORY:
- case FILE:
- processDirectoryAndFile(componentContext, component, module);
- processChildren(componentContext, component, module);
- break;
- default:
- throw new IllegalStateException(String.format("Unsupported component type '%s'", component.getType()));
+ @Override
+ public void visitProject(Component project) {
+ executeForProject(project);
+ nearestModule = project;
}
- }
- private void processChildren(ComponentContext componentContext, Component component, Component nearestModule) {
- for (Component child : component.getChildren()) {
- recursivelyProcessComponent(componentContext, child, nearestModule);
+ @Override
+ public void visitModule(Component module) {
+ executeForModule(module);
+ nearestModule = module;
}
- }
- private void processProject(ComponentContext componentContext, Component component, String projectKey) {
- feedComponent((ComponentImpl) component, projectKey, componentContext.componentUuidByKey);
- }
+ @Override
+ public void visitDirectory(Component directory) {
+ executeForDirectoryAndFile(directory);
+ }
- private void processModule(ComponentContext componentContext, Component component) {
- BatchReport.Component batchComponent = componentContext.reportReader.readComponent(component.getRef());
- String componentKey = ComponentKeys.createKey(batchComponent.getKey(), componentContext.branch);
- feedComponent((ComponentImpl) component, componentKey, componentContext.componentUuidByKey);
- }
+ @Override
+ public void visitFile(Component file) {
+ executeForDirectoryAndFile(file);
+ }
- private void processDirectoryAndFile(ComponentContext componentContext, Component component, Component module) {
- BatchReport.Component batchComponent = componentContext.reportReader.readComponent(component.getRef());
- // TODO fail if path is null
- String componentKey = ComponentKeys.createEffectiveKey(module.getKey(), batchComponent.getPath());
- feedComponent((ComponentImpl) component, componentKey, componentContext.componentUuidByKey);
- }
+ private void executeForProject(Component component) {
+ BatchReport.Component project = reportReader.readComponent(component.getRef());
+ String projectKey = ComponentKeys.createKey(project.getKey(), branch);
+ DbSession session = dbClient.openSession(false);
+ try {
+ List<ComponentDto> components = dbClient.componentDao().selectComponentsFromProjectKey(session, projectKey);
+ for (ComponentDto componentDto : components) {
+ componentUuidByKey.put(componentDto.getKey(), componentDto.uuid());
+ }
+
+ feedComponent((ComponentImpl) component, projectKey);
+ } finally {
+ session.close();
+ }
+ }
- private void feedComponent(ComponentImpl component, String componentKey, Map<String, String> componentUuidByKey) {
- component.setKey(componentKey);
+ private void executeForModule(Component component) {
+ BatchReport.Component batchComponent = reportReader.readComponent(component.getRef());
+ String componentKey = ComponentKeys.createKey(batchComponent.getKey(), branch);
+ feedComponent((ComponentImpl) component, componentKey);
+ }
- String componentUuid = componentUuidByKey.get(componentKey);
- if (componentUuid == null) {
- component.setUuid(Uuids.create());
- } else {
- component.setUuid(componentUuid);
+ private void executeForDirectoryAndFile(Component component) {
+ BatchReport.Component batchComponent = reportReader.readComponent(component.getRef());
+ // TODO fail if path is null
+ String componentKey = ComponentKeys.createEffectiveKey(nearestModule.getKey(), batchComponent.getPath());
+ feedComponent((ComponentImpl) component, componentKey);
}
- }
- private static class ComponentContext {
- private final BatchReportReader reportReader;
- private final Map<String, String> componentUuidByKey;
- private final String branch;
+ private void feedComponent(ComponentImpl component, String componentKey) {
+ component.setKey(componentKey);
- public ComponentContext(BatchReportReader reportReader, Map<String, String> componentUuidByKey, @Nullable String branch) {
- this.reportReader = reportReader;
- this.componentUuidByKey = new HashMap<>();
- this.branch = branch;
+ String componentUuid = componentUuidByKey.get(componentKey);
+ if (componentUuid == null) {
+ component.setUuid(Uuids.create());
+ } else {
+ component.setUuid(componentUuid);
+ }
}
}
-
- @Override
- public String getDescription() {
- return "Feed components uuid";
- }
-
}
}
@Test
- public void compute_keys_and_uuids() throws Exception {
+ public void add_components() throws Exception {
File reportDir = temp.newFolder();
BatchReportWriter writer = new BatchReportWriter(reportDir);
writer.writeMetadata(BatchReport.Metadata.newBuilder()
assertThat(componentsByRef.get(4).getKey()).isEqualTo("MODULE_KEY:origin/master:src/main/java/dir/Foo.java");
}
- @Test
- public void compute_keys_and_uuids_on_project_having_module_and_directory() throws Exception {
- File reportDir = temp.newFolder();
- BatchReportWriter writer = new BatchReportWriter(reportDir);
- writer.writeMetadata(BatchReport.Metadata.newBuilder()
- .setRootComponentRef(1)
- .build());
-
- writer.writeComponent(BatchReport.Component.newBuilder()
- .setRef(1)
- .setType(Constants.ComponentType.PROJECT)
- .setKey(PROJECT_KEY)
- .addChildRef(2)
- .addChildRef(5)
- .build());
- writer.writeComponent(BatchReport.Component.newBuilder()
- .setRef(2)
- .setType(Constants.ComponentType.MODULE)
- .setKey("MODULE_KEY")
- .addChildRef(3)
- .build());
- writer.writeComponent(BatchReport.Component.newBuilder()
- .setRef(3)
- .setType(Constants.ComponentType.DIRECTORY)
- .setPath("src/main/java/dir")
- .addChildRef(4)
- .build());
- writer.writeComponent(BatchReport.Component.newBuilder()
- .setRef(4)
- .setType(Constants.ComponentType.FILE)
- .setPath("src/main/java/dir/Foo.java")
- .build());
- writer.writeComponent(BatchReport.Component.newBuilder()
- .setRef(5)
- .setType(Constants.ComponentType.DIRECTORY)
- .setPath("/")
- .addChildRef(6)
- .build());
- writer.writeComponent(BatchReport.Component.newBuilder()
- .setRef(6)
- .setType(Constants.ComponentType.FILE)
- .setPath("pom.xml")
- .build());
-
- BatchReportReader batchReportReader = new BatchReportReader(reportDir);
- ComputationContext context = new ComputationContext(batchReportReader, PROJECT_KEY, projectSettings,
- dbClient, ComponentTreeBuilders.from(batchReportReader), languageRepository);
- sut.execute(context);
-
- Map<Integer, Component> componentsByRef = getComponentsByRef(context.getRoot());
-
- assertThat(componentsByRef.get(1).getKey()).isEqualTo(PROJECT_KEY);
- assertThat(componentsByRef.get(1).getUuid()).isNotNull();
-
- assertThat(componentsByRef.get(2).getKey()).isEqualTo("MODULE_KEY");
- assertThat(componentsByRef.get(2).getUuid()).isNotNull();
-
- assertThat(componentsByRef.get(3).getKey()).isEqualTo("MODULE_KEY:src/main/java/dir");
- assertThat(componentsByRef.get(3).getUuid()).isNotNull();
-
- assertThat(componentsByRef.get(4).getKey()).isEqualTo("MODULE_KEY:src/main/java/dir/Foo.java");
- assertThat(componentsByRef.get(4).getUuid()).isNotNull();
-
- assertThat(componentsByRef.get(5).getKey()).isEqualTo(PROJECT_KEY + ":/");
- assertThat(componentsByRef.get(5).getUuid()).isNotNull();
-
- assertThat(componentsByRef.get(6).getKey()).isEqualTo(PROJECT_KEY + ":pom.xml");
- assertThat(componentsByRef.get(6).getUuid()).isNotNull();
- }
-
private static Map<Integer, Component> getComponentsByRef(Component root) {
Map<Integer, Component> componentsByRef = new HashMap<>();
feedComponentByRef(root, componentsByRef);