LCOV - code coverage report
Current view: top level - server/query/group - GroupQueryBuilder.java (source / functions) Hit Total Coverage
Test: _coverage_report.dat Lines: 45 55 81.8 %
Date: 2022-11-19 15:00:39 Functions: 14 15 93.3 %

          Line data    Source code
       1             : // Copyright (C) 2017 The Android Open Source Project
       2             : //
       3             : // Licensed under the Apache License, Version 2.0 (the "License");
       4             : // you may not use this file except in compliance with the License.
       5             : // You may obtain a copy of the License at
       6             : //
       7             : // http://www.apache.org/licenses/LICENSE-2.0
       8             : //
       9             : // Unless required by applicable law or agreed to in writing, software
      10             : // distributed under the License is distributed on an "AS IS" BASIS,
      11             : // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
      12             : // See the License for the specific language governing permissions and
      13             : // limitations under the License.
      14             : 
      15             : package com.google.gerrit.server.query.group;
      16             : 
      17             : import static com.google.common.collect.ImmutableList.toImmutableList;
      18             : 
      19             : import com.google.common.base.Strings;
      20             : import com.google.common.collect.Lists;
      21             : import com.google.common.primitives.Ints;
      22             : import com.google.gerrit.entities.Account;
      23             : import com.google.gerrit.entities.AccountGroup;
      24             : import com.google.gerrit.entities.GroupReference;
      25             : import com.google.gerrit.entities.InternalGroup;
      26             : import com.google.gerrit.index.query.LimitPredicate;
      27             : import com.google.gerrit.index.query.Predicate;
      28             : import com.google.gerrit.index.query.QueryBuilder;
      29             : import com.google.gerrit.index.query.QueryParseException;
      30             : import com.google.gerrit.index.query.QueryRequiresAuthException;
      31             : import com.google.gerrit.server.account.AccountResolver;
      32             : import com.google.gerrit.server.account.AccountResolver.UnresolvableAccountException;
      33             : import com.google.gerrit.server.account.GroupBackend;
      34             : import com.google.gerrit.server.account.GroupBackends;
      35             : import com.google.gerrit.server.account.GroupCache;
      36             : import com.google.inject.Inject;
      37             : import java.io.IOException;
      38             : import java.util.List;
      39             : import java.util.Optional;
      40             : import java.util.Set;
      41             : import org.eclipse.jgit.errors.ConfigInvalidException;
      42             : 
      43             : /** Parses a query string meant to be applied to group objects. */
      44             : public class GroupQueryBuilder extends QueryBuilder<InternalGroup, GroupQueryBuilder> {
      45             :   public static final String FIELD_UUID = "uuid";
      46             :   public static final String FIELD_DESCRIPTION = "description";
      47             :   public static final String FIELD_INNAME = "inname";
      48             :   public static final String FIELD_NAME = "name";
      49             :   public static final String FIELD_OWNER = "owner";
      50             :   public static final String FIELD_LIMIT = "limit";
      51             : 
      52          12 :   private static final QueryBuilder.Definition<InternalGroup, GroupQueryBuilder> mydef =
      53             :       new QueryBuilder.Definition<>(GroupQueryBuilder.class);
      54             : 
      55             :   public static class Arguments {
      56             :     final GroupCache groupCache;
      57             :     final GroupBackend groupBackend;
      58             :     final AccountResolver accountResolver;
      59             : 
      60             :     @Inject
      61          12 :     Arguments(GroupCache groupCache, GroupBackend groupBackend, AccountResolver accountResolver) {
      62          12 :       this.groupCache = groupCache;
      63          12 :       this.groupBackend = groupBackend;
      64          12 :       this.accountResolver = accountResolver;
      65          12 :     }
      66             :   }
      67             : 
      68             :   private final Arguments args;
      69             : 
      70             :   @Inject
      71             :   GroupQueryBuilder(Arguments args) {
      72          12 :     super(mydef, null);
      73          12 :     this.args = args;
      74          12 :   }
      75             : 
      76             :   @Operator
      77             :   public Predicate<InternalGroup> uuid(String uuid) {
      78           7 :     return GroupPredicates.uuid(AccountGroup.uuid(uuid));
      79             :   }
      80             : 
      81             :   @Operator
      82             :   public Predicate<InternalGroup> description(String description) throws QueryParseException {
      83           7 :     if (Strings.isNullOrEmpty(description)) {
      84           2 :       throw error("description operator requires a value");
      85             :     }
      86             : 
      87           7 :     return GroupPredicates.description(description);
      88             :   }
      89             : 
      90             :   @Operator
      91             :   public Predicate<InternalGroup> inname(String namePart) {
      92           7 :     if (namePart.isEmpty()) {
      93           0 :       return name(namePart);
      94             :     }
      95           7 :     return GroupPredicates.inname(namePart);
      96             :   }
      97             : 
      98             :   @Operator
      99             :   public Predicate<InternalGroup> name(String name) {
     100          12 :     return GroupPredicates.name(name);
     101             :   }
     102             : 
     103             :   @Operator
     104             :   public Predicate<InternalGroup> owner(String owner) throws QueryParseException {
     105           7 :     AccountGroup.UUID groupUuid = parseGroup(owner);
     106           7 :     return GroupPredicates.owner(groupUuid);
     107             :   }
     108             : 
     109             :   @Operator
     110             :   public Predicate<InternalGroup> is(String value) throws QueryParseException {
     111           2 :     if ("visibletoall".equalsIgnoreCase(value)) {
     112           2 :       return GroupPredicates.isVisibleToAll();
     113             :     }
     114           0 :     throw error("Invalid query");
     115             :   }
     116             : 
     117             :   @Override
     118             :   protected Predicate<InternalGroup> defaultField(String query) throws QueryParseException {
     119             :     // Adapt the capacity of this list when adding more default predicates.
     120           7 :     List<Predicate<InternalGroup>> preds = Lists.newArrayListWithCapacity(5);
     121           7 :     preds.add(uuid(query));
     122           7 :     preds.add(name(query));
     123           7 :     preds.add(inname(query));
     124           7 :     if (!Strings.isNullOrEmpty(query)) {
     125           7 :       preds.add(description(query));
     126             :     }
     127             :     try {
     128           7 :       preds.add(owner(query));
     129           6 :     } catch (QueryParseException e) {
     130             :       // Skip.
     131           7 :     }
     132           7 :     return Predicate.or(preds);
     133             :   }
     134             : 
     135             :   @Operator
     136             :   public Predicate<InternalGroup> member(String query)
     137             :       throws QueryParseException, ConfigInvalidException, IOException {
     138           2 :     Set<Account.Id> accounts = parseAccount(query);
     139           2 :     List<Predicate<InternalGroup>> predicates =
     140           2 :         accounts.stream().map(GroupPredicates::member).collect(toImmutableList());
     141           2 :     return Predicate.or(predicates);
     142             :   }
     143             : 
     144             :   @Operator
     145             :   public Predicate<InternalGroup> subgroup(String query) throws QueryParseException {
     146           2 :     AccountGroup.UUID groupUuid = parseGroup(query);
     147           2 :     return GroupPredicates.subgroup(groupUuid);
     148             :   }
     149             : 
     150             :   @Operator
     151             :   public Predicate<InternalGroup> limit(String query) throws QueryParseException {
     152           0 :     Integer limit = Ints.tryParse(query);
     153           0 :     if (limit == null) {
     154           0 :       throw error("Invalid limit: " + query);
     155             :     }
     156           0 :     return new LimitPredicate<>(FIELD_LIMIT, limit);
     157             :   }
     158             : 
     159             :   private Set<Account.Id> parseAccount(String nameOrEmail)
     160             :       throws QueryParseException, IOException, ConfigInvalidException {
     161             :     try {
     162           2 :       return args.accountResolver.resolve(nameOrEmail).asNonEmptyIdSet();
     163           0 :     } catch (UnresolvableAccountException e) {
     164           0 :       if (e.isSelf()) {
     165           0 :         throw new QueryRequiresAuthException(e.getMessage(), e);
     166             :       }
     167           0 :       throw new QueryParseException(e.getMessage(), e);
     168             :     }
     169             :   }
     170             : 
     171             :   private AccountGroup.UUID parseGroup(String groupNameOrUuid) throws QueryParseException {
     172           7 :     Optional<InternalGroup> group = args.groupCache.get(AccountGroup.uuid(groupNameOrUuid));
     173           7 :     if (group.isPresent()) {
     174           2 :       return group.get().getGroupUUID();
     175             :     }
     176           7 :     GroupReference groupReference =
     177           7 :         GroupBackends.findBestSuggestion(args.groupBackend, groupNameOrUuid);
     178           7 :     if (groupReference == null) {
     179           6 :       throw error("Group " + groupNameOrUuid + " not found");
     180             :     }
     181           7 :     return groupReference.getUUID();
     182             :   }
     183             : }

Generated by: LCOV version 1.16+git.20220603.dfeb750