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

com.speedment.runtime.field.internal.predicate.AbstractCombinedPredicate Maven / Gradle / Ivy

/**
 *
 * Copyright (c) 2006-2017, Speedment, Inc. All Rights Reserved.
 *
 * 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.speedment.runtime.field.internal.predicate;

import com.speedment.runtime.field.predicate.CombinedPredicate;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import static java.util.Objects.requireNonNull;
import java.util.function.Predicate;
import static java.util.stream.Collectors.joining;
import java.util.stream.Stream;

/**
 * Immutable aggregation of a number of {@link Predicate Predicates} of the same type
 * (e.g. AND or OR) that can be applied in combination.
 *
 * @param  the entity type
 *
 * @author Per Minborg
 * @author Emil Forslund
 * @since 2.2.0
 */
public abstract class AbstractCombinedPredicate extends AbstractPredicate
    implements CombinedPredicate {

    private final List> predicates;
    private final Type type;

    private AbstractCombinedPredicate(
        final Type type,
        final List> predicates,
        final boolean negated
    ) {
        super(negated);
        this.type = requireNonNull(type);
        this.predicates = new ArrayList<>(requireNonNull(predicates));
    }

    @Override
    public Stream> stream() {
        return predicates.stream();
    }

    @Override
    public int size() {
        return predicates.size();
    }

    protected List> getPredicates() {
        return Collections.unmodifiableList(predicates);
    }

    @Override
    public Type getType() {
        return type;
    }

    @Override
    public abstract AndCombinedBasePredicate and(Predicate other);

    @Override
    public abstract OrCombinedBasePredicate or(Predicate other);

    public static class AndCombinedBasePredicate extends AbstractCombinedPredicate {

        public AndCombinedBasePredicate(
            final List> predicates,
            final boolean negated
        ) {
            super(Type.AND, requireNonNull(predicates), negated);
        }

        @Override
        protected boolean testWithoutNegation(ENTITY entity) {
            requireNonNull(entity);
            return stream().allMatch(p -> p.test(entity));
        }

        @Override
        public AndCombinedBasePredicate and(Predicate other) {
            requireNonNull(other);
            final List> updatedPredicates = new ArrayList<>(getPredicates());
            updatedPredicates.add(other);
            return new AndCombinedBasePredicate<>(updatedPredicates, isNegated());
        }

        @Override
        public OrCombinedBasePredicate or(Predicate other) {
            requireNonNull(other);
            return new OrCombinedBasePredicate<>(Arrays.asList(this, other), false);
        }

        @Override
        public AndCombinedBasePredicate negate() {
            return new AndCombinedBasePredicate<>(getPredicates(), !isNegated());
        }

    }

    public static class OrCombinedBasePredicate extends AbstractCombinedPredicate {

        public OrCombinedBasePredicate(
            final List> predicates,
            final boolean negated
        ) {
            super(Type.OR, requireNonNull(predicates), negated);
        }

        @Override
        protected boolean testWithoutNegation(ENTITY entity) {
            requireNonNull(entity);
            return stream().anyMatch(p -> p.test(entity));
        }

        @Override
        public AndCombinedBasePredicate and(Predicate other) {
            requireNonNull(other);
            return new AndCombinedBasePredicate<>(Arrays.asList(this, other), false);
        }

        @Override
        public OrCombinedBasePredicate or(Predicate other) {
            requireNonNull(other);
            final List> updatedPredicates = new ArrayList<>(getPredicates());
            updatedPredicates.add(other);
            return new OrCombinedBasePredicate<>(updatedPredicates, isNegated());
        }

        @Override
        public OrCombinedBasePredicate negate() {
            return new OrCombinedBasePredicate<>(getPredicates(), !isNegated());
        }

    }

    @Override
    public String toString() {
        return "CombinedPredicate {type="
            + type.name()
            + ", negated="
            + isNegated()
            + ", predicates="
            + predicates.stream()
                .map(Object::toString)
                .collect(joining(", "))
            + "}";
    }

}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy