});
}
+ public List<ComponentDto> selectComponentsFromProjectUuid(DbSession session, String projectKey) {
+ return mapper(session).selectComponentsFromProjectUuid(projectKey);
+ }
+
public List<ComponentDto> selectByKeys(DbSession session, Collection<String> keys) {
return mapper(session).selectByKeys(keys);
}
return mapper(session).selectByKey(key);
}
- public void insert(DbSession session, ComponentDto item) {
- mapper(session).insert(item);
- }
-
- public void insert(DbSession session, Collection<ComponentDto> items) {
- for (ComponentDto item : items) {
- insert(session, item);
- }
- }
-
- public void insert(DbSession session, ComponentDto item, ComponentDto... others) {
- insert(session, Lists.asList(item, others));
- }
-
- public List<String> selectProjectUuids(DbSession session) {
- return mapper(session).selectProjectUuids();
- }
-
public List<UuidWithProjectUuidDto> selectAllViewsAndSubViews(DbSession session) {
return mapper(session).selectUuidsForQualifiers(Qualifiers.VIEW, Qualifiers.SUBVIEW);
}
parameters.put("qualifier", Qualifiers.PROJECT);
}
+ public void insert(DbSession session, ComponentDto item) {
+ mapper(session).insert(item);
+ }
+
+ public void insert(DbSession session, Collection<ComponentDto> items) {
+ for (ComponentDto item : items) {
+ insert(session, item);
+ }
+ }
+
+ public void insert(DbSession session, ComponentDto item, ComponentDto... others) {
+ insert(session, Lists.asList(item, others));
+ }
+
+ public void update(DbSession session, ComponentDto item) {
+ mapper(session).update(item);
+ }
+
private ComponentMapper mapper(DbSession session) {
return session.getMapper(ComponentMapper.class);
}
--- /dev/null
+/*
+ * 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 class Component {
+
+ private Long id;
+ private String uuid;
+ private String key;
+
+ public Long getId() {
+ return id;
+ }
+
+ public Component setId(Long id) {
+ this.id = id;
+ return this;
+ }
+
+ public String getKey() {
+ return key;
+ }
+
+ public Component setKey(String key) {
+ this.key = key;
+ return this;
+ }
+
+ public String getUuid() {
+ return uuid;
+ }
+
+ public Component setUuid(String uuid) {
+ this.uuid = uuid;
+ return this;
+ }
+}
--- /dev/null
+/*
+ * 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 org.sonar.batch.protocol.output.BatchReportReader;
+import org.sonar.server.computation.component.Component;
+
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * To be finished
+ */
+public class ComponentsCache {
+
+ private final Map<Integer, Component> componentsByRef;
+
+ public ComponentsCache(final BatchReportReader reader) {
+ this.componentsByRef = new HashMap<>();
+ }
+
+ public Component getComponent(int componentRef) {
+ // TODO should we return null or fail on unknown component ?
+ return null;
+ }
+}
--- /dev/null
+/*
+ * 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.collect.Maps;
+import org.sonar.api.resources.Qualifiers;
+import org.sonar.api.utils.internal.Uuids;
+import org.sonar.batch.protocol.Constants;
+import org.sonar.batch.protocol.output.BatchReport;
+import org.sonar.batch.protocol.output.BatchReportReader;
+import org.sonar.core.component.ComponentDto;
+import org.sonar.core.component.ComponentKeys;
+import org.sonar.core.persistence.DbSession;
+import org.sonar.core.util.NonNullInputFunction;
+import org.sonar.server.computation.ComputationContext;
+import org.sonar.server.computation.component.Component;
+import org.sonar.server.db.DbClient;
+
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * To be finished
+ */
+public class FeedComponentsCacheStep implements ComputationStep {
+
+ private final DbClient dbClient;
+
+ public FeedComponentsCacheStep(DbClient dbClient) {
+ this.dbClient = dbClient;
+ }
+
+ @Override
+ public String[] supportedProjectQualifiers() {
+ return new String[] {Qualifiers.PROJECT};
+ }
+
+ @Override
+ public void execute(ComputationContext context) {
+ DbSession session = dbClient.openSession(false);
+ try {
+ List<ComponentDto> components = dbClient.componentDao().selectComponentsFromProjectUuid(session, context.getProject().uuid());
+ Map<String, ComponentDto> componentDtosByKey = componentDtosByKey(components);
+ Map<Integer, Component> componentsByRef = new HashMap<>();
+ int rootComponentRef = context.getReportMetadata().getRootComponentRef();
+ recursivelyProcessComponent(context, rootComponentRef, context.getReportReader().readComponent(rootComponentRef), componentDtosByKey, componentsByRef);
+ } finally {
+ session.close();
+ }
+ }
+
+ private void recursivelyProcessComponent(ComputationContext context, int componentRef, BatchReport.Component nearestModule,
+ Map<String, ComponentDto> componentDtosByKey, Map<Integer, Component> componentsByRef) {
+ BatchReportReader reportReader = context.getReportReader();
+ BatchReport.Component reportComponent = reportReader.readComponent(componentRef);
+ String componentKey = ComponentKeys.createKey(nearestModule.getKey(), reportComponent.getPath(), context.getReportMetadata().getBranch());
+
+ Component component = new Component().setKey(componentKey);
+ ComponentDto componentDto = componentDtosByKey.get(componentKey);
+ if (componentDto == null) {
+ component.setUuid(Uuids.create());
+ } else {
+ component.setId(component.getId());
+ component.setKey(componentKey);
+ }
+
+ for (Integer childRef : reportComponent.getChildRefList()) {
+ // If current component is not a module or a project, we need to keep the parent reference to the nearest module
+ BatchReport.Component nextNearestModule = !reportComponent.getType().equals(Constants.ComponentType.PROJECT) && !reportComponent.getType().equals(Constants.ComponentType.MODULE) ?
+ nearestModule : reportComponent;
+ recursivelyProcessComponent(context, childRef, nextNearestModule, componentDtosByKey, componentsByRef);
+ }
+ }
+
+ private Map<String, ComponentDto> componentDtosByKey(List<ComponentDto> components){
+ return Maps.uniqueIndex(components, new NonNullInputFunction<ComponentDto, String>() {
+ @Override
+ public String doApply(ComponentDto input) {
+ return input.key();
+ }
+ });
+ }
+
+ @Override
+ public String getDescription() {
+ return "Feed components cache";
+ }
+}
--- /dev/null
+/*
+ * 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.collect.Maps;
+import org.apache.commons.io.FilenameUtils;
+import org.apache.commons.lang.ObjectUtils;
+import org.apache.commons.lang.StringUtils;
+import org.sonar.api.resources.Qualifiers;
+import org.sonar.api.resources.Scopes;
+import org.sonar.api.utils.internal.Uuids;
+import org.sonar.batch.protocol.Constants;
+import org.sonar.batch.protocol.output.BatchReport;
+import org.sonar.batch.protocol.output.BatchReportReader;
+import org.sonar.core.component.ComponentDto;
+import org.sonar.core.component.ComponentKeys;
+import org.sonar.core.persistence.DbSession;
+import org.sonar.core.util.NonNullInputFunction;
+import org.sonar.server.computation.ComputationContext;
+import org.sonar.server.db.DbClient;
+
+import javax.annotation.Nullable;
+
+import java.util.List;
+import java.util.Map;
+
+public class PersistComponentsStep implements ComputationStep {
+
+ private final DbClient dbClient;
+
+ public PersistComponentsStep(DbClient dbClient) {
+ this.dbClient = dbClient;
+ }
+
+ @Override
+ public String[] supportedProjectQualifiers() {
+ return new String[] {Qualifiers.PROJECT};
+ }
+
+ @Override
+ public void execute(ComputationContext context) {
+ DbSession session = dbClient.openSession(false);
+ try {
+ List<ComponentDto> components = dbClient.componentDao().selectComponentsFromProjectUuid(session, context.getProject().uuid());
+ Map<String, ComponentDto> componentDtosByKey = componentDtosByKey(components);
+ int rootComponentRef = context.getReportMetadata().getRootComponentRef();
+ ComponentContext componentContext = new ComponentContext(context, session, componentDtosByKey);
+ recursivelyProcessComponent(componentContext, rootComponentRef, null);
+ session.commit();
+ } finally {
+ session.close();
+ }
+ }
+
+ private void recursivelyProcessComponent(ComponentContext componentContext, int componentRef, @Nullable ComponentDto moduleParent) {
+ BatchReportReader reportReader = componentContext.context.getReportReader();
+ BatchReport.Component reportComponent = reportReader.readComponent(componentRef);
+ ComponentDto componentDto = processComponent(componentContext, reportComponent, moduleParent);
+
+ for (Integer childRef : reportComponent.getChildRefList()) {
+ // If current component is not a module or a project, we need to keep the parent reference to the nearest module
+ ComponentDto nextModuleParent = !reportComponent.getType().equals(Constants.ComponentType.PROJECT) && !reportComponent.getType().equals(Constants.ComponentType.MODULE) ?
+ moduleParent : componentDto;
+ recursivelyProcessComponent(componentContext, childRef, nextModuleParent);
+ }
+ }
+
+ private ComponentDto processComponent(ComponentContext componentContext, BatchReport.Component reportComponent, @Nullable ComponentDto moduleParent) {
+ String path = reportComponent.hasPath() ? reportComponent.getPath() : null;
+ String branch = componentContext.context.getReportMetadata().hasBranch() ? componentContext.context.getReportMetadata().getBranch() : null;
+ String componentKey = reportComponent.hasKey() || moduleParent == null ?
+ ComponentKeys.createKey(reportComponent.getKey(), branch) :
+ ComponentKeys.createEffectiveKey(moduleParent.getKey(), path);
+ ComponentDto existingComponent = componentContext.componentDtosByKey.get(componentKey);
+ if (existingComponent == null) {
+ ComponentDto component = createComponent(reportComponent, componentKey, Uuids.create(), moduleParent);
+ dbClient.componentDao().insert(componentContext.dbSession, component);
+ return component;
+ } else {
+ ComponentDto component = createComponent(reportComponent, componentKey, existingComponent.uuid(), moduleParent);
+ if (updateComponent(existingComponent, component)) {
+ dbClient.componentDao().update(componentContext.dbSession, existingComponent);
+ }
+ return existingComponent;
+ }
+ }
+
+ private ComponentDto createComponent(BatchReport.Component reportComponent, String componentKey, String uuid, @Nullable ComponentDto parentModule) {
+ ComponentDto component = new ComponentDto();
+ component.setUuid(uuid);
+ component.setKey(componentKey);
+ component.setDeprecatedKey(componentKey);
+ component.setEnabled(true);
+ component.setScope(getScope(reportComponent));
+ component.setQualifier(getQualifier(reportComponent));
+ component.setName(getFileName(reportComponent));
+
+ if (isProjectOrModule(reportComponent)) {
+ component.setLongName(component.name());
+ if (reportComponent.hasDescription()) {
+ component.setDescription(reportComponent.getDescription());
+ }
+ } else {
+ component.setLongName(reportComponent.getPath());
+ if (reportComponent.hasPath()) {
+ component.setPath(reportComponent.getPath());
+ }
+ if (reportComponent.hasLanguage()) {
+ component.setLanguage(reportComponent.getLanguage());
+ }
+ }
+ if (parentModule != null) {
+ component.setParentProjectId(parentModule.getId());
+ component.setProjectUuid(parentModule.projectUuid());
+ component.setModuleUuid(parentModule.uuid());
+ component.setModuleUuidPath(reportComponent.getType().equals(Constants.ComponentType.MODULE) ?
+ parentModule.moduleUuidPath() + component.uuid() + ComponentDto.MODULE_UUID_PATH_SEP :
+ parentModule.moduleUuidPath());
+ } else {
+ component.setProjectUuid(uuid);
+ component.setModuleUuidPath(ComponentDto.MODULE_UUID_PATH_SEP + component.uuid() + ComponentDto.MODULE_UUID_PATH_SEP);
+ }
+ return component;
+ }
+
+ private boolean updateComponent(ComponentDto existingComponent, ComponentDto newComponent) {
+ boolean isUpdated = false;
+ if (Scopes.PROJECT.equals(existingComponent.scope())) {
+ if (!newComponent.name().equals(existingComponent.name())) {
+ existingComponent.setName(newComponent.name());
+ isUpdated = true;
+ }
+ if (!StringUtils.equals(existingComponent.description(), newComponent.description())) {
+ existingComponent.setDescription(newComponent.description());
+ isUpdated = true;
+ }
+ }
+
+ if (!StringUtils.equals(existingComponent.moduleUuid(), newComponent.moduleUuid())) {
+ existingComponent.setModuleUuid(newComponent.moduleUuid());
+ isUpdated = true;
+ }
+ if (!existingComponent.moduleUuidPath().equals(newComponent.moduleUuidPath())) {
+ existingComponent.setModuleUuidPath(newComponent.moduleUuidPath());
+ isUpdated = true;
+ }
+ if (!ObjectUtils.equals(existingComponent.parentProjectId(), newComponent.parentProjectId())) {
+ existingComponent.setParentProjectId(newComponent.parentProjectId());
+ isUpdated = true;
+ }
+
+ return isUpdated;
+ }
+
+ private static boolean isProjectOrModule(BatchReport.Component reportComponent) {
+ return reportComponent.getType().equals(Constants.ComponentType.PROJECT) || reportComponent.getType().equals(Constants.ComponentType.MODULE);
+ }
+
+ private static String getScope(BatchReport.Component reportComponent) {
+ switch (reportComponent.getType()) {
+ case PROJECT:
+ return Scopes.PROJECT;
+ case MODULE:
+ return Scopes.PROJECT;
+ case DIRECTORY:
+ return Scopes.DIRECTORY;
+ case FILE:
+ return Scopes.FILE;
+ }
+ throw new IllegalArgumentException(String.format("Unknown type '%s'", reportComponent.getType()));
+ }
+
+ private static String getQualifier(BatchReport.Component reportComponent) {
+ switch (reportComponent.getType()) {
+ case PROJECT:
+ return Qualifiers.PROJECT;
+ case MODULE:
+ return Qualifiers.MODULE;
+ case DIRECTORY:
+ return Qualifiers.DIRECTORY;
+ case FILE:
+ return !reportComponent.getIsTest() ? Qualifiers.FILE : Qualifiers.UNIT_TEST_FILE;
+ }
+ throw new IllegalArgumentException(String.format("Unknown type '%s'", reportComponent.getType()));
+ }
+
+ private static String getFileName(BatchReport.Component reportComponent) {
+ String path = reportComponent.getPath();
+ if (reportComponent.getType() == Constants.ComponentType.PROJECT || reportComponent.getType() == Constants.ComponentType.MODULE) {
+ return reportComponent.getName();
+ } else if (reportComponent.getType().equals(Constants.ComponentType.DIRECTORY)) {
+ return path;
+ } else {
+ return FilenameUtils.getName(path);
+ }
+ }
+
+ private Map<String, ComponentDto> componentDtosByKey(List<ComponentDto> components) {
+ return Maps.uniqueIndex(components, new NonNullInputFunction<ComponentDto, String>() {
+ @Override
+ public String doApply(ComponentDto input) {
+ return input.key();
+ }
+ });
+ }
+
+ private static class ComponentContext {
+ private final ComputationContext context;
+ private final Map<String, ComponentDto> componentDtosByKey;
+ private final DbSession dbSession;
+
+ public ComponentContext(ComputationContext context, DbSession dbSession, Map<String, ComponentDto> componentDtosByKey) {
+ this.componentDtosByKey = componentDtosByKey;
+ this.context = context;
+ this.dbSession = dbSession;
+ }
+ }
+
+ @Override
+ public String getDescription() {
+ return "Feed components cache";
+ }
+}
assertThat(result.path()).isNull();
assertThat(result.name()).isEqualTo("Struts");
assertThat(result.longName()).isEqualTo("Apache Struts");
+ assertThat(result.description()).isEqualTo("the description");
assertThat(result.qualifier()).isEqualTo("TRK");
assertThat(result.scope()).isEqualTo("PRJ");
assertThat(result.language()).isNull();
assertThat(sut.selectEnabledFilesFromProject(session, "unknown")).isEmpty();
}
+ @Test
+ public void select_components_from_project() {
+ db.prepareDbUnit(getClass(), "multi-modules.xml");
+
+ List<ComponentDto> components = sut.selectComponentsFromProjectUuid(session, "ABCD");
+ assertThat(components).hasSize(5);
+
+ assertThat(sut.selectComponentsFromProjectUuid(session, "UNKNOWN")).isEmpty();
+ }
+
+ @Test
+ public void select_views_and_sub_views() {
+ db.prepareDbUnit(getClass(), "shared_views.xml");
+
+ assertThat(sut.selectAllViewsAndSubViews(session)).extracting("uuid").containsOnly("ABCD", "EFGH", "FGHI", "IJKL");
+ assertThat(sut.selectAllViewsAndSubViews(session)).extracting("projectUuid").containsOnly("ABCD", "EFGH", "IJKL");
+ }
+
+ @Test
+ public void select_projects_from_view() {
+ db.prepareDbUnit(getClass(), "shared_views.xml");
+
+ assertThat(sut.selectProjectsFromView(session, "ABCD", "ABCD")).containsOnly("JKLM");
+ assertThat(sut.selectProjectsFromView(session, "EFGH", "EFGH")).containsOnly("KLMN", "JKLM");
+ assertThat(sut.selectProjectsFromView(session, "FGHI", "EFGH")).containsOnly("JKLM");
+ assertThat(sut.selectProjectsFromView(session, "IJKL", "IJKL")).isEmpty();
+ assertThat(sut.selectProjectsFromView(session, "Unknown", "Unknown")).isEmpty();
+ }
+
+ @Test
+ public void select_provisioned_projects() {
+ db.prepareDbUnit(getClass(), "select_provisioned_projects.xml");
+
+ List<ComponentDto> result = sut.selectProvisionedProjects(session, new SearchOptions(), null);
+ ComponentDto project = result.get(0);
+
+ assertThat(result).hasSize(1);
+ assertThat(project.getKey()).isEqualTo("org.provisioned.project");
+ }
+
+ @Test
+ public void count_provisioned_projects() {
+ db.prepareDbUnit(getClass(), "select_provisioned_projects.xml");
+
+ int numberOfProjects = sut.countProvisionedProjects(session, null);
+
+ assertThat(numberOfProjects).isEqualTo(1);
+ }
+
+ @Test
+ public void select_ghost_projects() throws Exception {
+ db.prepareDbUnit(getClass(), "select_ghost_projects.xml");
+
+ List<ComponentDto> result = sut.selectGhostProjects(session, null, new SearchOptions());
+
+ assertThat(result).hasSize(1);
+ assertThat(result.get(0).key()).isEqualTo("org.ghost.project");
+ assertThat(sut.countGhostProjects(session, null)).isEqualTo(1);
+ }
+
@Test
public void insert() {
db.prepareDbUnit(getClass(), "empty.xml");
.setQualifier("FIL")
.setScope("FIL")
.setLanguage("java")
+ .setDescription("description")
.setPath("src/org/struts/RequestContext.java")
.setParentProjectId(3L)
.setCopyResourceId(5L)
}
@Test
- public void find_project_uuids() {
- db.prepareDbUnit(getClass(), "find_project_uuids.xml");
-
- assertThat(sut.selectProjectUuids(session)).containsExactly("ABCD");
- }
-
- @Test
- public void select_views_and_sub_views() {
- db.prepareDbUnit(getClass(), "shared_views.xml");
-
- assertThat(sut.selectAllViewsAndSubViews(session)).extracting("uuid").containsOnly("ABCD", "EFGH", "FGHI", "IJKL");
- assertThat(sut.selectAllViewsAndSubViews(session)).extracting("projectUuid").containsOnly("ABCD", "EFGH", "IJKL");
- }
-
- @Test
- public void select_projects_from_view() {
- db.prepareDbUnit(getClass(), "shared_views.xml");
-
- assertThat(sut.selectProjectsFromView(session, "ABCD", "ABCD")).containsOnly("JKLM");
- assertThat(sut.selectProjectsFromView(session, "EFGH", "EFGH")).containsOnly("KLMN", "JKLM");
- assertThat(sut.selectProjectsFromView(session, "FGHI", "EFGH")).containsOnly("JKLM");
- assertThat(sut.selectProjectsFromView(session, "IJKL", "IJKL")).isEmpty();
- assertThat(sut.selectProjectsFromView(session, "Unknown", "Unknown")).isEmpty();
- }
-
- @Test
- public void select_provisioned_projects() {
- db.prepareDbUnit(getClass(), "select_provisioned_projects.xml");
-
- List<ComponentDto> result = sut.selectProvisionedProjects(session, new SearchOptions(), null);
- ComponentDto project = result.get(0);
-
- assertThat(result).hasSize(1);
- assertThat(project.getKey()).isEqualTo("org.provisioned.project");
- }
-
- @Test
- public void count_provisioned_projects() {
- db.prepareDbUnit(getClass(), "select_provisioned_projects.xml");
+ public void update() {
+ db.prepareDbUnit(getClass(), "update.xml");
- int numberOfProjects = sut.countProvisionedProjects(session, null);
-
- assertThat(numberOfProjects).isEqualTo(1);
- }
-
- @Test
- public void select_ghost_projects() throws Exception {
- db.prepareDbUnit(getClass(), "select_ghost_projects.xml");
+ ComponentDto componentDto = new ComponentDto()
+ .setUuid("GHIJ")
+ .setProjectUuid("DCBA")
+ .setModuleUuid("HGFE")
+ .setModuleUuidPath(".DCBA.HGFE.")
+ .setKey("org.struts:struts-core:src/org/struts/RequestContext2.java")
+ .setDeprecatedKey("org.struts:struts-core:src/org/struts/RequestContext2.java")
+ .setName("RequestContext2.java")
+ .setLongName("org.struts.RequestContext2")
+ .setQualifier("LIF")
+ .setScope("LIF")
+ .setLanguage("java2")
+ .setDescription("description2")
+ .setPath("src/org/struts/RequestContext2.java")
+ .setParentProjectId(4L)
+ .setCopyResourceId(6L)
+ .setEnabled(false)
+ .setAuthorizationUpdatedAt(12345678910L);
- List<ComponentDto> result = sut.selectGhostProjects(session, null, new SearchOptions());
+ sut.update(session, componentDto);
+ session.commit();
- assertThat(result).hasSize(1);
- assertThat(result.get(0).key()).isEqualTo("org.ghost.project");
- assertThat(sut.countGhostProjects(session, null)).isEqualTo(1);
+ db.assertDbUnit(getClass(), "update-result.xml", "projects");
}
}
--- /dev/null
+/*
+ * 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 org.junit.After;
+import org.junit.Before;
+import org.junit.ClassRule;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.experimental.categories.Category;
+import org.junit.rules.TemporaryFolder;
+import org.sonar.batch.protocol.Constants;
+import org.sonar.batch.protocol.output.BatchReport;
+import org.sonar.batch.protocol.output.BatchReportReader;
+import org.sonar.batch.protocol.output.BatchReportWriter;
+import org.sonar.core.component.ComponentDto;
+import org.sonar.core.persistence.DbSession;
+import org.sonar.core.persistence.DbTester;
+import org.sonar.server.component.ComponentTesting;
+import org.sonar.server.component.db.ComponentDao;
+import org.sonar.server.computation.ComputationContext;
+import org.sonar.server.db.DbClient;
+import org.sonar.test.DbTests;
+
+import java.io.File;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+@Category(DbTests.class)
+public class PersistComponentsStepTest extends BaseStepTest {
+
+ @ClassRule
+ public static DbTester dbTester = new DbTester();
+
+ @Rule
+ public TemporaryFolder temp = new TemporaryFolder();
+
+ File reportDir;
+
+ DbSession session;
+
+ DbClient dbClient;
+
+ PersistComponentsStep sut;
+
+ @Before
+ public void setup() throws Exception {
+ dbTester.truncateTables();
+ session = dbTester.myBatis().openSession(false);
+ dbClient = new DbClient(dbTester.database(), dbTester.myBatis(), new ComponentDao());
+
+ reportDir = temp.newFolder();
+
+ sut = new PersistComponentsStep(dbClient);
+ }
+
+ @Override
+ protected ComputationStep step() {
+ return sut;
+ }
+
+ @After
+ public void tearDown() {
+ session.close();
+ }
+
+ @Test
+ public void persist_components() 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")
+ .setName("Project")
+ .setDescription("Project description")
+ .addChildRef(2)
+ .build());
+ writer.writeComponent(BatchReport.Component.newBuilder()
+ .setRef(2)
+ .setType(Constants.ComponentType.MODULE)
+ .setKey("MODULE_KEY")
+ .setName("Module")
+ .setDescription("Module description")
+ .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")
+ .setLanguage("java")
+ .build());
+
+ sut.execute(new ComputationContext(new BatchReportReader(reportDir), ComponentTesting.newProjectDto()));
+
+ assertThat(dbTester.countRowsOfTable("projects")).isEqualTo(4);
+
+ ComponentDto project = dbClient.componentDao().selectNullableByKey(session, "PROJECT_KEY");
+ assertThat(project).isNotNull();
+ assertThat(project.name()).isEqualTo("Project");
+ assertThat(project.description()).isEqualTo("Project description");
+ assertThat(project.uuid()).isNotNull();
+ assertThat(project.moduleUuid()).isNull();
+ assertThat(project.moduleUuidPath()).isEqualTo("." + project.uuid() + ".");
+ assertThat(project.projectUuid()).isEqualTo(project.uuid());
+ assertThat(project.qualifier()).isEqualTo("TRK");
+ assertThat(project.scope()).isEqualTo("PRJ");
+ assertThat(project.parentProjectId()).isNull();
+
+ ComponentDto module = dbClient.componentDao().selectNullableByKey(session, "MODULE_KEY");
+ assertThat(module).isNotNull();
+ assertThat(module.name()).isEqualTo("Module");
+ assertThat(module.description()).isEqualTo("Module description");
+ assertThat(module.uuid()).isNotNull();
+ assertThat(module.moduleUuid()).isEqualTo(project.uuid());
+ assertThat(module.moduleUuidPath()).isEqualTo(project.moduleUuidPath() + module.uuid() + ".");
+ assertThat(module.projectUuid()).isEqualTo(project.uuid());
+ assertThat(module.qualifier()).isEqualTo("BRC");
+ assertThat(module.scope()).isEqualTo("PRJ");
+ assertThat(module.parentProjectId()).isEqualTo(project.getId());
+
+ ComponentDto directory = dbClient.componentDao().selectNullableByKey(session, "MODULE_KEY:src/main/java/dir");
+ assertThat(directory).isNotNull();
+ assertThat(directory.name()).isEqualTo("src/main/java/dir");
+ assertThat(directory.path()).isEqualTo("src/main/java/dir");
+ assertThat(directory.uuid()).isNotNull();
+ assertThat(directory.moduleUuid()).isEqualTo(module.uuid());
+ assertThat(directory.moduleUuidPath()).isEqualTo(module.moduleUuidPath());
+ assertThat(directory.projectUuid()).isEqualTo(project.uuid());
+ assertThat(directory.qualifier()).isEqualTo("DIR");
+ assertThat(directory.scope()).isEqualTo("DIR");
+ assertThat(directory.parentProjectId()).isEqualTo(module.getId());
+
+ ComponentDto file = dbClient.componentDao().selectNullableByKey(session, "MODULE_KEY:src/main/java/dir/Foo.java");
+ assertThat(file).isNotNull();
+ assertThat(file.name()).isEqualTo("Foo.java");
+ assertThat(file.path()).isEqualTo("src/main/java/dir/Foo.java");
+ assertThat(file.language()).isEqualTo("java");
+ assertThat(file.uuid()).isNotNull();
+ assertThat(file.moduleUuid()).isEqualTo(module.uuid());
+ assertThat(file.moduleUuidPath()).isEqualTo(module.moduleUuidPath());
+ assertThat(file.projectUuid()).isEqualTo(project.uuid());
+ assertThat(file.qualifier()).isEqualTo("FIL");
+ assertThat(file.scope()).isEqualTo("FIL");
+ assertThat(file.parentProjectId()).isEqualTo(module.getId());
+ }
+
+ @Test
+ public void persist_file_directly_attached_on_root_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")
+ .setName("Project")
+ .addChildRef(2)
+ .build());
+ writer.writeComponent(BatchReport.Component.newBuilder()
+ .setRef(2)
+ .setType(Constants.ComponentType.DIRECTORY)
+ .setPath("/")
+ .addChildRef(3)
+ .build());
+ writer.writeComponent(BatchReport.Component.newBuilder()
+ .setRef(3)
+ .setType(Constants.ComponentType.FILE)
+ .setPath("pom.xml")
+ .build());
+
+ sut.execute(new ComputationContext(new BatchReportReader(reportDir), ComponentTesting.newProjectDto()));
+
+ ComponentDto directory = dbClient.componentDao().selectNullableByKey(session, "PROJECT_KEY:/");
+ assertThat(directory).isNotNull();
+ assertThat(directory.name()).isEqualTo("/");
+ assertThat(directory.path()).isEqualTo("/");
+
+ ComponentDto file = dbClient.componentDao().selectNullableByKey(session, "PROJECT_KEY:pom.xml");
+ assertThat(file).isNotNull();
+ assertThat(file.name()).isEqualTo("pom.xml");
+ assertThat(file.path()).isEqualTo("pom.xml");
+ }
+
+ @Test
+ public void persist_unit_test() 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")
+ .setName("Project")
+ .addChildRef(2)
+ .build());
+ writer.writeComponent(BatchReport.Component.newBuilder()
+ .setRef(2)
+ .setType(Constants.ComponentType.DIRECTORY)
+ .setPath("src/test/java/dir")
+ .addChildRef(3)
+ .build());
+ writer.writeComponent(BatchReport.Component.newBuilder()
+ .setRef(3)
+ .setType(Constants.ComponentType.FILE)
+ .setPath("src/test/java/dir/FooTest.java")
+ .setIsTest(true)
+ .build());
+
+ sut.execute(new ComputationContext(new BatchReportReader(reportDir), ComponentTesting.newProjectDto()));
+
+ ComponentDto file = dbClient.componentDao().selectNullableByKey(session, "PROJECT_KEY:src/test/java/dir/FooTest.java");
+ assertThat(file).isNotNull();
+ assertThat(file.name()).isEqualTo("FooTest.java");
+ assertThat(file.path()).isEqualTo("src/test/java/dir/FooTest.java");
+ assertThat(file.qualifier()).isEqualTo("UTS");
+ assertThat(file.scope()).isEqualTo("FIL");
+ }
+
+ @Test
+ public void use_latest_module_for_files_key() 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")
+ .setName("Project")
+ .addChildRef(2)
+ .build());
+ writer.writeComponent(BatchReport.Component.newBuilder()
+ .setRef(2)
+ .setType(Constants.ComponentType.MODULE)
+ .setKey("MODULE_KEY")
+ .setName("Module")
+ .addChildRef(3)
+ .build());
+ writer.writeComponent(BatchReport.Component.newBuilder()
+ .setRef(3)
+ .setType(Constants.ComponentType.MODULE)
+ .setKey("SUB_MODULE_KEY")
+ .setName("Sub Module")
+ .addChildRef(4)
+ .build());
+ writer.writeComponent(BatchReport.Component.newBuilder()
+ .setRef(4)
+ .setType(Constants.ComponentType.DIRECTORY)
+ .setPath("src/main/java/dir")
+ .addChildRef(5)
+ .build());
+ writer.writeComponent(BatchReport.Component.newBuilder()
+ .setRef(5)
+ .setType(Constants.ComponentType.FILE)
+ .setPath("src/main/java/dir/Foo.java")
+ .build());
+
+ sut.execute(new ComputationContext(new BatchReportReader(reportDir), ComponentTesting.newProjectDto()));
+
+ assertThat(dbClient.componentDao().selectNullableByKey(session, "MODULE_KEY")).isNotNull();
+ assertThat(dbClient.componentDao().selectNullableByKey(session, "SUB_MODULE_KEY")).isNotNull();
+ assertThat(dbClient.componentDao().selectNullableByKey(session, "SUB_MODULE_KEY:src/main/java/dir")).isNotNull();
+ assertThat(dbClient.componentDao().selectNullableByKey(session, "SUB_MODULE_KEY:src/main/java/dir/Foo.java")).isNotNull();
+ }
+
+ @Test
+ public void persist_with_branch() throws Exception {
+ File reportDir = temp.newFolder();
+ BatchReportWriter writer = new BatchReportWriter(reportDir);
+ writer.writeMetadata(BatchReport.Metadata.newBuilder()
+ .setRootComponentRef(1)
+ .setBranch("origin/master")
+ .build());
+
+ writer.writeComponent(BatchReport.Component.newBuilder()
+ .setRef(1)
+ .setType(Constants.ComponentType.PROJECT)
+ .setKey("PROJECT_KEY")
+ .setName("Project")
+ .addChildRef(2)
+ .build());
+ writer.writeComponent(BatchReport.Component.newBuilder()
+ .setRef(2)
+ .setType(Constants.ComponentType.MODULE)
+ .setKey("MODULE_KEY")
+ .setName("Module")
+ .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());
+
+ sut.execute(new ComputationContext(new BatchReportReader(reportDir), ComponentTesting.newProjectDto()));
+
+ assertThat(dbTester.countRowsOfTable("projects")).isEqualTo(4);
+ assertThat(dbClient.componentDao().selectNullableByKey(session, "PROJECT_KEY:origin/master")).isNotNull();
+ assertThat(dbClient.componentDao().selectNullableByKey(session, "MODULE_KEY:origin/master")).isNotNull();
+ assertThat(dbClient.componentDao().selectNullableByKey(session, "MODULE_KEY:origin/master:src/main/java/dir")).isNotNull();
+ assertThat(dbClient.componentDao().selectNullableByKey(session, "MODULE_KEY:origin/master:src/main/java/dir/Foo.java")).isNotNull();
+ }
+
+ @Test
+ public void persist_only_new_components() throws Exception {
+ // Project amd module already exists
+ ComponentDto project = ComponentTesting.newProjectDto("ABCD").setKey("PROJECT_KEY").setName("Project");
+ dbClient.componentDao().insert(session, project);
+ ComponentDto module = ComponentTesting.newModuleDto("BCDE", project).setKey("MODULE_KEY").setName("Module");
+ dbClient.componentDao().insert(session, module);
+ session.commit();
+
+ 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")
+ .setName("Project")
+ .addChildRef(2)
+ .build());
+ writer.writeComponent(BatchReport.Component.newBuilder()
+ .setRef(2)
+ .setType(Constants.ComponentType.MODULE)
+ .setKey("MODULE_KEY")
+ .setName("Module")
+ .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());
+
+ sut.execute(new ComputationContext(new BatchReportReader(reportDir), project));
+
+ assertThat(dbTester.countRowsOfTable("projects")).isEqualTo(4);
+
+ ComponentDto projectReloaded = dbClient.componentDao().selectNullableByKey(session, "PROJECT_KEY");
+ assertThat(projectReloaded.getId()).isEqualTo(project.getId());
+ assertThat(projectReloaded.uuid()).isEqualTo(project.uuid());
+
+ ComponentDto moduleReloaded = dbClient.componentDao().selectNullableByKey(session, "MODULE_KEY");
+ assertThat(moduleReloaded.getId()).isEqualTo(module.getId());
+ assertThat(moduleReloaded.uuid()).isEqualTo(module.uuid());
+ assertThat(moduleReloaded.moduleUuid()).isEqualTo(module.moduleUuid());
+ assertThat(moduleReloaded.moduleUuidPath()).isEqualTo(module.moduleUuidPath());
+ assertThat(moduleReloaded.projectUuid()).isEqualTo(module.projectUuid());
+ assertThat(moduleReloaded.parentProjectId()).isEqualTo(module.parentProjectId());
+
+ ComponentDto directory = dbClient.componentDao().selectNullableByKey(session, "MODULE_KEY:src/main/java/dir");
+ assertThat(directory).isNotNull();
+ assertThat(directory.moduleUuid()).isEqualTo(module.uuid());
+ assertThat(directory.moduleUuidPath()).isEqualTo(module.moduleUuidPath());
+ assertThat(directory.projectUuid()).isEqualTo(project.uuid());
+ assertThat(directory.parentProjectId()).isEqualTo(module.getId());
+
+ ComponentDto file = dbClient.componentDao().selectNullableByKey(session, "MODULE_KEY:src/main/java/dir/Foo.java");
+ assertThat(file).isNotNull();
+ assertThat(file.moduleUuid()).isEqualTo(module.uuid());
+ assertThat(file.moduleUuidPath()).isEqualTo(module.moduleUuidPath());
+ assertThat(file.projectUuid()).isEqualTo(project.uuid());
+ assertThat(file.parentProjectId()).isEqualTo(module.getId());
+ }
+
+ @Test
+ public void nothing_to_persist() throws Exception {
+ ComponentDto project = ComponentTesting.newProjectDto("ABCD").setKey("PROJECT_KEY").setName("Project");
+ dbClient.componentDao().insert(session, project);
+ ComponentDto module = ComponentTesting.newModuleDto("BCDE", project).setKey("MODULE_KEY").setName("Module");
+ dbClient.componentDao().insert(session, module);
+ ComponentDto directory = ComponentTesting.newDirectory(module, "src/main/java/dir").setUuid("CDEF").setKey("MODULE_KEY:src/main/java/dir");
+ ComponentDto file = ComponentTesting.newFileDto(module, "DEFG").setPath("src/main/java/dir/Foo.java").setName("Foo.java").setKey("MODULE_KEY:src/main/java/dir/Foo.java");
+ dbClient.componentDao().insert(session, directory, file);
+ session.commit();
+
+ 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")
+ .setName("Project")
+ .addChildRef(2)
+ .build());
+ writer.writeComponent(BatchReport.Component.newBuilder()
+ .setRef(2)
+ .setType(Constants.ComponentType.MODULE)
+ .setKey("MODULE_KEY")
+ .setName("Module")
+ .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());
+
+ sut.execute(new ComputationContext(new BatchReportReader(reportDir), project));
+
+ assertThat(dbTester.countRowsOfTable("projects")).isEqualTo(4);
+ assertThat(dbClient.componentDao().selectNullableByKey(session, "PROJECT_KEY").getId()).isEqualTo(project.getId());
+ assertThat(dbClient.componentDao().selectNullableByKey(session, "MODULE_KEY").getId()).isEqualTo(module.getId());
+ assertThat(dbClient.componentDao().selectNullableByKey(session, "MODULE_KEY:src/main/java/dir").getId()).isEqualTo(directory.getId());
+ assertThat(dbClient.componentDao().selectNullableByKey(session, "MODULE_KEY:src/main/java/dir/Foo.java").getId()).isEqualTo(file.getId());
+
+ ComponentDto projectReloaded = dbClient.componentDao().selectNullableByKey(session, "PROJECT_KEY");
+ assertThat(projectReloaded.getId()).isEqualTo(project.getId());
+ assertThat(projectReloaded.uuid()).isEqualTo(project.uuid());
+ assertThat(projectReloaded.moduleUuid()).isEqualTo(project.moduleUuid());
+ assertThat(projectReloaded.moduleUuidPath()).isEqualTo(project.moduleUuidPath());
+ assertThat(projectReloaded.projectUuid()).isEqualTo(project.projectUuid());
+ assertThat(projectReloaded.parentProjectId()).isEqualTo(project.parentProjectId());
+
+ ComponentDto moduleReloaded = dbClient.componentDao().selectNullableByKey(session, "MODULE_KEY");
+ assertThat(moduleReloaded.getId()).isEqualTo(module.getId());
+ assertThat(moduleReloaded.uuid()).isEqualTo(module.uuid());
+ assertThat(moduleReloaded.moduleUuid()).isEqualTo(module.moduleUuid());
+ assertThat(moduleReloaded.moduleUuidPath()).isEqualTo(module.moduleUuidPath());
+ assertThat(moduleReloaded.projectUuid()).isEqualTo(module.projectUuid());
+ assertThat(moduleReloaded.parentProjectId()).isEqualTo(module.parentProjectId());
+
+ ComponentDto directoryReloaded = dbClient.componentDao().selectNullableByKey(session, "MODULE_KEY:src/main/java/dir");
+ assertThat(directoryReloaded).isNotNull();
+ assertThat(directoryReloaded.uuid()).isEqualTo(directory.uuid());
+ assertThat(directoryReloaded.moduleUuid()).isEqualTo(directory.moduleUuid());
+ assertThat(directoryReloaded.moduleUuidPath()).isEqualTo(directory.moduleUuidPath());
+ assertThat(directoryReloaded.projectUuid()).isEqualTo(directory.projectUuid());
+ assertThat(directoryReloaded.parentProjectId()).isEqualTo(directory.parentProjectId());
+ assertThat(directoryReloaded.name()).isEqualTo(directory.name());
+ assertThat(directoryReloaded.path()).isEqualTo(directory.path());
+
+ ComponentDto fileReloaded = dbClient.componentDao().selectNullableByKey(session, "MODULE_KEY:src/main/java/dir/Foo.java");
+ assertThat(fileReloaded).isNotNull();
+ assertThat(fileReloaded.uuid()).isEqualTo(file.uuid());
+ assertThat(fileReloaded.moduleUuid()).isEqualTo(file.moduleUuid());
+ assertThat(fileReloaded.moduleUuidPath()).isEqualTo(file.moduleUuidPath());
+ assertThat(fileReloaded.projectUuid()).isEqualTo(file.projectUuid());
+ assertThat(fileReloaded.parentProjectId()).isEqualTo(file.parentProjectId());
+ assertThat(fileReloaded.name()).isEqualTo(file.name());
+ assertThat(fileReloaded.path()).isEqualTo(file.path());
+ }
+
+ @Test
+ public void update_name_and_description() throws Exception {
+ ComponentDto project = ComponentTesting.newProjectDto("ABCD").setKey("PROJECT_KEY").setName("Project");
+ dbClient.componentDao().insert(session, project);
+ ComponentDto module = ComponentTesting.newModuleDto("BCDE", project).setKey("MODULE_KEY").setName("Module");
+ dbClient.componentDao().insert(session, module);
+ session.commit();
+
+ 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")
+ .setName("New project name")
+ .setDescription("New project description")
+ .addChildRef(2)
+ .build());
+ writer.writeComponent(BatchReport.Component.newBuilder()
+ .setRef(2)
+ .setType(Constants.ComponentType.MODULE)
+ .setKey("MODULE_KEY")
+ .setName("New module name")
+ .setDescription("New module description")
+ .build());
+
+ sut.execute(new ComputationContext(new BatchReportReader(reportDir), project));
+
+ ComponentDto projectReloaded = dbClient.componentDao().selectNullableByKey(session, "PROJECT_KEY");
+ assertThat(projectReloaded.name()).isEqualTo("New project name");
+ assertThat(projectReloaded.description()).isEqualTo("New project description");
+
+ ComponentDto moduleReloaded = dbClient.componentDao().selectNullableByKey(session, "MODULE_KEY");
+ assertThat(moduleReloaded.name()).isEqualTo("New module name");
+ assertThat(moduleReloaded.description()).isEqualTo("New module description");
+ }
+
+ @Test
+ public void update_module_uuid_when_moving_a_module() throws Exception {
+ ComponentDto project = ComponentTesting.newProjectDto("ABCD").setKey("PROJECT_KEY").setName("Project");
+ dbClient.componentDao().insert(session, project);
+ ComponentDto moduleB = ComponentTesting.newModuleDto("BCDE", project).setKey("MODULE_B").setName("Module B");
+ dbClient.componentDao().insert(session, moduleB);
+ ComponentDto directory = ComponentTesting.newDirectory(moduleB, "src/main/java/dir").setUuid("CDEF").setKey("MODULE_B:src/main/java/dir");
+ ComponentDto file = ComponentTesting.newFileDto(moduleB, "DEFG").setPath("src/main/java/dir/Foo.java").setName("Foo.java").setKey("MODULE_B:src/main/java/dir/Foo.java");
+ dbClient.componentDao().insert(session, directory, file);
+ session.commit();
+
+ 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")
+ .setName("Project")
+ .addChildRef(2)
+ .build());
+ writer.writeComponent(BatchReport.Component.newBuilder()
+ .setRef(2)
+ .setType(Constants.ComponentType.MODULE)
+ .setKey("MODULE_A")
+ .setName("Module A")
+ .addChildRef(3)
+ .build());
+ // Module B is now a sub module of module A
+ writer.writeComponent(BatchReport.Component.newBuilder()
+ .setRef(3)
+ .setType(Constants.ComponentType.MODULE)
+ .setKey("MODULE_B")
+ .setName("Module B")
+ .addChildRef(4)
+ .build());
+ writer.writeComponent(BatchReport.Component.newBuilder()
+ .setRef(4)
+ .setType(Constants.ComponentType.DIRECTORY)
+ .setPath("src/main/java/dir")
+ .addChildRef(5)
+ .build());
+ writer.writeComponent(BatchReport.Component.newBuilder()
+ .setRef(5)
+ .setType(Constants.ComponentType.FILE)
+ .setPath("src/main/java/dir/Foo.java")
+ .build());
+
+ sut.execute(new ComputationContext(new BatchReportReader(reportDir), project));
+
+ assertThat(dbTester.countRowsOfTable("projects")).isEqualTo(5);
+
+ ComponentDto moduleA = dbClient.componentDao().selectNullableByKey(session, "MODULE_A");
+ assertThat(moduleA).isNotNull();
+
+ ComponentDto moduleBReloaded = dbClient.componentDao().selectNullableByKey(session, "MODULE_B");
+ assertThat(moduleBReloaded).isNotNull();
+ assertThat(moduleBReloaded.uuid()).isEqualTo(moduleB.uuid());
+ assertThat(moduleBReloaded.moduleUuid()).isEqualTo(moduleA.uuid());
+ assertThat(moduleBReloaded.moduleUuidPath()).isEqualTo(moduleA.moduleUuidPath() + moduleBReloaded.uuid() + ".");
+ assertThat(moduleBReloaded.projectUuid()).isEqualTo(project.uuid());
+ assertThat(moduleBReloaded.parentProjectId()).isEqualTo(moduleA.getId());
+
+ ComponentDto directoryReloaded = dbClient.componentDao().selectNullableByKey(session, "MODULE_B:src/main/java/dir");
+ assertThat(directoryReloaded).isNotNull();
+ assertThat(directoryReloaded.uuid()).isEqualTo(directory.uuid());
+ assertThat(directoryReloaded.moduleUuid()).isEqualTo(moduleBReloaded.uuid());
+ assertThat(directoryReloaded.moduleUuidPath()).isEqualTo(moduleBReloaded.moduleUuidPath());
+ assertThat(directoryReloaded.projectUuid()).isEqualTo(project.uuid());
+ assertThat(directoryReloaded.parentProjectId()).isEqualTo(moduleBReloaded.getId());
+
+ ComponentDto fileReloaded = dbClient.componentDao().selectNullableByKey(session, "MODULE_B:src/main/java/dir/Foo.java");
+ assertThat(fileReloaded).isNotNull();
+ assertThat(fileReloaded.uuid()).isEqualTo(file.uuid());
+ assertThat(fileReloaded.moduleUuid()).isEqualTo(moduleBReloaded.uuid());
+ assertThat(fileReloaded.moduleUuidPath()).isEqualTo(moduleBReloaded.moduleUuidPath());
+ assertThat(fileReloaded.projectUuid()).isEqualTo(project.uuid());
+ assertThat(fileReloaded.parentProjectId()).isEqualTo(moduleBReloaded.getId());
+ }
+
+}
+++ /dev/null
-<dataset>
-
- <!-- root project -->
- <projects id="1" root_id="[null]" scope="PRJ" qualifier="TRK" kee="org.struts:struts" deprecated_kee="org.struts:struts" name="Struts"
- uuid="ABCD" project_uuid="ABCD" module_uuid="[null]" module_uuid_path=".ABCD."
- description="the description" long_name="Apache Struts"
- enabled="[true]" language="[null]" copy_resource_id="[null]" person_id="[null]" path="[null]" authorization_updated_at="123456789" />
-
- <!-- module -->
- <projects id="2" root_id="1" kee="org.struts:struts-core" name="Struts Core"
- uuid="EFGH" project_uuid="ABCD" module_uuid="[null]" module_uuid_path=".ABCD.EFGH."
- scope="PRJ" qualifier="BRC" long_name="Struts Core"
- description="[null]" enabled="[true]" language="[null]" copy_resource_id="[null]" person_id="[null]" authorization_updated_at="[null]" />
-
- <!-- directory -->
- <projects long_name="org.struts" id="3" scope="DIR" qualifier="DIR" kee="org.struts:struts-core:src/org/struts"
- uuid="GHIJ" project_uuid="ABCD" module_uuid="EFGH" module_uuid_path=".ABCD.EFGH."
- name="src/org/struts" root_id="2"
- description="[null]"
- enabled="[true]" language="[null]" copy_resource_id="[null]" person_id="[null]" path="src/org/struts" authorization_updated_at="[null]" />
-
- <!-- file -->
- <projects long_name="org.struts.RequestContext" id="4" scope="FIL" qualifier="FIL" kee="org.struts:struts-core:src/org/struts/RequestContext.java"
- uuid="KLMN" project_uuid="ABCD" module_uuid="EFGH" module_uuid_path=".ABCD.EFGH."
- name="RequestContext.java" root_id="2"
- description="[null]"
- enabled="[true]" language="java" copy_resource_id="[null]" person_id="[null]" path="src/org/struts/RequestContext.java" authorization_updated_at="[null]" />
-
- <!-- Disabled projects -->
- <projects id="10" root_id="[null]" scope="PRJ" qualifier="TRK" kee="org.disabled.project" name="Disabled Project"
- uuid="DCBA" project_uuid="DCBA" module_uuid="[null]" module_uuid_path="."
- description="the description" long_name="Disabled project"
- enabled="[false]" language="[null]" copy_resource_id="[null]" person_id="[null]" path="[null]" authorization_updated_at="123456789" />
-
- <!-- Developer -->
- <projects id="20" kee="DEV:developer@company.net" name="developer@company.net" long_name="Developer" scope="PRJ" qualifier="DEV" root_id="[null]" description="[null]"
- uuid="DEV" project_uuid="[null]" module_uuid="[null]" module_uuid_path="."
- enabled="[true]" language="java" copy_resource_id="[null]" person_id="[null]" path="[null]" deprecated_kee="[null]"
- created_at="2014-09-01" authorization_updated_at="[null]"/>
-
- <!-- View -->
- <projects id="30" kee="view" name="View" long_name="View" scope="PRJ" qualifier="VW" root_id="[null]" description="[null]"
- uuid="VIEW" project_uuid="[null]" module_uuid="[null]" module_uuid_path="."
- enabled="[true]" language="java" copy_resource_id="[null]" person_id="[null]" path="[null]" deprecated_kee="[null]"
- created_at="2014-09-01" authorization_updated_at="[null]"/>
-
-</dataset>
name="RequestContext.java" long_name="org.struts.RequestContext"
uuid="GHIJ" project_uuid="ABCD" module_uuid="EFGH" module_uuid_path=".ABCD.EFGH."
qualifier="FIL" scope="FIL" language="java" path="src/org/struts/RequestContext.java" root_id="3"
- description="[null]" enabled="[true]" copy_resource_id="5" person_id="[null]"
+ description="description" enabled="[true]" copy_resource_id="5" person_id="[null]"
authorization_updated_at="123456789" created_at="2014-06-18"
/>
--- /dev/null
+<dataset>
+
+ <projects id="1" kee="org.struts:struts-core:src/org/struts/RequestContext2.java" deprecated_kee="org.struts:struts-core:src/org/struts/RequestContext2.java"
+ name="RequestContext2.java" long_name="org.struts.RequestContext2"
+ uuid="GHIJ" project_uuid="DCBA" module_uuid="HGFE" module_uuid_path=".DCBA.HGFE."
+ qualifier="LIF" scope="LIF" language="java2" path="src/org/struts/RequestContext2.java" root_id="4"
+ description="description2" enabled="[false]" copy_resource_id="6" person_id="[null]"
+ authorization_updated_at="12345678910" created_at="2014-06-18"
+ />
+
+</dataset>
--- /dev/null
+<dataset>
+
+ <projects id="1" kee="org.struts:struts-core:src/org/struts/RequestContext.java" deprecated_kee="org.struts:struts-core:src/org/struts/RequestContext.java"
+ name="RequestContext.java" long_name="org.struts.RequestContext"
+ uuid="GHIJ" project_uuid="ABCD" module_uuid="EFGH" module_uuid_path=".ABCD.EFGH."
+ qualifier="FIL" scope="FIL" language="java" path="src/org/struts/RequestContext.java" root_id="3"
+ description="description" enabled="[true]" copy_resource_id="5" person_id="[null]"
+ authorization_updated_at="123456789" created_at="2014-06-18"
+ />
+
+</dataset>
private String name;
private String longName;
private String language;
+ private String description;
private boolean enabled = true;
private Date createdAt;
return this;
}
+ @CheckForNull
+ public String description() {
+ return description;
+ }
+
+ public ComponentDto setDescription(@Nullable String description) {
+ this.description = description;
+ return this;
+ }
+
@CheckForNull
public Long parentProjectId() {
return parentProjectId;
*/
List<UuidWithProjectUuidDto> selectUuidsForQualifiers(@Param("qualifiers") String... qualifiers);
+ /**
+ * Return all components of a project
+ */
+ List<ComponentDto> selectComponentsFromProjectUuid(@Param("projectUuid") String projectUuid);
+
/**
* Return technical projects from a view or a sub-view
*/
long countById(long id);
- void insert(ComponentDto rule);
-
List<ComponentDto> selectProvisionedProjects(Map<String, String> parameters, RowBounds rowBounds);
int countProvisionedProjects(Map<String, String> parameters);
List<ComponentDto> selectGhostProjects(Map<String, String> parameters, RowBounds rowBounds);
long countGhostProjects(Map<String, String> parameters);
+
+ void insert(ComponentDto componentDto);
+
+ void update(ComponentDto componentDto);
}
p.deprecated_kee as deprecatedKey,
p.name as name,
p.long_name as longName,
+ p.description as description,
p.qualifier as qualifier,
p.scope as scope,
p.language as language,
</where>
</select>
- <sql id="insertColumns">
- (kee, deprecated_kee, uuid, project_uuid, module_uuid, module_uuid_path, name, long_name, qualifier, scope, language, root_id, path, copy_resource_id, enabled,
- created_at, authorization_updated_at)
- </sql>
-
- <insert id="insert" parameterType="Component" keyColumn="id" useGeneratedKeys="true" keyProperty="id">
- insert into projects <include refid="insertColumns"/>
- values (#{kee}, #{deprecatedKey}, #{uuid}, #{projectUuid}, #{moduleUuid}, #{moduleUuidPath}, #{name}, #{longName}, #{qualifier}, #{scope},
- #{language}, #{parentProjectId}, #{path}, #{copyResourceId}, #{enabled}, #{createdAt}, #{authorizationUpdatedAt})
- </insert>
+ <select id="selectComponentsFromProjectUuid" parameterType="map" resultType="Component">
+ SELECT <include refid="componentColumns"/>
+ FROM projects p
+ <where>
+ AND p.project_uuid=#{projectUuid}
+ AND p.enabled=${_true}
+ </where>
+ </select>
<select id="selectProvisionedProjects" parameterType="map" resultType="Component">
select <include refid="componentColumns"/>
inner join snapshots s1 on s1.project_id = p.id and s1.status='U'
left join snapshots s2 on s2.project_id = p.id and s2.status='P'
where
- s2.id is null
- and p.qualifier=#{qualifier}
- and p.copy_resource_id is null
- <if test="query!=null">
- and (
- UPPER(p.name) like #{query}
- or UPPER(p.kee) like #{query}
- )
- </if>
+ s2.id is null
+ and p.qualifier=#{qualifier}
+ and p.copy_resource_id is null
+ <if test="query!=null">
+ and (
+ UPPER(p.name) like #{query}
+ or UPPER(p.kee) like #{query}
+ )
+ </if>
</sql>
+
+ <insert id="insert" parameterType="Component" keyColumn="id" useGeneratedKeys="true" keyProperty="id">
+ INSERT INTO projects (kee, deprecated_kee, uuid, project_uuid, module_uuid, module_uuid_path, name, long_name, qualifier, scope, language, description, root_id, path, copy_resource_id, enabled,
+ created_at, authorization_updated_at)
+ VALUES (#{kee,jdbcType=VARCHAR}, #{deprecatedKey,jdbcType=VARCHAR}, #{uuid,jdbcType=VARCHAR}, #{projectUuid,jdbcType=VARCHAR}, #{moduleUuid,jdbcType=VARCHAR}, #{moduleUuidPath,jdbcType=VARCHAR},
+ #{name,jdbcType=VARCHAR}, #{longName,jdbcType=VARCHAR}, #{qualifier,jdbcType=VARCHAR}, #{scope,jdbcType=VARCHAR}, #{language,jdbcType=VARCHAR}, #{description,jdbcType=VARCHAR},
+ #{parentProjectId,jdbcType=BIGINT}, #{path,jdbcType=VARCHAR}, #{copyResourceId,jdbcType=BIGINT}, #{enabled,jdbcType=BOOLEAN},
+ #{createdAt,jdbcType=TIMESTAMP}, #{authorizationUpdatedAt,jdbcType=BIGINT})
+ </insert>
+
+ <insert id="update" parameterType="Component">
+ UPDATE projects SET
+ kee=#{kee,jdbcType=VARCHAR},
+ deprecated_kee=#{deprecatedKey,jdbcType=VARCHAR},
+ project_uuid=#{projectUuid,jdbcType=VARCHAR},
+ module_uuid=#{moduleUuid,jdbcType=VARCHAR},
+ module_uuid_path=#{moduleUuidPath,jdbcType=VARCHAR},
+ name=#{name,jdbcType=VARCHAR},
+ long_name=#{longName,jdbcType=VARCHAR},
+ qualifier=#{qualifier,jdbcType=VARCHAR},
+ scope=#{scope,jdbcType=VARCHAR},
+ language=#{language,jdbcType=VARCHAR},
+ description=#{description,jdbcType=VARCHAR},
+ root_id=#{parentProjectId,jdbcType=BIGINT},
+ path=#{path,jdbcType=VARCHAR},
+ copy_resource_id=#{copyResourceId,jdbcType=BIGINT},
+ enabled=#{enabled,jdbcType=BOOLEAN},
+ authorization_updated_at=#{authorizationUpdatedAt,jdbcType=BIGINT}
+ WHERE uuid=#{uuid}
+ </insert>
+
</mapper>
.setQualifier("FIL")
.setScope("FIL")
.setLanguage("java")
+ .setDescription("desc")
.setPath("src/org/struts/RequestContext.java")
.setCopyResourceId(5L)
.setParentProjectId(3L)
assertThat(componentDto.scope()).isEqualTo("FIL");
assertThat(componentDto.path()).isEqualTo("src/org/struts/RequestContext.java");
assertThat(componentDto.language()).isEqualTo("java");
+ assertThat(componentDto.description()).isEqualTo("desc");
assertThat(componentDto.parentProjectId()).isEqualTo(3L);
assertThat(componentDto.getCopyResourceId()).isEqualTo(5L);
assertThat(componentDto.getAuthorizationUpdatedAt()).isEqualTo(123456789L);