All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.google.gerrit.server.group.Groups Maven / Gradle / Ivy

// Copyright (C) 2017 The Android Open Source Project
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package com.google.gerrit.server.group;

import static com.google.common.collect.ImmutableSet.toImmutableSet;

import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Iterables;
import com.google.common.collect.Streams;
import com.google.gerrit.common.errors.NoSuchGroupException;
import com.google.gerrit.reviewdb.client.Account;
import com.google.gerrit.reviewdb.client.AccountGroup;
import com.google.gerrit.reviewdb.client.AccountGroupById;
import com.google.gerrit.reviewdb.client.AccountGroupMember;
import com.google.gerrit.reviewdb.server.ReviewDb;
import com.google.gwtorm.server.OrmDuplicateKeyException;
import com.google.gwtorm.server.OrmException;
import com.google.gwtorm.server.ResultSet;
import com.google.inject.Singleton;
import java.util.List;
import java.util.Optional;
import java.util.stream.Stream;

/**
 * A database accessor for read calls related to groups.
 *
 * 

All calls which read group related details from the database (either ReviewDb or NoteDb) are * gathered here. Other classes should always use this class instead of accessing the database * directly. There are a few exceptions though: schema classes, wrapper classes, and classes * executed during init. The latter ones should use {@code GroupsOnInit} instead. * *

If not explicitly stated, all methods of this class refer to internal groups. */ @Singleton public class Groups { /** * Returns the {@code AccountGroup} for the specified ID if it exists. * * @param db the {@code ReviewDb} instance to use for lookups * @param groupId the ID of the group * @return the found {@code AccountGroup} if it exists, or else an empty {@code Optional} * @throws OrmException if the group couldn't be retrieved from ReviewDb */ public Optional getGroup(ReviewDb db, AccountGroup.Id groupId) throws OrmException, NoSuchGroupException { Optional accountGroup = Optional.ofNullable(db.accountGroups().get(groupId)); if (!accountGroup.isPresent()) { return Optional.empty(); } AccountGroup.UUID groupUuid = accountGroup.get().getGroupUUID(); ImmutableSet members = getMembers(db, groupUuid).collect(toImmutableSet()); ImmutableSet subgroups = getSubgroups(db, groupUuid).collect(toImmutableSet()); return accountGroup.map(group -> InternalGroup.create(group, members, subgroups)); } /** * Returns the {@code InternalGroup} for the specified UUID if it exists. * * @param db the {@code ReviewDb} instance to use for lookups * @param groupUuid the UUID of the group * @return the found {@code InternalGroup} if it exists, or else an empty {@code Optional} * @throws OrmDuplicateKeyException if multiple groups are found for the specified UUID * @throws OrmException if the group couldn't be retrieved from ReviewDb */ public Optional getGroup(ReviewDb db, AccountGroup.UUID groupUuid) throws OrmException, NoSuchGroupException { Optional accountGroup = getGroupFromReviewDb(db, groupUuid); if (!accountGroup.isPresent()) { return Optional.empty(); } ImmutableSet members = getMembers(db, groupUuid).collect(toImmutableSet()); ImmutableSet subgroups = getSubgroups(db, groupUuid).collect(toImmutableSet()); return accountGroup.map(group -> InternalGroup.create(group, members, subgroups)); } /** * Returns the {@code AccountGroup} for the specified UUID. * * @param db the {@code ReviewDb} instance to use for lookups * @param groupUuid the UUID of the group * @return the {@code AccountGroup} which has the specified UUID * @throws OrmDuplicateKeyException if multiple groups are found for the specified UUID * @throws OrmException if the group couldn't be retrieved from ReviewDb * @throws NoSuchGroupException if a group with such a UUID doesn't exist */ static AccountGroup getExistingGroupFromReviewDb(ReviewDb db, AccountGroup.UUID groupUuid) throws OrmException, NoSuchGroupException { Optional group = getGroupFromReviewDb(db, groupUuid); return group.orElseThrow(() -> new NoSuchGroupException(groupUuid)); } /** * Returns the {@code AccountGroup} for the specified UUID if it exists. * * @param db the {@code ReviewDb} instance to use for lookups * @param groupUuid the UUID of the group * @return the found {@code AccountGroup} if it exists, or else an empty {@code Optional} * @throws OrmDuplicateKeyException if multiple groups are found for the specified UUID * @throws OrmException if the group couldn't be retrieved from ReviewDb */ private static Optional getGroupFromReviewDb( ReviewDb db, AccountGroup.UUID groupUuid) throws OrmException { List accountGroups = db.accountGroups().byUUID(groupUuid).toList(); if (accountGroups.size() == 1) { return Optional.of(Iterables.getOnlyElement(accountGroups)); } else if (accountGroups.isEmpty()) { return Optional.empty(); } else { throw new OrmDuplicateKeyException("Duplicate group UUID " + groupUuid); } } public Stream getAll(ReviewDb db) throws OrmException { return Streams.stream(db.accountGroups().all()); } /** * Indicates whether the specified account is a member of the specified group. * *

Note: This method doesn't check whether the account exists! * * @param db the {@code ReviewDb} instance to use for lookups * @param groupUuid the UUID of the group * @param accountId the ID of the account * @return {@code true} if the account is a member of the group, or else {@code false} * @throws OrmException if an error occurs while reading from ReviewDb * @throws NoSuchGroupException if the specified group doesn't exist */ public boolean isMember(ReviewDb db, AccountGroup.UUID groupUuid, Account.Id accountId) throws OrmException, NoSuchGroupException { AccountGroup group = getExistingGroupFromReviewDb(db, groupUuid); AccountGroupMember.Key key = new AccountGroupMember.Key(accountId, group.getId()); return db.accountGroupMembers().get(key) != null; } /** * Indicates whether the specified group is a subgroup of the specified parent group. * *

The parent group must be an internal group whereas the subgroup may either be an internal or * an external group. * *

Note: This method doesn't check whether the subgroup exists! * * @param db the {@code ReviewDb} instance to use for lookups * @param parentGroupUuid the UUID of the parent group * @param subgroupUuid the UUID of the subgroup * @return {@code true} if the group is a subgroup of the other group, or else {@code false} * @throws OrmException if an error occurs while reading from ReviewDb * @throws NoSuchGroupException if the specified parent group doesn't exist */ public boolean isSubgroup( ReviewDb db, AccountGroup.UUID parentGroupUuid, AccountGroup.UUID subgroupUuid) throws OrmException, NoSuchGroupException { AccountGroup parentGroup = getExistingGroupFromReviewDb(db, parentGroupUuid); AccountGroupById.Key key = new AccountGroupById.Key(parentGroup.getId(), subgroupUuid); return db.accountGroupById().get(key) != null; } /** * Returns the members (accounts) of a group. * *

Note: This method doesn't check whether the accounts exist! * * @param db the {@code ReviewDb} instance to use for lookups * @param groupUuid the UUID of the group * @return a stream of the IDs of the members * @throws OrmException if an error occurs while reading from ReviewDb * @throws NoSuchGroupException if the specified group doesn't exist */ public Stream getMembers(ReviewDb db, AccountGroup.UUID groupUuid) throws OrmException, NoSuchGroupException { AccountGroup group = getExistingGroupFromReviewDb(db, groupUuid); ResultSet accountGroupMembers = db.accountGroupMembers().byGroup(group.getId()); return Streams.stream(accountGroupMembers).map(AccountGroupMember::getAccountId); } /** * Returns the subgroups of a group. * *

This parent group must be an internal group whereas the subgroups can either be internal or * external groups. * *

Note: This method doesn't check whether the subgroups exist! * * @param db the {@code ReviewDb} instance to use for lookups * @param groupUuid the UUID of the parent group * @return a stream of the UUIDs of the subgroups * @throws OrmException if an error occurs while reading from ReviewDb * @throws NoSuchGroupException if the specified parent group doesn't exist */ public Stream getSubgroups(ReviewDb db, AccountGroup.UUID groupUuid) throws OrmException, NoSuchGroupException { AccountGroup group = getExistingGroupFromReviewDb(db, groupUuid); ResultSet accountGroupByIds = db.accountGroupById().byGroup(group.getId()); return Streams.stream(accountGroupByIds).map(AccountGroupById::getIncludeUUID).distinct(); } /** * Returns the groups of which the specified account is a member. * *

Note: This method returns an empty stream if the account doesn't exist. * This method doesn't check whether the groups exist. * * @param db the {@code ReviewDb} instance to use for lookups * @param accountId the ID of the account * @return a stream of the IDs of the groups of which the account is a member * @throws OrmException if an error occurs while reading from ReviewDb */ public static Stream getGroupsWithMemberFromReviewDb( ReviewDb db, Account.Id accountId) throws OrmException { ResultSet accountGroupMembers = db.accountGroupMembers().byAccount(accountId); return Streams.stream(accountGroupMembers).map(AccountGroupMember::getAccountGroupId); } /** * Returns the parent groups of the specified (sub)group. * *

The subgroup may either be an internal or an external group whereas the returned parent * groups represent only internal groups. * *

Note: This method returns an empty stream if the specified group doesn't * exist. This method doesn't check whether the parent groups exist. * * @param db the {@code ReviewDb} instance to use for lookups * @param subgroupUuid the UUID of the subgroup * @return a stream of the IDs of the parent groups * @throws OrmException if an error occurs while reading from ReviewDb */ public static Stream getParentGroupsFromReviewDb( ReviewDb db, AccountGroup.UUID subgroupUuid) throws OrmException { ResultSet accountGroupByIds = db.accountGroupById().byIncludeUUID(subgroupUuid); return Streams.stream(accountGroupByIds).map(AccountGroupById::getGroupId); } /** * Returns all known external groups. External groups are 'known' when they are specified as a * subgroup of an internal group. * * @param db the {@code ReviewDb} instance to use for lookups * @return a stream of the UUIDs of the known external groups * @throws OrmException if an error occurs while reading from ReviewDb */ public Stream getExternalGroups(ReviewDb db) throws OrmException { return Streams.stream(db.accountGroupById().all()) .map(AccountGroupById::getIncludeUUID) .distinct() .filter(groupUuid -> !AccountGroup.isInternalGroup(groupUuid)); } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy