package org.sonar.server.component;
import org.sonar.api.ServerComponent;
+import org.sonar.api.i18n.I18n;
+import org.sonar.api.resources.Scopes;
+import org.sonar.api.utils.internal.Uuids;
import org.sonar.api.web.UserRole;
import org.sonar.core.component.ComponentDto;
+import org.sonar.core.component.ComponentKeys;
+import org.sonar.core.permission.GlobalPermissions;
import org.sonar.core.persistence.DbSession;
import org.sonar.core.preview.PreviewCache;
+import org.sonar.core.resource.ResourceIndexerDao;
import org.sonar.core.resource.ResourceKeyUpdaterDao;
import org.sonar.server.db.DbClient;
+import org.sonar.server.exceptions.BadRequestException;
+import org.sonar.server.permission.InternalPermissionService;
import org.sonar.server.user.UserSession;
import javax.annotation.CheckForNull;
+import javax.annotation.Nullable;
+import java.util.Date;
+import java.util.Locale;
import java.util.Map;
public class ComponentService implements ServerComponent {
private final ResourceKeyUpdaterDao resourceKeyUpdaterDao;
private final PreviewCache previewCache;
+ private final I18n i18n;
+ private final ResourceIndexerDao resourceIndexerDao;
+ private final InternalPermissionService permissionService;
- public ComponentService(DbClient dbClient, ResourceKeyUpdaterDao resourceKeyUpdaterDao, PreviewCache previewCache) {
+ public ComponentService(DbClient dbClient, ResourceKeyUpdaterDao resourceKeyUpdaterDao, PreviewCache previewCache, I18n i18n, ResourceIndexerDao resourceIndexerDao,
+ InternalPermissionService permissionService) {
this.dbClient = dbClient;
this.resourceKeyUpdaterDao = resourceKeyUpdaterDao;
this.previewCache = previewCache;
+ this.i18n = i18n;
+ this.resourceIndexerDao = resourceIndexerDao;
+ this.permissionService = permissionService;
}
public ComponentDto getByKey(String key) {
DbSession session = dbClient.openSession(false);
try {
- return dbClient.componentDao().getByKey(session, key);
+ return getByKey(session, key);
} finally {
session.close();
}
public ComponentDto getNullableByKey(String key) {
DbSession session = dbClient.openSession(false);
try {
- return dbClient.componentDao().getNullableByKey(session, key);
+ return getNullableByKey(session, key);
} finally {
session.close();
}
DbSession session = dbClient.openSession(false);
try {
- ComponentDto projectOrModule = getByKey(projectOrModuleKey);
+ ComponentDto projectOrModule = getByKey(session, projectOrModuleKey);
resourceKeyUpdaterDao.updateKey(projectOrModule.getId(), newKey);
session.commit();
DbSession session = dbClient.openSession(false);
try {
- ComponentDto project = getByKey(projectKey);
+ ComponentDto project = getByKey(session, projectKey);
resourceKeyUpdaterDao.bulkUpdateKey(project.getId(), stringToReplace, replacementString);
session.commit();
}
}
+ public String create(NewComponent newComponent) {
+ UserSession.get().checkGlobalPermission(GlobalPermissions.PROVISIONING);
+
+ DbSession session = dbClient.openSession(false);
+ try {
+ checkKeyFormat(newComponent.qualifier(), newComponent.key());
+ checkBranchFormat(newComponent.qualifier(), newComponent.branch());
+ String keyWithBranch = ComponentKeys.createKey(newComponent.key(), newComponent.branch());
+
+ ComponentDto existingComponent = getNullableByKey(keyWithBranch);
+ if (existingComponent != null) {
+ throw new BadRequestException(formatMessage("Could not create %s, key already exists: %s", newComponent.qualifier(), keyWithBranch));
+ }
+
+ String uuid = Uuids.create();
+ ComponentDto component = dbClient.componentDao().insert(session,
+ new ComponentDto()
+ .setUuid(uuid)
+ .setProjectUuid(uuid)
+ .setKey(keyWithBranch)
+ .setDeprecatedKey(keyWithBranch)
+ .setName(newComponent.name())
+ .setLongName(newComponent.name())
+ .setScope(Scopes.PROJECT)
+ .setQualifier(newComponent.qualifier())
+ .setCreatedAt(new Date()));
+ resourceIndexerDao.indexResource(session, component.getId());
+ session.commit();
+
+ permissionService.applyDefaultPermissionTemplate(component.key());
+ return component.key();
+ } finally {
+ session.close();
+ }
+ }
+
+ private void checkKeyFormat(String qualifier, String kee) {
+ if (!ComponentKeys.isValidModuleKey(kee)) {
+ throw new BadRequestException(formatMessage("Malformed key for %s: %s. Allowed characters are alphanumeric, '-', '_', '.' and ':', with at least one non-digit.",
+ qualifier, kee));
+ }
+ }
+
+ private void checkBranchFormat(String qualifier, @Nullable String branch) {
+ if (branch != null && !ComponentKeys.isValidBranch(branch)) {
+ throw new BadRequestException(formatMessage("Malformed branch for %s: %s. Allowed characters are alphanumeric, '-', '_', '.' and '/', with at least one non-digit.",
+ qualifier, branch));
+ }
+ }
+
+ private String formatMessage(String message, String qualifier, String key) {
+ return String.format(message, i18n.message(Locale.getDefault(), "qualifier." + qualifier, "Project"), key);
+ }
+
+ @CheckForNull
+ private ComponentDto getNullableByKey(DbSession session, String key) {
+ return dbClient.componentDao().getNullableByKey(session, key);
+ }
+
+ private ComponentDto getByKey(DbSession session, String key) {
+ return dbClient.componentDao().getByKey(session, key);
+ }
+
}
import org.sonar.api.component.RubyComponentService;
import org.sonar.api.i18n.I18n;
import org.sonar.api.resources.Qualifiers;
-import org.sonar.api.resources.Scopes;
-import org.sonar.api.utils.internal.Uuids;
import org.sonar.core.component.ComponentDto;
-import org.sonar.core.component.ComponentKeys;
import org.sonar.core.resource.ResourceDao;
import org.sonar.core.resource.ResourceDto;
-import org.sonar.core.resource.ResourceIndexerDao;
import org.sonar.server.exceptions.BadRequestException;
-import org.sonar.server.exceptions.NotFoundException;
import org.sonar.server.util.RubyUtils;
import javax.annotation.CheckForNull;
+import javax.annotation.Nullable;
-import java.util.*;
+import java.util.List;
+import java.util.Map;
public class DefaultRubyComponentService implements RubyComponentService {
private final ResourceDao resourceDao;
private final DefaultComponentFinder finder;
- private final ResourceIndexerDao resourceIndexerDao;
private final ComponentService componentService;
private final I18n i18n;
- public DefaultRubyComponentService(ResourceDao resourceDao, DefaultComponentFinder finder, ResourceIndexerDao resourceIndexerDao, ComponentService componentService, I18n i18n) {
+ public DefaultRubyComponentService(ResourceDao resourceDao, DefaultComponentFinder finder, ComponentService componentService, I18n i18n) {
this.resourceDao = resourceDao;
this.finder = finder;
- this.resourceIndexerDao = resourceIndexerDao;
this.componentService = componentService;
this.i18n = i18n;
}
return componentService.getNullableByUuid(uuid);
}
+ /**
+ * Be careful when updating this method, it's used by the Views plugin
+ */
@CheckForNull
- public Long createComponent(String kee, String name, String qualifier) {
+ public Long createComponent(String key, String name, String qualifier) {
+ return createComponent(key, null, name, qualifier);
+ }
+
+ @CheckForNull
+ public Long createComponent(String key, @Nullable String branch, String name, @Nullable String qualifier) {
// Sub view should not be created with provisioning. Will be fixed by http://jira.sonarsource.com/browse/VIEWS-296
if (!Qualifiers.SUBVIEW.equals(qualifier)) {
- ComponentDto component = (ComponentDto) resourceDao.findByKey(kee);
- if (component != null) {
- throw new BadRequestException(formatMessage("Could not create %s, key already exists: %s", qualifier, kee));
- }
- checkKeyFormat(qualifier, kee);
-
- String uuid = Uuids.create();
- resourceDao.insertOrUpdate(
- new ResourceDto()
- .setUuid(uuid)
- .setProjectUuid(uuid)
- .setKey(kee)
- .setDeprecatedKey(kee)
- .setName(name)
- .setLongName(name)
- .setScope(Scopes.PROJECT)
- .setQualifier(qualifier)
- .setCreatedAt(new Date()));
- component = (ComponentDto) resourceDao.findByKey(kee);
+ String createdKey = componentService.create(NewComponent.create(key, name).setQualifier(qualifier).setBranch(branch));
+ ComponentDto component = (ComponentDto) resourceDao.findByKey(createdKey);
if (component == null) {
- throw new BadRequestException(String.format("Component not created: %s", kee));
+ throw new BadRequestException(String.format("Component not created: %s", createdKey));
}
- resourceIndexerDao.indexResource(component.getId());
return component.getId();
}
return null;
}
- public void updateComponent(Long id, String key, String name) {
- ResourceDto resource = resourceDao.getResource(id);
- if (resource == null) {
- throw new NotFoundException();
- }
- checkKeyFormat(resource.getQualifier(), key);
-
- resourceDao.insertOrUpdate(resource.setKey(key).setName(name));
- }
-
public DefaultComponentQueryResult find(Map<String, Object> params) {
ComponentQuery query = toQuery(params);
List<Component> components = resourceDao.selectProjectsByQualifiers(query.qualifiers());
return builder.build();
}
- private void checkKeyFormat(String qualifier, String kee) {
- if (!ComponentKeys.isValidModuleKey(kee)) {
- throw new BadRequestException(formatMessage("Malformed key for %s: %s. Allowed characters are alphanumeric, '-', '_', '.' and ':', with at least one non-digit.",
- qualifier, kee));
- }
- }
-
- private String formatMessage(String message, String qualifier, String key) {
- return String.format(message, i18n.message(Locale.getDefault(), "qualifier." + qualifier, "Project"), key);
- }
}
--- /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.component;
+
+import com.google.common.base.Preconditions;
+import org.sonar.api.resources.Qualifiers;
+
+import javax.annotation.CheckForNull;
+import javax.annotation.Nullable;
+
+public class NewComponent {
+
+ private String key;
+ private String branch;
+ private String qualifier;
+ private String name;
+
+ public NewComponent(String key, String name) {
+ this.key = key;
+ this.name = name;
+ }
+
+ public String key() {
+ return key;
+ }
+
+ public String name() {
+ return name;
+ }
+
+ @CheckForNull
+ public String branch() {
+ return branch;
+ }
+
+ public NewComponent setBranch(@Nullable String branch) {
+ this.branch = branch;
+ return this;
+ }
+
+ public String qualifier() {
+ return qualifier != null ? qualifier : Qualifiers.PROJECT;
+ }
+
+ public NewComponent setQualifier(@Nullable String qualifier) {
+ this.qualifier = qualifier;
+ return this;
+ }
+
+ public static NewComponent create(String key, String name) {
+ Preconditions.checkNotNull(key, "Key can't be null");
+ Preconditions.checkNotNull(name, "Name can't be null");
+ return new NewComponent(key, name);
+ }
+}
import org.junit.Before;
import org.junit.ClassRule;
import org.junit.Test;
+import org.sonar.api.resources.Qualifiers;
import org.sonar.api.security.DefaultGroups;
import org.sonar.api.web.UserRole;
import org.sonar.core.component.ComponentDto;
import org.sonar.core.permission.GlobalPermissions;
import org.sonar.core.persistence.DbSession;
-import org.sonar.core.rule.RuleDto;
import org.sonar.server.component.db.ComponentDao;
import org.sonar.server.db.DbClient;
+import org.sonar.server.exceptions.BadRequestException;
import org.sonar.server.exceptions.ForbiddenException;
import org.sonar.server.permission.InternalPermissionService;
import org.sonar.server.permission.PermissionChange;
-import org.sonar.server.rule.RuleTesting;
-import org.sonar.server.rule.db.RuleDao;
+import org.sonar.server.platform.Platform;
import org.sonar.server.tester.ServerTester;
import org.sonar.server.user.MockUserSession;
import java.util.Map;
import static org.fest.assertions.Assertions.assertThat;
+import static org.fest.assertions.Fail.fail;
public class ComponentServiceMediumTest {
DbClient db;
DbSession session;
ComponentService service;
- ComponentDto project;
- RuleDto rule;
@Before
public void setUp() throws Exception {
db = tester.get(DbClient.class);
session = db.openSession(false);
service = tester.get(ComponentService.class);
-
- project = ComponentTesting.newProjectDto().setKey("sample:root");
- tester.get(ComponentDao.class).insert(session, project);
- session.commit();
-
- // project can be seen by anyone
- MockUserSession.set().setLogin("admin").setGlobalPermissions(GlobalPermissions.SYSTEM_ADMIN);
- tester.get(InternalPermissionService.class).addPermission(new PermissionChange().setComponentKey(project.getKey()).setGroup(DefaultGroups.ANYONE).setPermission(UserRole.USER));
-
- rule = RuleTesting.newXooX1();
- tester.get(RuleDao.class).insert(session, rule);
-
- session.commit();
}
@After
@Test
public void get_by_key() throws Exception {
+ ComponentDto project = createProject("sample:root");
assertThat(service.getByKey(project.getKey())).isNotNull();
}
@Test
public void get_nullable_by_key() throws Exception {
+ ComponentDto project = createProject("sample:root");
assertThat(service.getNullableByKey(project.getKey())).isNotNull();
assertThat(service.getNullableByKey("unknown")).isNull();
}
@Test
public void get_by_uuid() throws Exception {
+ ComponentDto project = createProject("sample:root");
assertThat(service.getByUuid(project.uuid())).isNotNull();
}
@Test
public void get_nullable_by_uuid() throws Exception {
+ ComponentDto project = createProject("sample:root");
assertThat(service.getNullableByUuid(project.uuid())).isNotNull();
assertThat(service.getNullableByUuid("unknown")).isNull();
}
@Test
public void update_project_key() throws Exception {
+ ComponentDto project = createProject("sample:root");
ComponentDto file = ComponentTesting.newFileDto(project).setKey("sample:root:src/File.xoo");
tester.get(ComponentDao.class).insert(session, file);
@Test
public void update_module_key() throws Exception {
+ ComponentDto project = createProject("sample:root");
ComponentDto module = ComponentTesting.newModuleDto(project).setKey("sample:root:module");
tester.get(ComponentDao.class).insert(session, module);
@Test(expected = ForbiddenException.class)
public void fail_to_update_project_key_without_admin_permission() throws Exception {
+ ComponentDto project = createProject("sample:root");
MockUserSession.set().setLogin("john").addComponentPermission(UserRole.USER, project.key(), project.key());
service.updateKey(project.key(), "sample2:root");
}
@Test
public void check_module_keys_before_renaming() throws Exception {
+ ComponentDto project = createProject("sample:root");
ComponentDto module = ComponentTesting.newModuleDto(project).setKey("sample:root:module");
tester.get(ComponentDao.class).insert(session, module);
@Test
public void check_module_keys_before_renaming_return_duplicate_key() throws Exception {
+ ComponentDto project = createProject("sample:root");
ComponentDto module = ComponentTesting.newModuleDto(project).setKey("sample:root:module");
tester.get(ComponentDao.class).insert(session, module);
@Test(expected = ForbiddenException.class)
public void fail_to_check_module_keys_before_renaming_without_admin_permission() throws Exception {
+ ComponentDto project = createProject("sample:root");
MockUserSession.set().setLogin("john").addComponentPermission(UserRole.USER, project.key(), project.key());
service.checkModuleKeysBeforeRenaming(project.key(), "sample", "sample2");
}
@Test
public void bulk_update_project_key() throws Exception {
+ ComponentDto project = createProject("sample:root");
ComponentDto module = ComponentTesting.newModuleDto(project).setKey("sample:root:module");
tester.get(ComponentDao.class).insert(session, module);
@Test(expected = ForbiddenException.class)
public void fail_to_bulk_update_project_key_without_admin_permission() throws Exception {
+ ComponentDto project = createProject("sample:root");
MockUserSession.set().setLogin("john").addProjectPermissions(UserRole.USER, project.key());
service.bulkUpdateKey("sample:root", "sample", "sample2");
}
+ @Test
+ public void create_project() throws Exception {
+ executeStartupTasksToCreateDefaultPermissionTemplate();
+ MockUserSession.set().setLogin("john").setGlobalPermissions(GlobalPermissions.PROVISIONING);
+
+ String key = service.create(NewComponent.create("struts", "Struts project"));
+
+ ComponentDto project = service.getNullableByKey(key);
+ assertThat(project.key()).isEqualTo("struts");
+ assertThat(project.deprecatedKey()).isEqualTo("struts");
+ assertThat(project.uuid()).isNotNull();
+ assertThat(project.projectUuid()).isEqualTo(project.uuid());
+ assertThat(project.moduleUuid()).isNull();
+ assertThat(project.moduleUuidPath()).isNull();
+ assertThat(project.name()).isEqualTo("Struts project");
+ assertThat(project.longName()).isEqualTo("Struts project");
+ assertThat(project.scope()).isEqualTo("PRJ");
+ assertThat(project.qualifier()).isEqualTo("TRK");
+ assertThat(project.getCreatedAt()).isNotNull();
+ }
+
+ @Test
+ public void create_new_project_with_branch() throws Exception {
+ executeStartupTasksToCreateDefaultPermissionTemplate();
+ MockUserSession.set().setLogin("john").setGlobalPermissions(GlobalPermissions.PROVISIONING);
+
+ String key = service.create(NewComponent.create("struts", "Struts project").setBranch("origin/branch"));
+
+ ComponentDto project = service.getNullableByKey(key);
+ assertThat(project.key()).isEqualTo("struts:origin/branch");
+ assertThat(project.deprecatedKey()).isEqualTo("struts:origin/branch");
+ }
+
+ @Test
+ public void create_view() throws Exception {
+ executeStartupTasksToCreateDefaultPermissionTemplate();
+ MockUserSession.set().setLogin("john").setGlobalPermissions(GlobalPermissions.PROVISIONING);
+
+ String key = service.create(NewComponent.create("all-project", "All Projects").setQualifier(Qualifiers.VIEW));
+
+ ComponentDto project = service.getNullableByKey(key);
+ assertThat(project.key()).isEqualTo("all-project");
+ assertThat(project.deprecatedKey()).isEqualTo("all-project");
+ assertThat(project.uuid()).isNotNull();
+ assertThat(project.projectUuid()).isEqualTo(project.uuid());
+ assertThat(project.moduleUuid()).isNull();
+ assertThat(project.moduleUuidPath()).isNull();
+ assertThat(project.name()).isEqualTo("All Projects");
+ assertThat(project.longName()).isEqualTo("All Projects");
+ assertThat(project.scope()).isEqualTo("PRJ");
+ assertThat(project.qualifier()).isEqualTo("VW");
+ assertThat(project.getCreatedAt()).isNotNull();
+ }
+
+ @Test
+ public void fail_to_create_new_component_on_invalid_key() throws Exception {
+ MockUserSession.set().setLogin("john").setGlobalPermissions(GlobalPermissions.PROVISIONING);
+
+ try {
+ service.create(NewComponent.create("struts?parent", "Struts project"));
+ fail();
+ } catch (Exception e){
+ assertThat(e).isInstanceOf(BadRequestException.class).hasMessage("Malformed key for Project: struts?parent. Allowed characters are alphanumeric, '-', '_', '.' and ':', with at least one non-digit.");
+ }
+ }
+
+ @Test
+ public void fail_to_create_new_component_on_invalid_branch() throws Exception {
+ MockUserSession.set().setLogin("john").setGlobalPermissions(GlobalPermissions.PROVISIONING);
+
+ try {
+ service.create(NewComponent.create("struts", "Struts project").setBranch("origin?branch"));
+ fail();
+ } catch (Exception e){
+ assertThat(e).isInstanceOf(BadRequestException.class).hasMessage("Malformed branch for Project: origin?branch. Allowed characters are alphanumeric, '-', '_', '.' and '/', with at least one non-digit.");
+ }
+ }
+
+ @Test
+ public void fail_to_create_new_component_if_key_already_exists() throws Exception {
+ MockUserSession.set().setLogin("john").setGlobalPermissions(GlobalPermissions.PROVISIONING);
+
+ ComponentDto project = ComponentTesting.newProjectDto().setKey("struts");
+ tester.get(ComponentDao.class).insert(session, project);
+ session.commit();
+
+ try {
+ service.create(NewComponent.create("struts", "Struts project"));
+ fail();
+ } catch (Exception e){
+ assertThat(e).isInstanceOf(BadRequestException.class).hasMessage("Could not create Project, key already exists: struts");
+ }
+ }
+
+ private ComponentDto createProject(String key){
+ ComponentDto project = ComponentTesting.newProjectDto().setKey("sample:root");
+ tester.get(ComponentDao.class).insert(session, project);
+ session.commit();
+
+ // project can be seen by anyone
+ MockUserSession.set().setLogin("admin").setGlobalPermissions(GlobalPermissions.SYSTEM_ADMIN);
+ tester.get(InternalPermissionService.class).addPermission(new PermissionChange().setComponentKey(project.getKey()).setGroup(DefaultGroups.ANYONE).setPermission(UserRole.USER));
+ MockUserSession.set();
+
+ return project;
+ }
+
+ private void executeStartupTasksToCreateDefaultPermissionTemplate(){
+ tester.get(Platform.class).executeStartupTasks();
+ }
+
}
import org.sonar.api.component.Component;
import org.sonar.api.i18n.I18n;
import org.sonar.api.resources.Qualifiers;
-import org.sonar.api.resources.Scopes;
import org.sonar.core.component.ComponentDto;
import org.sonar.core.resource.ResourceDao;
-import org.sonar.core.resource.ResourceDto;
-import org.sonar.core.resource.ResourceIndexerDao;
import org.sonar.server.exceptions.BadRequestException;
-import org.sonar.server.exceptions.NotFoundException;
import java.util.List;
import java.util.Map;
ResourceDao resourceDao;
DefaultComponentFinder finder;
- ResourceIndexerDao resourceIndexerDao;
ComponentService componentService;
I18n i18n;
public void before() {
resourceDao = mock(ResourceDao.class);
finder = mock(DefaultComponentFinder.class);
- resourceIndexerDao = mock(ResourceIndexerDao.class);
componentService = mock(ComponentService.class);
i18n = mock(I18n.class);
- service = new DefaultRubyComponentService(resourceDao, finder, resourceIndexerDao, componentService, i18n);
+ service = new DefaultRubyComponentService(resourceDao, finder, componentService, i18n);
}
@Test
}
@Test
- public void create_component_and_index_it() {
+ public void create_component() {
String componentKey = "new-project";
String componentName = "New Project";
String qualifier = Qualifiers.PROJECT;
- long componentId = Long.MAX_VALUE;
- ComponentDto component = mock(ComponentDto.class);
- when(component.getId()).thenReturn(componentId);
- when(resourceDao.findByKey(componentKey)).thenReturn(null).thenReturn(component);
+ when(resourceDao.findByKey(componentKey)).thenReturn(ComponentTesting.newProjectDto());
+ when(componentService.create(any(NewComponent.class))).thenReturn(componentKey);
service.createComponent(componentKey, componentName, qualifier);
- ArgumentCaptor<ResourceDto> resourceCaptor = ArgumentCaptor.forClass(ResourceDto.class);
- verify(resourceDao).insertOrUpdate(resourceCaptor.capture());
- ResourceDto created = resourceCaptor.getValue();
- assertThat(created.getUuid()).isNotNull();
- assertThat(created.getProjectUuid()).isEqualTo(created.getUuid());
- assertThat(created.getKey()).isEqualTo(componentKey);
- assertThat(created.getName()).isEqualTo(componentName);
- assertThat(created.getLongName()).isEqualTo(componentName);
- assertThat(created.getScope()).isEqualTo(Scopes.PROJECT);
- assertThat(created.getQualifier()).isEqualTo(qualifier);
- verify(resourceDao, times(2)).findByKey(componentKey);
- verify(resourceIndexerDao).indexResource(componentId);
+ ArgumentCaptor<NewComponent> newComponentArgumentCaptor = ArgumentCaptor.forClass(NewComponent.class);
+ verify(componentService).create(newComponentArgumentCaptor.capture());
+ NewComponent newComponent = newComponentArgumentCaptor.getValue();
+ assertThat(newComponent.key()).isEqualTo(componentKey);
+ assertThat(newComponent.name()).isEqualTo(componentName);
+ assertThat(newComponent.branch()).isNull();
+ assertThat(newComponent.qualifier()).isEqualTo(Qualifiers.PROJECT);
}
@Test
public void not_create_component_on_sub_views() {
- String componentKey = "new-project";
- String componentName = "New Project";
- String qualifier = Qualifiers.SUBVIEW;
- long componentId = Long.MAX_VALUE;
- ComponentDto component = mock(ComponentDto.class);
- when(component.getId()).thenReturn(componentId);
- when(resourceDao.findByKey(componentKey)).thenReturn(null).thenReturn(component);
+ when(resourceDao.findByKey(anyString())).thenReturn(ComponentTesting.newProjectDto());
- service.createComponent(componentKey, componentName, qualifier);
+ service.createComponent("new-project", "New Project", Qualifiers.SUBVIEW);
- verify(resourceDao, never()).insertOrUpdate(any(ResourceDto.class));
- verifyZeroInteractions(resourceIndexerDao);
+ verify(componentService, never()).create(any(NewComponent.class));
}
@Test(expected = BadRequestException.class)
- public void should_thow_if_create_fails() {
+ public void should_throw_exception_if_create_fails() {
String componentKey = "new-project";
String componentName = "New Project";
String qualifier = Qualifiers.PROJECT;
service.createComponent(componentKey, componentName, qualifier);
}
- @Test(expected = BadRequestException.class)
- public void should_throw_if_component_already_exists() {
- String componentKey = "new-project";
- String componentName = "New Project";
- String qualifier = Qualifiers.PROJECT;
- when(resourceDao.findByKey(componentKey)).thenReturn(mock(ComponentDto.class));
-
- service.createComponent(componentKey, componentName, qualifier);
- }
-
@Test(expected = BadRequestException.class)
public void should_throw_if_malformed_key1() {
service.createComponent("1234", "New Project", Qualifiers.PROJECT);
}
- @Test(expected = NotFoundException.class)
- public void should_throw_if_updating_unknown_component() {
- final long componentId = 1234l;
- when(resourceDao.getResource(componentId)).thenReturn(null);
- service.updateComponent(componentId, "key", "name");
- }
-
- @Test
- public void should_update_component() {
- final long componentId = 1234l;
- final String newKey = "newKey";
- final String newName = "newName";
- ResourceDto resource = mock(ResourceDto.class);
- when(resourceDao.getResource(componentId)).thenReturn(resource);
- when(resource.setKey(newKey)).thenReturn(resource);
- when(resource.setName(newName)).thenReturn(resource);
- service.updateComponent(componentId, newKey, newName);
- verify(resource).setKey(newKey);
- verify(resource).setName(newName);
- verify(resourceDao).insertOrUpdate(resource);
- }
-
- @Test(expected=BadRequestException.class)
- public void should_throw_if_malformed_key_in_update() {
- final long componentId = 1234l;
- final String newKey = "new/key";
- final String newName = "newName";
- ResourceDto resource = mock(ResourceDto.class);
- when(resourceDao.getResource(componentId)).thenReturn(resource);
- service.updateComponent(componentId, newKey, newName);
- }
-
@Test
public void should_find() {
List<String> qualifiers = newArrayList("TRK");
# POST /api/projects/create?key=<key>&name=<name>
#
# -- Example
- # curl -v -u admin:admin -X POST 'http://localhost:9000/api/projects/create?key=project1&name=Project%20One'
+ # curl -v -u admin:admin -X POST 'http://localhost:9000/api/projects/create?key=project1&name=Project%20One&branch=origin/master'
#
# since 4.0
#
def create
verify_post_request
require_parameters :key, :name
- access_denied unless has_role?("provisioning")
- key = params[:key]
- name = params[:name]
- Internal.component_api.createComponent(key, name, 'TRK')
- Internal.permissions.applyDefaultPermissionTemplate(key)
- result = Project.by_key(key)
+ id = Internal.component_api.createComponent(params[:key], params[:branch], params[:name], nil)
+ result = Project.find(id.to_i)
respond_to do |format|
format.json { render :json => jsonp(to_json_hash(result)) }
) { |p| p.key }
end
- def create_or_update
+ def create
verify_post_request
- access_denied unless has_role?("provisioning")
@id = params[:id]
@key = params[:key]
@name = params[:name]
+ @branch = params[:branch]
begin
bad_request('provisioning.missing.key') if @key.blank?
bad_request('provisioning.missing.name') if @name.blank?
- if @id.nil? or @id.empty?
- Internal.component_api.createComponent(@key, @name, 'TRK')
- begin
- Internal.permissions.applyDefaultPermissionTemplate(@key)
- rescue
- # Programmatic transaction rollback
- Java::OrgSonarServerUi::JRubyFacade.getInstance().deleteResourceTree(@key)
- raise
- end
- else
- Internal.component_api.updateComponent(@id.to_i, @key, @name)
- end
+ Internal.component_api.createComponent(@key, @branch, @name, nil)
redirect_to :action => 'index'
rescue Exception => e
flash.now[:error]= Api::Utils.message(e.message)
- render :partial => 'create_form', :id => @id, :key => @key, :name => @name, :status => 400
+ render :partial => 'create_form', :key => @key, :branch => @branch, :name => @name, :status => 400
end
end
-<form id="create-resource-form" method="post" action="<%= ApplicationController.root_context -%>/provisioning/create_or_update">
- <input type="hidden" name="id" value="<%= @id -%>"/>
+<form id="create-resource-form" method="post" action="<%= ApplicationController.root_context -%>/provisioning/create">
<fieldset>
<div class="modal-head">
- <h2><%= message((@id.nil? || @id.empty?) ? 'qualifiers.new.TRK' : 'qualifiers.update.TRK') -%></h2>
+ <h2><%= message('qualifiers.new.TRK') -%></h2>
</div>
<div class="modal-body">
<% if flash.now[:error] %>
<label for="key"><%= h message('key') -%> <em class="mandatory">*</em></label>
<input id="key" name="key" value="<%= h @key -%>" type="text" size="50" maxlength="400" autofocus="autofocus"/>
</div>
+ <div class="modal-field">
+ <label for="branch"><%= h message('branch') -%></label>
+ <input id="branch" name="branch" value="<%= h @branch -%>" type="text" size="50" maxlength="400" autofocus="autofocus"/>
+ </div>
<div class="modal-field">
<label for="name"><%= h message('name') -%> <em class="mandatory">*</em></label>
<input id="name" name="name" value="<%= h @name -%>" type="text" size="50" maxlength="256" value=""/>
</div>
</div>
<div class="modal-foot">
- <input type="submit" value="<%= h message((@id.nil? || @id.empty?) ? 'qualifiers.create.TRK' : 'qualifiers.update.TRK') -%>" id="save-submit"/>
+ <input type="submit" value="<%= h message('qualifiers.create.TRK') -%>" id="save-submit"/>
<a href="#" onclick="return closeModalWindow()" id="save-cancel"><%= h message('cancel') -%></a>
</div>
</fieldset>
<td><%= h resource.name -%></td>
<td><%= format_datetime(resource.created_at) -%></td>
<td class="operations">
- <%= link_to message('edit'), {:action => :create_form, :id => resource.id, :key => resource.key, :name => resource.name},
- {:id => "edit-#{resource.key.parameterize}", :class => 'open-modal link-action'} -%>
-
<%= link_to message('delete'), {:action => :delete_form, :id => resource.id},
{:id => "delete-#{resource.key.parameterize}", :class => 'open-modal link-action link-red'} -%>
</td>
* </ul>
* </li>
* </ul>
- * @param keyCandidate
- * @return <code>true</code> if <code>keyCandidate</code> can be used for a project/module
+ * @param branchCandidate
+ * @return <code>true</code> if <code>branchCandidate</code> can be used for a project/module
*/
public static boolean isValidBranch(String branchCandidate) {
return branchCandidate.matches(VALID_BRANCH_REGEXP);
}
public boolean indexResource(long id) {
- boolean indexed = false;
- SqlSession session = mybatis.openSession(false);
+ DbSession session = mybatis.openSession(false);
try {
- ResourceIndexerMapper mapper = session.getMapper(ResourceIndexerMapper.class);
- ResourceDto resource = mapper.selectResourceToIndex(id);
- if (resource != null) {
- Long rootId = resource.getRootId();
- if (rootId == null) {
- rootId = resource.getId();
- }
- indexed = indexResource(resource.getId(), resource.getName(), resource.getQualifier(), rootId, session, mapper);
- }
- return indexed;
+ return indexResource(session, id);
} finally {
MyBatis.closeQuietly(session);
}
}
+ public boolean indexResource(DbSession session, long id) {
+ boolean indexed = false;
+ ResourceIndexerMapper mapper = session.getMapper(ResourceIndexerMapper.class);
+ ResourceDto resource = mapper.selectResourceToIndex(id);
+ if (resource != null) {
+ Long rootId = resource.getRootId();
+ if (rootId == null) {
+ rootId = resource.getId();
+ }
+ indexed = indexResource(resource.getId(), resource.getName(), resource.getQualifier(), rootId, session, mapper);
+ }
+ return indexed;
+ }
+
public boolean indexResource(int id, String name, String qualifier, int rootId) {
boolean indexed = false;
SqlSession session = mybatis.openSession(false);
backup_verb=Back up
blocker=Blocker
bold=Bold
+branch=Branch
build_date=Build date
build_time=Build time
calendar=Calendar
qualifiers.create.VW=Create View
qualifiers.create.DEV=Create Developer
-qualifiers.update.TRK=Update Project
qualifiers.update.VW=Update View
qualifiers.update.DEV=Update Developer