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

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

Go to download

Partly generated model of the fields that represent columns in the database. Fields can be used to produce special predicates and functions that contain metadata that Speedment can analyze runtime.

There is a newer version: 3.2.10
Show newest version
/**
 *
 * 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.Iterator;
import java.util.List;
import java.util.function.Predicate;
import java.util.stream.Stream;

import static com.speedment.runtime.field.internal.util.CollectionUtil.copyAndAdd;
import static java.util.Collections.unmodifiableList;
import static java.util.Objects.requireNonNull;
import static java.util.stream.Collectors.toList;

/**
 * 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) {

        this.type       = requireNonNull(type);
        this.predicates = requireNonNull(predicates);
    }

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

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

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

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

    @Override
    public abstract CombinedPredicate and(Predicate other);

    @Override
    public abstract CombinedPredicate or(Predicate other);

    /**
     * Specialization for {@code AND}-predicates.
     *
     * @param   the entity type
     */
    public static final class AndCombinedBasePredicate
    extends AbstractCombinedPredicate {

        public AndCombinedBasePredicate(
                List> predicates) {

            super(Type.AND, predicates);
        }

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

        @Override
        public CombinedPredicate and(Predicate other) {
            requireNonNull(other);
            return new AndCombinedBasePredicate<>(
                copyAndAdd(getPredicates(), other)
            );
        }

        @Override
        public CombinedPredicate or(Predicate other) {
            requireNonNull(other);
            return CombinedPredicate.or(this, other);
        }

        @Override
        @SuppressWarnings("unchecked")
        public CombinedPredicate negate() {
            return new OrCombinedBasePredicate<>(
                getPredicates().stream()
                    .map(p -> (Predicate) p)
                    .map(Predicate::negate)
                    .collect(toList())
            );
        }
    }

    /**
     * Specialization for {@code OR}-predicates.
     *
     * @param   the entity type
     */
    public static final class OrCombinedBasePredicate
    extends AbstractCombinedPredicate {

        public OrCombinedBasePredicate(
                List> predicates) {

            super(Type.OR, predicates);
        }

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

        @Override
        public CombinedPredicate and(Predicate other) {
            requireNonNull(other);
            return CombinedPredicate.and(this, other);
        }

        @Override
        public CombinedPredicate or(Predicate other) {
            requireNonNull(other);
            return new OrCombinedBasePredicate<>(
                copyAndAdd(getPredicates(), other)
            );
        }

        @Override
        @SuppressWarnings("unchecked")
        public AndCombinedBasePredicate negate() {
            return new AndCombinedBasePredicate<>(
                getPredicates().stream()
                    .map(p -> (Predicate) p)
                    .map(Predicate::negate)
                    .collect(toList())
            );
        }
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (!(o instanceof CombinedPredicate)) return false;

        final CombinedPredicate that = (CombinedPredicate) o;
        final Iterator> it = predicates.iterator();
        return getType() == that.getType()
            && that.stream().allMatch(it.next()::equals);
    }

    @Override
    public int hashCode() {
        int result = getPredicates().hashCode();
        result = 31 * result + getType().hashCode();
        return result;
    }

    @Override
    public String toString() {
        return "CombinedPredicate {type="
            + type.name()
            + ", predicates="
            + predicates
            + "}";
    }

}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy