diff options
Diffstat (limited to 'java/com/google/gerrit/server/project/RefFilter.java')
-rw-r--r-- | java/com/google/gerrit/server/project/RefFilter.java | 121 |
1 files changed, 121 insertions, 0 deletions
diff --git a/java/com/google/gerrit/server/project/RefFilter.java b/java/com/google/gerrit/server/project/RefFilter.java new file mode 100644 index 0000000000..76bafc0113 --- /dev/null +++ b/java/com/google/gerrit/server/project/RefFilter.java @@ -0,0 +1,121 @@ +// Copyright (C) 2015 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.project; + +import com.google.common.base.Predicate; +import com.google.common.base.Strings; +import com.google.common.collect.FluentIterable; +import com.google.gerrit.extensions.api.projects.RefInfo; +import com.google.gerrit.extensions.restapi.BadRequestException; +import dk.brics.automaton.RegExp; +import dk.brics.automaton.RunAutomaton; +import java.util.List; +import java.util.Locale; + +public class RefFilter<T extends RefInfo> { + private final String prefix; + private String matchSubstring; + private String matchRegex; + private int start; + private int limit; + + public RefFilter(String prefix) { + this.prefix = prefix; + } + + public RefFilter<T> subString(String subString) { + this.matchSubstring = subString; + return this; + } + + public RefFilter<T> regex(String regex) { + this.matchRegex = regex; + return this; + } + + public RefFilter<T> start(int start) { + this.start = start; + return this; + } + + public RefFilter<T> limit(int limit) { + this.limit = limit; + return this; + } + + public List<T> filter(List<T> refs) throws BadRequestException { + if (!Strings.isNullOrEmpty(matchSubstring) && !Strings.isNullOrEmpty(matchRegex)) { + throw new BadRequestException("specify exactly one of m/r"); + } + FluentIterable<T> results = FluentIterable.from(refs); + if (!Strings.isNullOrEmpty(matchSubstring)) { + results = results.filter(new SubstringPredicate(matchSubstring)); + } else if (!Strings.isNullOrEmpty(matchRegex)) { + results = results.filter(new RegexPredicate(matchRegex)); + } + if (start > 0) { + results = results.skip(start); + } + if (limit > 0) { + results = results.limit(limit); + } + return results.toList(); + } + + private class SubstringPredicate implements Predicate<T> { + private final String substring; + + private SubstringPredicate(String substring) { + this.substring = substring.toLowerCase(Locale.US); + } + + @Override + public boolean apply(T in) { + String ref = in.ref; + if (ref.startsWith(prefix)) { + ref = ref.substring(prefix.length()); + } + ref = ref.toLowerCase(Locale.US); + return ref.contains(substring); + } + } + + private class RegexPredicate implements Predicate<T> { + private final RunAutomaton a; + + private RegexPredicate(String regex) throws BadRequestException { + if (regex.startsWith("^")) { + regex = regex.substring(1); + if (regex.endsWith("$") && !regex.endsWith("\\$")) { + regex = regex.substring(0, regex.length() - 1); + } + } + try { + a = new RunAutomaton(new RegExp(regex).toAutomaton()); + } catch (IllegalArgumentException e) { + throw new BadRequestException(e.getMessage()); + } + } + + @Override + public boolean apply(T in) { + String ref = in.ref; + if (ref.startsWith(prefix)) { + ref = ref.substring(prefix.length()); + } + return a.run(ref); + } + } +} |