| // Copyright (C) 2021 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.entities; |
| |
| import com.google.auto.value.AutoValue; |
| import com.google.common.collect.ImmutableList; |
| import java.util.Optional; |
| |
| /** Result of evaluating a submit requirement expression on a given Change. */ |
| @AutoValue |
| public abstract class SubmitRequirementExpressionResult { |
| |
| /** |
| * Entity detailing the result of evaluating a Submit requirement expression. Contains an empty |
| * {@link Optional} if {@link #status()} is equal to {@link Status#ERROR}. |
| */ |
| public abstract Optional<PredicateResult> predicateResult(); |
| |
| public abstract Optional<String> errorMessage(); |
| |
| public Status status() { |
| if (predicateResult().isPresent()) { |
| return predicateResult().get().status() ? Status.PASS : Status.FAIL; |
| } |
| return Status.ERROR; |
| } |
| |
| public static SubmitRequirementExpressionResult create(PredicateResult predicateResult) { |
| return new AutoValue_SubmitRequirementExpressionResult( |
| Optional.of(predicateResult), Optional.empty()); |
| } |
| |
| public static SubmitRequirementExpressionResult error(String errorMessage) { |
| return new AutoValue_SubmitRequirementExpressionResult( |
| Optional.empty(), Optional.of(errorMessage)); |
| } |
| |
| /** |
| * Returns a list of leaf predicate results whose {@link PredicateResult#status()} is true. If |
| * {@link #status()} is equal to {@link Status#ERROR}, an empty list is returned. |
| */ |
| public ImmutableList<PredicateResult> getPassingAtoms() { |
| if (predicateResult().isPresent()) { |
| return predicateResult().get().getAtoms(/* status= */ true); |
| } |
| return ImmutableList.of(); |
| } |
| |
| /** |
| * Returns a list of leaf predicate results whose {@link PredicateResult#status()} is false. If |
| * {@link #status()} is equal to {@link Status#ERROR}, an empty list is returned. |
| */ |
| public ImmutableList<PredicateResult> getFailingAtoms() { |
| if (predicateResult().isPresent()) { |
| return predicateResult().get().getAtoms(/* status= */ false); |
| } |
| return ImmutableList.of(); |
| } |
| |
| public enum Status { |
| /** Submit requirement expression is fulfilled for a given change. */ |
| PASS, |
| |
| /** Submit requirement expression is failing for a given change. */ |
| FAIL, |
| |
| /** Submit requirement expression contains invalid syntax and is not parsable. */ |
| ERROR |
| } |
| |
| /** |
| * Entity detailing the result of evaluating a predicate. |
| * |
| * <p>Example - branch:refs/heads/foo and has:unresolved |
| * |
| * <p>The above predicate is an "And" predicate having two child predicates: |
| * |
| * <ul> |
| * <li>branch:refs/heads/foo |
| * <li>has:unresolved |
| * </ul> |
| * |
| * <p>Each child predicate as well as the parent contains the result of its evaluation. |
| */ |
| @AutoValue |
| public abstract static class PredicateResult { |
| abstract ImmutableList<PredicateResult> childPredicateResults(); |
| |
| public abstract String predicateString(); |
| |
| /** true if the predicate is passing for a given change. */ |
| abstract boolean status(); |
| |
| /** |
| * Returns the list of leaf {@link PredicateResult} whose {@link #status()} is equal to the |
| * {@code status} parameter. |
| */ |
| ImmutableList<PredicateResult> getAtoms(boolean status) { |
| ImmutableList.Builder<PredicateResult> atomsList = ImmutableList.builder(); |
| getAtomsRecursively(atomsList, status); |
| return atomsList.build(); |
| } |
| |
| private void getAtomsRecursively(ImmutableList.Builder<PredicateResult> list, boolean status) { |
| if (childPredicateResults().isEmpty() && status() == status) { |
| list.add(this); |
| return; |
| } |
| childPredicateResults().forEach(c -> c.getAtomsRecursively(list, status)); |
| } |
| |
| public static Builder builder() { |
| return new AutoValue_SubmitRequirementExpressionResult_PredicateResult.Builder(); |
| } |
| |
| @AutoValue.Builder |
| public abstract static class Builder { |
| public abstract Builder childPredicateResults(ImmutableList<PredicateResult> value); |
| |
| protected abstract ImmutableList.Builder<PredicateResult> childPredicateResultsBuilder(); |
| |
| public abstract Builder predicateString(String value); |
| |
| public abstract Builder status(boolean value); |
| |
| public Builder addChildPredicateResult(PredicateResult result) { |
| childPredicateResultsBuilder().add(result); |
| return this; |
| } |
| |
| public abstract PredicateResult build(); |
| } |
| } |
| } |