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

org.optaplanner.constraint.streams.drools.uni.DroolsAbstractUniConstraintStream Maven / Gradle / Ivy

/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you 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 org.optaplanner.constraint.streams.drools.uni;

import static org.optaplanner.constraint.streams.common.RetrievalSemantics.STANDARD;

import java.math.BigDecimal;
import java.util.Collection;
import java.util.Objects;
import java.util.function.BiFunction;
import java.util.function.Function;
import java.util.function.Predicate;
import java.util.function.ToIntFunction;
import java.util.function.ToLongFunction;

import org.optaplanner.constraint.streams.common.RetrievalSemantics;
import org.optaplanner.constraint.streams.common.ScoreImpactType;
import org.optaplanner.constraint.streams.common.bi.BiJoinerComber;
import org.optaplanner.constraint.streams.common.uni.InnerUniConstraintStream;
import org.optaplanner.constraint.streams.common.uni.UniConstraintBuilderImpl;
import org.optaplanner.constraint.streams.drools.DroolsConstraintFactory;
import org.optaplanner.constraint.streams.drools.bi.DroolsAbstractBiConstraintStream;
import org.optaplanner.constraint.streams.drools.bi.DroolsGroupingBiConstraintStream;
import org.optaplanner.constraint.streams.drools.bi.DroolsJoinBiConstraintStream;
import org.optaplanner.constraint.streams.drools.common.DroolsAbstractConstraintStream;
import org.optaplanner.constraint.streams.drools.common.RuleBuilder;
import org.optaplanner.constraint.streams.drools.common.UniLeftHandSide;
import org.optaplanner.constraint.streams.drools.quad.DroolsGroupingQuadConstraintStream;
import org.optaplanner.constraint.streams.drools.tri.DroolsGroupingTriConstraintStream;
import org.optaplanner.core.api.score.Score;
import org.optaplanner.core.api.score.stream.DefaultConstraintJustification;
import org.optaplanner.core.api.score.stream.bi.BiConstraintStream;
import org.optaplanner.core.api.score.stream.bi.BiJoiner;
import org.optaplanner.core.api.score.stream.quad.QuadConstraintStream;
import org.optaplanner.core.api.score.stream.tri.TriConstraintStream;
import org.optaplanner.core.api.score.stream.uni.UniConstraintBuilder;
import org.optaplanner.core.api.score.stream.uni.UniConstraintCollector;
import org.optaplanner.core.api.score.stream.uni.UniConstraintStream;

