Line data Source code
1 : // Copyright (C) 2016 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.index.account; 16 : 17 : import static java.util.Objects.requireNonNull; 18 : 19 : import com.google.gerrit.index.IndexConfig; 20 : import com.google.gerrit.index.IndexRewriter; 21 : import com.google.gerrit.index.QueryOptions; 22 : import com.google.gerrit.index.query.IndexPredicate; 23 : import com.google.gerrit.index.query.Predicate; 24 : import com.google.gerrit.index.query.QueryParseException; 25 : import com.google.gerrit.index.query.TooManyTermsInQueryException; 26 : import com.google.gerrit.server.account.AccountState; 27 : import com.google.inject.Inject; 28 : import com.google.inject.Singleton; 29 : import org.eclipse.jgit.util.MutableInteger; 30 : 31 : /** Rewriter for the account index. See {@link IndexRewriter} for details. */ 32 : @Singleton 33 : public class AccountIndexRewriter implements IndexRewriter<AccountState> { 34 : private final AccountIndexCollection indexes; 35 : private final IndexConfig config; 36 : 37 : @Inject 38 149 : AccountIndexRewriter(AccountIndexCollection indexes, IndexConfig config) { 39 149 : this.indexes = indexes; 40 149 : this.config = config; 41 149 : } 42 : 43 : @Override 44 : public Predicate<AccountState> rewrite(Predicate<AccountState> in, QueryOptions opts) 45 : throws QueryParseException { 46 109 : AccountIndex index = indexes.getSearchIndex(); 47 109 : requireNonNull(index, "no active search index configured for accounts"); 48 109 : validateMaxTermsInQuery(in); 49 109 : return new IndexedAccountQuery(index, in, opts); 50 : } 51 : 52 : /** 53 : * Validates whether a query has too many terms. 54 : * 55 : * @param predicate the predicate for which the leaf predicates should be counted 56 : * @throws QueryParseException thrown if the query has too many terms 57 : */ 58 : public void validateMaxTermsInQuery(Predicate<AccountState> predicate) 59 : throws QueryParseException { 60 109 : MutableInteger leafTerms = new MutableInteger(); 61 109 : countLeafTerms(predicate, leafTerms); 62 109 : if (leafTerms.value > config.maxTerms()) { 63 1 : throw new TooManyTermsInQueryException(leafTerms.value, config.maxTerms()); 64 : } 65 109 : } 66 : 67 : private void countLeafTerms(Predicate<AccountState> predicate, MutableInteger leafTerms) { 68 109 : if (predicate instanceof IndexPredicate) { 69 109 : ++leafTerms.value; 70 : } 71 : 72 109 : for (Predicate<AccountState> childPredicate : predicate.getChildren()) { 73 33 : countLeafTerms(childPredicate, leafTerms); 74 33 : } 75 109 : } 76 : }