package org.sonar.server.favorite.ws;
-import com.google.common.collect.ImmutableSet;
+import java.util.Collection;
import java.util.List;
+import java.util.Map;
import java.util.Set;
import java.util.function.Predicate;
import org.sonar.api.server.ws.Request;
import org.sonar.db.DbClient;
import org.sonar.db.DbSession;
import org.sonar.db.component.ComponentDto;
+import org.sonar.db.organization.OrganizationDto;
import org.sonar.server.favorite.FavoriteFinder;
import org.sonar.server.user.UserSession;
import org.sonarqube.ws.Common;
import org.sonarqube.ws.Favorites.SearchResponse;
import org.sonarqube.ws.client.favorite.SearchRequest;
+import static com.google.common.base.Preconditions.checkArgument;
import static org.sonar.core.util.Protobuf.setNullable;
import static org.sonar.server.ws.WsUtils.writeProtobuf;
import static org.sonarqube.ws.client.favorite.FavoritesWsParameters.ACTION_SEARCH;
private SearchResults toSearchResults(SearchRequest request) {
userSession.checkLoggedIn();
try (DbSession dbSession = dbClient.openSession(false)) {
- SearchResults.Builder builder = SearchResults.newBuilder(request);
- addAuthorizedProjectUuids(dbSession, builder);
- addFavorites(builder);
- return builder.build();
+ List<ComponentDto> authorizedFavorites = favoriteFinder.list().stream()
+ .filter(isAuthorized(dbSession))
+ .collect(Collectors.toList());
+ Paging paging = Paging.forPageIndex(request.getPage()).withPageSize(request.getPageSize()).andTotal(authorizedFavorites.size());
+ List<ComponentDto> displayedFavorites = authorizedFavorites.stream()
+ .skip(paging.offset())
+ .limit(paging.pageSize())
+ .collect(Collectors.toList());
+ Map<String, OrganizationDto> organizationsByUuid = getOrganizationsOfComponents(dbSession, displayedFavorites);
+ return new SearchResults(paging, displayedFavorites, organizationsByUuid);
}
}
- private void addFavorites(SearchResults.Builder builder) {
- builder.allFavorites = favoriteFinder.list();
+ private Predicate<ComponentDto> isAuthorized(DbSession dbSession) {
+ Collection<String> rootProjectsUuids = dbClient.authorizationDao().selectAuthorizedRootProjectsUuids(dbSession, userSession.getUserId(), UserRole.USER);
+ Set<String> authorizedProjectUuids = rootProjectsUuids
+ .stream()
+ .collect(Collectors.toSet(rootProjectsUuids.size()));
+ return dto -> authorizedProjectUuids.contains(dto.projectUuid());
}
- private void addAuthorizedProjectUuids(DbSession dbSession, SearchResults.Builder results) {
- results.authorizedProjectUuids = ImmutableSet
- .copyOf(dbClient.authorizationDao().selectAuthorizedRootProjectsUuids(dbSession, userSession.getUserId(), UserRole.USER));
+ private Map<String, OrganizationDto> getOrganizationsOfComponents(DbSession dbSession, List<ComponentDto> displayedFavorites) {
+ Set<String> organizationUuids = displayedFavorites.stream()
+ .map(ComponentDto::getOrganizationUuid)
+ .collect(Collectors.toSet());
+ return dbClient.organizationDao().selectByUuids(dbSession, organizationUuids)
+ .stream()
+ .collect(Collectors.uniqueIndex(OrganizationDto::getUuid));
}
private static class SearchResults {
private final List<ComponentDto> favorites;
private final Paging paging;
+ private final Map<String, OrganizationDto> organizationsByUuid;
- private SearchResults(Builder builder) {
- Predicate<ComponentDto> authorizedProjects = c -> builder.authorizedProjectUuids.contains(c.projectUuid());
- int total = (int) builder.allFavorites.stream().filter(authorizedProjects).count();
- this.paging = Paging.forPageIndex(builder.page).withPageSize(builder.pageSize).andTotal(total);
- this.favorites = builder.allFavorites.stream()
- .filter(authorizedProjects)
- .skip(paging.offset())
- .limit(paging.pageSize())
- .collect(Collectors.toList());
- }
-
- static Builder newBuilder(SearchRequest request) {
- return new Builder(request);
- }
-
- private static class Builder {
- private final int page;
- private final int pageSize;
- private Set<String> authorizedProjectUuids;
- private List<ComponentDto> allFavorites;
-
- private Builder(SearchRequest request) {
- this.page = request.getPage();
- this.pageSize = request.getPageSize();
- }
-
- public SearchResults build() {
- return new SearchResults(this);
- }
+ private SearchResults(Paging paging, List<ComponentDto> favorites, Map<String, OrganizationDto> organizationsByUuid) {
+ this.paging = paging;
+ this.favorites = favorites;
+ this.organizationsByUuid = organizationsByUuid;
}
}
- private SearchResponse toSearchResponse(SearchResults searchResults) {
+ private static SearchResponse toSearchResponse(SearchResults searchResults) {
SearchResponse.Builder builder = SearchResponse.newBuilder();
addPaging(builder, searchResults);
addFavorites(builder, searchResults);
return builder.build();
}
- private void addPaging(SearchResponse.Builder builder, SearchResults results) {
+ private static void addPaging(SearchResponse.Builder builder, SearchResults results) {
builder
.setPaging(Common.Paging.newBuilder()
.setPageIndex(results.paging.pageIndex())
.setTotal(results.paging.total()));
}
- private void addFavorites(SearchResponse.Builder builder, SearchResults results) {
+ private static void addFavorites(SearchResponse.Builder builder, SearchResults results) {
Favorite.Builder favoriteBuilder = Favorite.newBuilder();
results.favorites.stream()
- .map(componentDto -> toWsFavorite(favoriteBuilder, componentDto))
+ .map(componentDto -> toWsFavorite(favoriteBuilder, results, componentDto))
.forEach(builder::addFavorites);
}
- private Favorite toWsFavorite(Favorite.Builder builder, ComponentDto componentDto) {
+ private static Favorite toWsFavorite(Favorite.Builder builder, SearchResults results, ComponentDto componentDto) {
+ OrganizationDto organization = results.organizationsByUuid.get(componentDto.getOrganizationUuid());
+ checkArgument(organization != null,
+ "Organization with uuid '%s' not found for favorite with uuid '%s'",
+ componentDto.getOrganizationUuid(), componentDto.uuid());
builder
.clear()
+ .setOrganization(organization.getKey())
.setKey(componentDto.key());
setNullable(componentDto.name(), builder::setName);
setNullable(componentDto.qualifier(), builder::setQualifier);