public abstract class DroolsAbstractUniConstraintStream
        extends DroolsAbstractConstraintStream>
        implements InnerUniConstraintStream {

    public DroolsAbstractUniConstraintStream(DroolsConstraintFactory constraintFactory,
            RetrievalSemantics retrievalSemantics) {
        super(constraintFactory, retrievalSemantics);
    }

    @Override
    public UniConstraintStream filter(Predicate predicate) {
        DroolsFilterUniConstraintStream stream = new DroolsFilterUniConstraintStream<>(constraintFactory,
                this, predicate);
        addChildStream(stream);
        return stream;
    }

    @Override
    @SafeVarargs
    public final  BiConstraintStream join(UniConstraintStream otherStream,
            BiJoiner... joiners) {
        BiJoinerComber joinerComber = BiJoinerComber.comb(joiners);
        return join(otherStream, joinerComber);
    }

    @Override
    public final  BiConstraintStream join(UniConstraintStream otherStream,
            BiJoinerComber joinerComber) {
        DroolsAbstractUniConstraintStream castOtherStream =
                (DroolsAbstractUniConstraintStream) otherStream;
        DroolsAbstractBiConstraintStream stream = new DroolsJoinBiConstraintStream<>(constraintFactory,
                this, castOtherStream, joinerComber.getMergedJoiner());
        addChildStream(stream);
        castOtherStream.addChildStream(stream);
        if (joinerComber.getMergedFiltering() == null) {
            return stream;
        } else {
            return stream.filter(joinerComber.getMergedFiltering());
        }
    }

    @SafeVarargs
    @Override
    public final  UniConstraintStream ifExists(Class otherClass, BiJoiner... joiners) {
        return ifExistsOrNot(true, getRetrievalSemantics() != STANDARD, otherClass, joiners);
    }

    @SafeVarargs
    @Override
    public final  UniConstraintStream ifExistsIncludingNullVars(Class otherClass, BiJoiner... joiners) {
        return ifExistsOrNot(true, true, otherClass, joiners);
    }

    @SafeVarargs
    @Override
    public final  UniConstraintStream ifNotExists(Class otherClass, BiJoiner... joiners) {
        return ifExistsOrNot(false, getRetrievalSemantics() != STANDARD,
                otherClass, joiners);
    }

    @SafeVarargs
    @Override
    public final  UniConstraintStream ifNotExistsIncludingNullVars(Class otherClass, BiJoiner... joiners) {
        return ifExistsOrNot(false, true, otherClass, joiners);
    }

    @SafeVarargs
    private  UniConstraintStream ifExistsOrNot(boolean shouldExist, boolean shouldIncludeNullVars,
            Class otherClass, BiJoiner... joiners) {
        getConstraintFactory().assertValidFromType(otherClass);
        DroolsExistsUniConstraintStream stream = new DroolsExistsUniConstraintStream<>(constraintFactory, this,
                shouldExist, shouldIncludeNullVars, otherClass, joiners);
        addChildStream(stream);
        return stream;
    }

    @Override
    public  UniConstraintStream groupBy(
            UniConstraintCollector collector) {
        DroolsGroupingUniConstraintStream stream = new DroolsGroupingUniConstraintStream<>(
                constraintFactory, this, collector);
        addChildStream(stream);
        return stream;
    }

    @Override
    public  BiConstraintStream groupBy(
            UniConstraintCollector collectorA,
            UniConstraintCollector collectorB) {
        DroolsGroupingBiConstraintStream stream =
                new DroolsGroupingBiConstraintStream<>(constraintFactory, this, collectorA, collectorB);
        addChildStream(stream);
        return stream;
    }

    @Override
    public 
            TriConstraintStream
            groupBy(UniConstraintCollector collectorA,
                    UniConstraintCollector collectorB,
                    UniConstraintCollector collectorC) {
        DroolsGroupingTriConstraintStream stream =
                new DroolsGroupingTriConstraintStream<>(constraintFactory, this, collectorA, collectorB, collectorC);
        addChildStream(stream);
        return stream;
    }

    @Override
    public 
            QuadConstraintStream
            groupBy(UniConstraintCollector collectorA,
                    UniConstraintCollector collectorB,
                    UniConstraintCollector collectorC,
                    UniConstraintCollector collectorD) {
        DroolsGroupingQuadConstraintStream stream =
                new DroolsGroupingQuadConstraintStream<>(constraintFactory, this, collectorA, collectorB, collectorC,
                        collectorD);
        addChildStream(stream);
        return stream;
    }

    @Override
    public  UniConstraintStream groupBy(Function groupKeyMapping) {
        DroolsGroupingUniConstraintStream stream = new DroolsGroupingUniConstraintStream<>(
                constraintFactory, this, groupKeyMapping);
        addChildStream(stream);
        return stream;
    }

    @Override
    public  BiConstraintStream groupBy(
            Function groupKeyMapping, UniConstraintCollector collector) {
        DroolsGroupingBiConstraintStream stream = new DroolsGroupingBiConstraintStream<>(
                constraintFactory, this, groupKeyMapping, collector);
        addChildStream(stream);
        return stream;
    }

    @Override
    public 
            TriConstraintStream groupBy(Function groupKeyMapping,
                    UniConstraintCollector collectorB,
                    UniConstraintCollector collectorC) {
        DroolsGroupingTriConstraintStream stream =
                new DroolsGroupingTriConstraintStream<>(constraintFactory, this, groupKeyMapping, collectorB, collectorC);
        addChildStream(stream);
        return stream;
    }

    @Override
    public 
            QuadConstraintStream
            groupBy(Function groupKeyMapping, UniConstraintCollector collectorB,
                    UniConstraintCollector collectorC,
                    UniConstraintCollector collectorD) {
        DroolsGroupingQuadConstraintStream stream =
                new DroolsGroupingQuadConstraintStream<>(constraintFactory, this, groupKeyMapping, collectorB, collectorC,
                        collectorD);
        addChildStream(stream);
        return stream;
    }

    @Override
    public  BiConstraintStream groupBy(
            Function groupKeyAMapping, Function groupKeyBMapping) {
        DroolsGroupingBiConstraintStream stream = new DroolsGroupingBiConstraintStream<>(
                constraintFactory, this, groupKeyAMapping,
                groupKeyBMapping);
        addChildStream(stream);
        return stream;
    }

    @Override
    public  TriConstraintStream groupBy(
            Function groupKeyAMapping,
            Function groupKeyBMapping, UniConstraintCollector collector) {
        DroolsGroupingTriConstraintStream stream =
                new DroolsGroupingTriConstraintStream<>(constraintFactory, this, groupKeyAMapping, groupKeyBMapping, collector);
        addChildStream(stream);
        return stream;
    }

    @Override
    public 
            QuadConstraintStream groupBy(
                    Function groupKeyAMapping,
                    Function groupKeyBMapping, UniConstraintCollector collectorC,
                    UniConstraintCollector collectorD) {
        DroolsGroupingQuadConstraintStream stream =
                new DroolsGroupingQuadConstraintStream<>(constraintFactory, this, groupKeyAMapping, groupKeyBMapping,
                        collectorC, collectorD);
        addChildStream(stream);
        return stream;
    }

    @Override
    public  TriConstraintStream groupBy(
            Function groupKeyAMapping, Function groupKeyBMapping,
            Function groupKeyCMapping) {
        DroolsGroupingTriConstraintStream stream =
                new DroolsGroupingTriConstraintStream<>(constraintFactory, this, groupKeyAMapping, groupKeyBMapping,
                        groupKeyCMapping);
        addChildStream(stream);
        return stream;
    }

    @Override
    public 
            QuadConstraintStream groupBy(Function groupKeyAMapping,
                    Function groupKeyBMapping, Function groupKeyCMapping,
                    UniConstraintCollector collectorD) {
        DroolsGroupingQuadConstraintStream stream =
                new DroolsGroupingQuadConstraintStream<>(constraintFactory, this, groupKeyAMapping, groupKeyBMapping,
                        groupKeyCMapping, collectorD);
        addChildStream(stream);
        return stream;
    }

    @Override
    public  QuadConstraintStream
            groupBy(Function groupKeyAMapping, Function groupKeyBMapping,
                    Function groupKeyCMapping, Function groupKeyDMapping) {
        DroolsGroupingQuadConstraintStream stream =
                new DroolsGroupingQuadConstraintStream<>(constraintFactory, this, groupKeyAMapping, groupKeyBMapping,
                        groupKeyCMapping, groupKeyDMapping);
        addChildStream(stream);
        return stream;
    }

    @Override
    public  UniConstraintStream map(Function mapping) {
        DroolsMappingUniConstraintStream stream =
                new DroolsMappingUniConstraintStream<>(constraintFactory, this, Objects.requireNonNull(mapping));
        addChildStream(stream);
        return stream;
    }

    @Override
    public  UniConstraintStream flattenLast(Function> mapping) {
        DroolsFlatteningUniConstraintStream stream =
                new DroolsFlatteningUniConstraintStream<>(constraintFactory, this, Objects.requireNonNull(mapping));
        addChildStream(stream);
        return stream;
    }

    // ************************************************************************
    // Pattern creation
    // ************************************************************************

    @Override
    public > UniConstraintBuilder innerImpact(Score_ constraintWeight,
            ToIntFunction matchWeigher, ScoreImpactType scoreImpactType) {
        RuleBuilder ruleBuilder = createLeftHandSide().andTerminate(matchWeigher);
        return newTerminator(ruleBuilder, constraintWeight, scoreImpactType);
    }

    private > UniConstraintBuilderImpl newTerminator(RuleBuilder ruleBuilder,
            Score_ constraintWeight, ScoreImpactType impactType) {
        return new UniConstraintBuilderImpl<>(
                (constraintPackage, constraintName, constraintWeight_, impactType_, justificationMapping,
                        indictedObjectsMapping) -> buildConstraint(constraintPackage, constraintName, constraintWeight_,
                                impactType_, justificationMapping, indictedObjectsMapping, ruleBuilder),
                impactType, constraintWeight);
    }

    @Override
    public > UniConstraintBuilder innerImpact(Score_ constraintWeight,
            ToLongFunction matchWeigher, ScoreImpactType scoreImpactType) {
        RuleBuilder ruleBuilder = createLeftHandSide().andTerminate(matchWeigher);
        return newTerminator(ruleBuilder, constraintWeight, scoreImpactType);
    }

    @Override
    public > UniConstraintBuilder innerImpact(Score_ constraintWeight,
            Function matchWeigher, ScoreImpactType scoreImpactType) {
        RuleBuilder ruleBuilder = createLeftHandSide().andTerminate(matchWeigher);
        return newTerminator(ruleBuilder, constraintWeight, scoreImpactType);
    }

    @Override
    protected final BiFunction, DefaultConstraintJustification> getDefaultJustificationMapping() {
        return InnerUniConstraintStream.createDefaultJustificationMapping();
    }

    @Override
    protected final Function> getDefaultIndictedObjectsMapping() {
        return InnerUniConstraintStream.createDefaultIndictedObjectsMapping();
    }

}