String projectKey = randomAlphabetic(5).toLowerCase();
db.components().insertPrivateProject(c -> c.setKey(projectKey)).getMainBranchComponent();
- ComponentDto result = underTest.selectByKeyCaseInsensitive(db.getSession(), projectKey.toUpperCase()).orElse(null);
+ List<ComponentDto> result = underTest.selectByKeyCaseInsensitive(db.getSession(), projectKey.toUpperCase());
- assertThat(result).isNotNull();
- assertThat(result.getKey()).isEqualTo(projectKey);
+ assertThat(result).isNotEmpty();
+ assertThat(result.get(0).getKey()).isEqualTo(projectKey);
}
@Test
BranchDto projectBranch = db.components().insertProjectBranch(project);
ComponentDto file = db.components().insertFile(projectBranch);
- ComponentDto result = underTest.selectByKeyCaseInsensitive(db.getSession(), file.getKey()).orElse(null);
+ List<ComponentDto> result = underTest.selectByKeyCaseInsensitive(db.getSession(), file.getKey());
- assertThat(result).isNull();
+ assertThat(result).isEmpty();
}
@Test
String projectKey = randomAlphabetic(5).toLowerCase();
db.components().insertPrivateProject(c -> c.setKey(projectKey)).getMainBranchComponent();
- Optional<ComponentDto> result = underTest.selectByKeyCaseInsensitive(db.getSession(), projectKey + randomAlphabetic(1));
+ List<ComponentDto> result = underTest.selectByKeyCaseInsensitive(db.getSession(), projectKey + randomAlphabetic(1));
assertThat(result).isEmpty();
}
import org.apache.ibatis.session.ResultHandler;
import org.apache.ibatis.session.RowBounds;
import org.sonar.api.resources.Qualifiers;
-import org.sonar.api.resources.Scopes;
import org.sonar.db.Dao;
import org.sonar.db.DbSession;
import org.sonar.db.RowNotFoundException;
return Optional.ofNullable(mapper(session).selectByKeyAndBranchOrPr(key, null, pullRequestId));
}
- public Optional<ComponentDto> selectByKeyCaseInsensitive(DbSession session, String key) {
- return Optional.ofNullable(mapper(session).selectByKeyCaseInsensitive(key));
+ public List<ComponentDto> selectByKeyCaseInsensitive(DbSession session, String key) {
+ return mapper(session).selectByKeyCaseInsensitive(key);
}
/**
public interface ComponentMapper {
@CheckForNull
- ComponentDto selectByKeyCaseInsensitive(@Param("key") String key);
+ List<ComponentDto> selectByKeyCaseInsensitive(@Param("key") String key);
@CheckForNull
ComponentDto selectByKeyAndBranchOrPr(@Param("key") String key, @Nullable @Param("branch") String branch, @Nullable @Param("pullRequest") String pullRequest);
package org.sonar.server.component;
import java.util.Optional;
+import org.apache.commons.lang3.StringUtils;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
.hasMessage("Could not create Project with key: \"%s\". A similar key already exists: \"%s\"", newKey, existingKey);
}
+ @Test
+ public void createComponent_shouldFail_whenCreatingComponentWithMultipleExistingKeyButDifferentCase() {
+ String existingKey = randomAlphabetic(5).toUpperCase();
+ String existingKeyLowerCase = existingKey.toLowerCase();
+ db.components().insertPrivateProject(component -> component.setKey(existingKey));
+ db.components().insertPrivateProject(component -> component.setKey(existingKeyLowerCase));
+ String newKey = StringUtils.capitalize(existingKeyLowerCase);
+
+ NewComponent newComponent = NewComponent.newComponentBuilder()
+ .setKey(newKey)
+ .setName(DEFAULT_PROJECT_NAME)
+ .build();
+
+ DbSession dbSession = db.getSession();
+ assertThatThrownBy(() -> underTest.create(dbSession, newComponent, null, null))
+ .isInstanceOf(BadRequestException.class)
+ .hasMessage("Could not create Project with key: \"%s\". A similar key already exists: \"%s, %s\"", newKey, existingKey, existingKeyLowerCase);
+ }
+
+
@Test
public void create_createsComponentWithMasterBranchName() {
String componentNameAndKey = "createApplicationOrPortfolio";
package org.sonar.server.component;
import com.google.common.annotations.VisibleForTesting;
+import java.util.ArrayList;
+import java.util.Collections;
import java.util.Date;
+import java.util.List;
import java.util.Locale;
import java.util.Optional;
import java.util.Set;
import java.util.function.Consumer;
+import java.util.stream.Collectors;
import javax.annotation.Nullable;
import org.sonar.api.resources.Qualifiers;
import org.sonar.api.resources.Scopes;
}
private void checkKeyAlreadyExists(DbSession dbSession, NewComponent newComponent) {
- Optional<ComponentDto> componentDto = newComponent.isProject()
+ List<ComponentDto> componentDtos = newComponent.isProject()
? dbClient.componentDao().selectByKeyCaseInsensitive(dbSession, newComponent.key())
- : dbClient.componentDao().selectByKey(dbSession, newComponent.key());
+ : dbClient.componentDao().selectByKey(dbSession, newComponent.key()).map(Collections::singletonList).orElse(new ArrayList<>());
- componentDto.map(ComponentDto::getKey)
- .ifPresent(existingKey -> throwBadRequestException(KEY_ALREADY_EXISTS_ERROR, getQualifierToDisplay(newComponent.qualifier()), newComponent.key(), existingKey));
+ if (!componentDtos.isEmpty()) {
+ String alreadyExistingKeys = componentDtos
+ .stream()
+ .map(ComponentDto::getKey)
+ .collect(Collectors.joining(", "));
+ throwBadRequestException(KEY_ALREADY_EXISTS_ERROR, getQualifierToDisplay(newComponent.qualifier()), newComponent.key(), alreadyExistingKeys);
+ }
}
private ComponentDto createRootComponent(DbSession session, NewComponent newComponent, Consumer<ComponentDto> componentModifier, long now) {