From 075d80d232ebea15341ab261d64a78e0034a74e9 Mon Sep 17 00:00:00 2001 From: Julien Lancelot Date: Thu, 23 Feb 2017 17:28:33 +0100 Subject: [PATCH] SONAR-8847 Persist copy_component_uuid for local views --- .../projectanalysis/component/Component.java | 7 ++ .../component/ComponentImpl.java | 11 ++- .../component/SubViewAttributes.java | 48 +++++++++++++ .../step/PersistComponentsStep.java | 1 + .../component/ComponentImplTest.java | 15 +++++ .../component/ReportComponent.java | 5 ++ .../component/ViewsComponent.java | 21 +++++- .../step/ViewsPersistComponentsStepTest.java | 67 +++++++++++++++++-- 8 files changed, 163 insertions(+), 12 deletions(-) create mode 100644 server/sonar-server/src/main/java/org/sonar/server/computation/task/projectanalysis/component/SubViewAttributes.java diff --git a/server/sonar-server/src/main/java/org/sonar/server/computation/task/projectanalysis/component/Component.java b/server/sonar-server/src/main/java/org/sonar/server/computation/task/projectanalysis/component/Component.java index 8426608c3c4..b89efeaad99 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/computation/task/projectanalysis/component/Component.java +++ b/server/sonar-server/src/main/java/org/sonar/server/computation/task/projectanalysis/component/Component.java @@ -105,4 +105,11 @@ public interface Component { * @throws IllegalStateException if the Component's type is not {@link Type#PROJECT_VIEW} */ ProjectViewAttributes getProjectViewAttributes(); + + /** + * The attributes of the Component if it's type is {@link Type#SUBVIEW}. + * + * @throws IllegalStateException if the Component's type is not {@link Type#SUBVIEW} + */ + SubViewAttributes getSubViewAttributes(); } diff --git a/server/sonar-server/src/main/java/org/sonar/server/computation/task/projectanalysis/component/ComponentImpl.java b/server/sonar-server/src/main/java/org/sonar/server/computation/task/projectanalysis/component/ComponentImpl.java index 1961da1920e..1a9c96008ef 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/computation/task/projectanalysis/component/ComponentImpl.java +++ b/server/sonar-server/src/main/java/org/sonar/server/computation/task/projectanalysis/component/ComponentImpl.java @@ -102,7 +102,12 @@ public class ComponentImpl implements Component { @Override public ProjectViewAttributes getProjectViewAttributes() { - throw new IllegalStateException("Only component of type PROJECT_VIEW have a FileAttributes object"); + throw new IllegalStateException("Only component of type PROJECT_VIEW have a ProjectViewAttributes object"); + } + + @Override + public SubViewAttributes getSubViewAttributes() { + throw new IllegalStateException("Only component of type SUBVIEW have a SubViewAttributes object"); } public static Builder builder(Type type) { @@ -125,7 +130,7 @@ public class ComponentImpl implements Component { private FileAttributes fileAttributes; private final List children = new ArrayList<>(); - private Builder(Type type){ + private Builder(Type type) { this.type = requireNonNull(type, "type can't be null"); } @@ -159,7 +164,7 @@ public class ComponentImpl implements Component { return this; } - public Builder setFileAttributes(@Nullable FileAttributes fileAttributes) { + public Builder setFileAttributes(@Nullable FileAttributes fileAttributes) { this.fileAttributes = fileAttributes; return this; } diff --git a/server/sonar-server/src/main/java/org/sonar/server/computation/task/projectanalysis/component/SubViewAttributes.java b/server/sonar-server/src/main/java/org/sonar/server/computation/task/projectanalysis/component/SubViewAttributes.java new file mode 100644 index 00000000000..e7739889544 --- /dev/null +++ b/server/sonar-server/src/main/java/org/sonar/server/computation/task/projectanalysis/component/SubViewAttributes.java @@ -0,0 +1,48 @@ +/* + * SonarQube + * Copyright (C) 2009-2017 SonarSource SA + * mailto:info AT sonarsource DOT com + * + * This program 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. + * + * This program 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.task.projectanalysis.component; + +import javax.annotation.CheckForNull; +import javax.annotation.Nullable; +import javax.annotation.concurrent.Immutable; + +@Immutable +public class SubViewAttributes { + private final String originalViewUuid; + + public SubViewAttributes(@Nullable String originalViewUuid) { + this.originalViewUuid = originalViewUuid; + } + + /** + * Return the original view uuid when the sub view is a local view + */ + @CheckForNull + public String getOriginalViewUuid() { + return originalViewUuid; + } + + @Override + public String toString() { + return "SubViewAttributes{" + + "originalViewUuid='" + originalViewUuid + '\'' + + '}'; + } +} diff --git a/server/sonar-server/src/main/java/org/sonar/server/computation/task/projectanalysis/step/PersistComponentsStep.java b/server/sonar-server/src/main/java/org/sonar/server/computation/task/projectanalysis/step/PersistComponentsStep.java index f20245b652f..6d793c70f9e 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/computation/task/projectanalysis/step/PersistComponentsStep.java +++ b/server/sonar-server/src/main/java/org/sonar/server/computation/task/projectanalysis/step/PersistComponentsStep.java @@ -320,6 +320,7 @@ public class PersistComponentsStep implements ComputationStep { res.setName(subView.getName()); res.setDescription(subView.getDescription()); res.setLongName(res.name()); + res.setCopyComponentUuid(subView.getSubViewAttributes().getOriginalViewUuid()); setRootAndParentModule(res, path); diff --git a/server/sonar-server/src/test/java/org/sonar/server/computation/task/projectanalysis/component/ComponentImplTest.java b/server/sonar-server/src/test/java/org/sonar/server/computation/task/projectanalysis/component/ComponentImplTest.java index e9843431e31..0f4f0b2d686 100644 --- a/server/sonar-server/src/test/java/org/sonar/server/computation/task/projectanalysis/component/ComponentImplTest.java +++ b/server/sonar-server/src/test/java/org/sonar/server/computation/task/projectanalysis/component/ComponentImplTest.java @@ -103,6 +103,21 @@ public class ComponentImplTest { }); } + @Test + public void getSubViewAttributes_throws_ISE_if_component_is_not_have_type_SUBVIEW() { + Arrays.stream(Component.Type.values()) + .filter(type -> type != FILE) + .forEach((componentType) -> { + ComponentImpl component = buildSimpleComponent(componentType, componentType.name()).build(); + try { + component.getSubViewAttributes(); + fail("A IllegalStateException should have been raised"); + } catch (IllegalStateException e) { + assertThat(e).hasMessage("Only component of type SUBVIEW have a SubViewAttributes object"); + } + }); + } + @Test public void isUnitTest_returns_true_if_IsTest_is_set_in_BatchComponent() { ComponentImpl component = buildSimpleComponent(FILE, "file").setFileAttributes(new FileAttributes(true, null, 1)).build(); diff --git a/server/sonar-server/src/test/java/org/sonar/server/computation/task/projectanalysis/component/ReportComponent.java b/server/sonar-server/src/test/java/org/sonar/server/computation/task/projectanalysis/component/ReportComponent.java index c90898d2242..3d11af6d2a4 100644 --- a/server/sonar-server/src/test/java/org/sonar/server/computation/task/projectanalysis/component/ReportComponent.java +++ b/server/sonar-server/src/test/java/org/sonar/server/computation/task/projectanalysis/component/ReportComponent.java @@ -116,6 +116,11 @@ public class ReportComponent implements Component { throw new IllegalStateException("Only component of type PROJECT_VIEW can have a ProjectViewAttributes object"); } + @Override + public SubViewAttributes getSubViewAttributes() { + throw new IllegalStateException("Only component of type SUBVIEW have a SubViewAttributes object"); + } + @Override public boolean equals(@Nullable Object o) { if (this == o) { diff --git a/server/sonar-server/src/test/java/org/sonar/server/computation/task/projectanalysis/component/ViewsComponent.java b/server/sonar-server/src/test/java/org/sonar/server/computation/task/projectanalysis/component/ViewsComponent.java index 384b57a9a14..06a331e68fa 100644 --- a/server/sonar-server/src/test/java/org/sonar/server/computation/task/projectanalysis/component/ViewsComponent.java +++ b/server/sonar-server/src/test/java/org/sonar/server/computation/task/projectanalysis/component/ViewsComponent.java @@ -46,10 +46,12 @@ public class ViewsComponent implements Component { private final List children; @CheckForNull private final ProjectViewAttributes projectViewAttributes; + @CheckForNull + private final SubViewAttributes subViewAttributes; private ViewsComponent(Type type, String key, @Nullable String uuid, @Nullable String name, @Nullable String description, List children, - @Nullable ProjectViewAttributes projectViewAttributes) { + @Nullable ProjectViewAttributes projectViewAttributes, @Nullable SubViewAttributes subViewAttributes) { checkArgument(type.isViewsType(), "Component type must be a Views type"); this.type = type; this.key = requireNonNull(key); @@ -58,6 +60,7 @@ public class ViewsComponent implements Component { this.description = description; this.children = ImmutableList.copyOf(children); this.projectViewAttributes = projectViewAttributes; + this.subViewAttributes = subViewAttributes; } public static Builder builder(Type type, String key) { @@ -80,6 +83,8 @@ public class ViewsComponent implements Component { private List children = new ArrayList<>(); @CheckForNull private ProjectViewAttributes projectViewAttributes; + @CheckForNull + private SubViewAttributes subViewAttributes; private Builder(Type type, String key) { this.type = type; @@ -111,6 +116,11 @@ public class ViewsComponent implements Component { return this; } + public Builder setSubViewAttributes(@Nullable SubViewAttributes subViewAttributes) { + this.subViewAttributes = subViewAttributes; + return this; + } + public Builder addChildren(Component... c) { for (Component viewsComponent : c) { checkArgument(viewsComponent.getType().isViewsType()); @@ -120,7 +130,7 @@ public class ViewsComponent implements Component { } public ViewsComponent build() { - return new ViewsComponent(type, key, uuid, name, description, children, projectViewAttributes); + return new ViewsComponent(type, key, uuid, name, description, children, projectViewAttributes, subViewAttributes); } } @@ -172,6 +182,12 @@ public class ViewsComponent implements Component { return this.projectViewAttributes; } + @Override + public SubViewAttributes getSubViewAttributes() { + checkState(this.type != Type.SUBVIEW || this.subViewAttributes != null, "A SubViewAttributes object should have been set"); + return this.subViewAttributes; + } + @Override public String toString() { return "ViewsComponent{" + @@ -181,6 +197,7 @@ public class ViewsComponent implements Component { ", name='" + name + '\'' + ", children=" + children + ", projectViewAttributes=" + projectViewAttributes + + ", subViewAttributes=" + subViewAttributes + '}'; } diff --git a/server/sonar-server/src/test/java/org/sonar/server/computation/task/projectanalysis/step/ViewsPersistComponentsStepTest.java b/server/sonar-server/src/test/java/org/sonar/server/computation/task/projectanalysis/step/ViewsPersistComponentsStepTest.java index 8cbeeda2489..ebb89f81bf2 100644 --- a/server/sonar-server/src/test/java/org/sonar/server/computation/task/projectanalysis/step/ViewsPersistComponentsStepTest.java +++ b/server/sonar-server/src/test/java/org/sonar/server/computation/task/projectanalysis/step/ViewsPersistComponentsStepTest.java @@ -21,6 +21,7 @@ package org.sonar.server.computation.task.projectanalysis.step; import java.text.SimpleDateFormat; import java.util.Date; +import javax.annotation.Nullable; import org.junit.Before; import org.junit.Rule; import org.junit.Test; @@ -37,6 +38,7 @@ import org.sonar.server.computation.task.projectanalysis.analysis.AnalysisMetada import org.sonar.server.computation.task.projectanalysis.component.MutableDbIdsRepositoryRule; import org.sonar.server.computation.task.projectanalysis.component.MutableDisabledComponentsHolder; import org.sonar.server.computation.task.projectanalysis.component.ProjectViewAttributes; +import org.sonar.server.computation.task.projectanalysis.component.SubViewAttributes; import org.sonar.server.computation.task.projectanalysis.component.TreeRootHolderRule; import org.sonar.server.computation.task.projectanalysis.component.ViewsComponent; import org.sonar.server.computation.task.step.ComputationStep; @@ -151,7 +153,7 @@ public class ViewsPersistComponentsStepTest extends BaseStepTest { treeRootHolder.setRoot( createViewBuilder() .addChildren( - createSubView1Builder().build()) + createSubView1Builder(null).build()) .build()); underTest.execute(); @@ -165,6 +167,22 @@ public class ViewsPersistComponentsStepTest extends BaseStepTest { assertDtoIsSubView1(viewDto, sv1Dto); } + @Test + public void persist_empty_subview_having_original_view_uuid() { + treeRootHolder.setRoot( + createViewBuilder() + .addChildren( + createSubView1Builder("ORIGINAL_UUID").build()) + .build()); + + underTest.execute(); + + assertRowsCountInTableProjects(2); + + ComponentDto subView = getComponentFromDb(SUBVIEW_1_KEY); + assertThat(subView.getCopyResourceUuid()).isEqualTo("ORIGINAL_UUID"); + } + @Test public void persist_existing_empty_subview_under_existing_view() { ComponentDto viewDto = newViewDto(dbTester.organizations().insert()); @@ -174,7 +192,7 @@ public class ViewsPersistComponentsStepTest extends BaseStepTest { treeRootHolder.setRoot( createViewBuilder() .addChildren( - createSubView1Builder().build()) + createSubView1Builder(null).build()) .build()); underTest.execute(); @@ -192,7 +210,7 @@ public class ViewsPersistComponentsStepTest extends BaseStepTest { treeRootHolder.setRoot( createViewBuilder() .addChildren( - createSubView1Builder().build()) + createSubView1Builder(null).build()) .build()); underTest.execute(); @@ -211,7 +229,7 @@ public class ViewsPersistComponentsStepTest extends BaseStepTest { treeRootHolder.setRoot( createViewBuilder() .addChildren( - createSubView1Builder() + createSubView1Builder(null) .addChildren( createProjectView1Builder(project, null).build()) .build()) @@ -307,12 +325,42 @@ public class ViewsPersistComponentsStepTest extends BaseStepTest { assertDtoIsProjectView1(pv1Dto, view, view, project2); } + @Test + public void update_copy_component_uuid_of_sub_view() { + OrganizationDto organizationDto = dbTester.organizations().insert(); + ComponentDto view = newViewDto(organizationDto); + ComponentDto subView = newSubViewDto(view).setCopyComponentUuid("OLD_COPY"); + persistComponents(view, subView); + + treeRootHolder.setRoot( + createViewBuilder() + .addChildren( + createSubView1Builder("NEW_COPY").build()) + .build()); + + underTest.execute(); + + // commit functional transaction -> copies B-fields to A-fields + dbClient.componentDao().applyBChangesForRootComponentUuid(dbTester.getSession(), view.uuid()); + dbTester.commit(); + + ComponentDto subViewReloaded = getComponentFromDb(SUBVIEW_1_KEY); + assertThat(subViewReloaded.getCopyResourceUuid()).isEqualTo("NEW_COPY"); + } + private static ViewsComponent.Builder createViewBuilder() { - return builder(VIEW, VIEW_KEY).setUuid(VIEW_UUID).setName(VIEW_NAME).setDescription(VIEW_DESCRIPTION); + return builder(VIEW, VIEW_KEY) + .setUuid(VIEW_UUID) + .setName(VIEW_NAME) + .setDescription(VIEW_DESCRIPTION); } - private ViewsComponent.Builder createSubView1Builder() { - return builder(SUBVIEW, SUBVIEW_1_KEY).setUuid(SUBVIEW_1_UUID).setName(SUBVIEW_1_NAME).setDescription(SUBVIEW_1_DESCRIPTION); + private ViewsComponent.Builder createSubView1Builder(@Nullable String originalViewUuid) { + return builder(SUBVIEW, SUBVIEW_1_KEY) + .setUuid(SUBVIEW_1_UUID) + .setName(SUBVIEW_1_NAME) + .setDescription(SUBVIEW_1_DESCRIPTION) + .setSubViewAttributes(new SubViewAttributes(originalViewUuid)); } private static ViewsComponent.Builder createProjectView1Builder(ComponentDto project, Long analysisDate) { @@ -346,6 +394,11 @@ public class ViewsPersistComponentsStepTest extends BaseStepTest { .setName(VIEW_NAME); } + private ComponentDto newSubViewDto(ComponentDto rootView) { + return ComponentTesting.newSubView(rootView, SUBVIEW_1_UUID, SUBVIEW_1_KEY) + .setName(SUBVIEW_1_NAME); + } + /** * Assertions to verify the DTO created from {@link #createViewBuilder()} */ -- 2.39.5