Package org.optaplanner.core.api.score.holder

Source Code of org.optaplanner.core.api.score.holder.AbstractScoreHolder

/*
* Copyright 2010 JBoss Inc
*
* 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 org.optaplanner.core.api.score.holder;

import java.io.Serializable;
import java.math.BigDecimal;
import java.util.Arrays;
import java.util.Collection;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

import org.drools.core.common.AgendaItem;
import org.kie.api.definition.rule.Rule;
import org.kie.api.runtime.rule.Match;
import org.kie.api.runtime.rule.RuleContext;
import org.kie.api.runtime.rule.RuleRuntime;
import org.kie.internal.event.rule.ActivationUnMatchListener;
import org.optaplanner.core.api.score.constraint.ConstraintMatchTotal;
import org.optaplanner.core.api.score.constraint.bigdecimal.BigDecimalConstraintMatch;
import org.optaplanner.core.api.score.constraint.bigdecimal.BigDecimalConstraintMatchTotal;
import org.optaplanner.core.api.score.constraint.primdouble.DoubleConstraintMatch;
import org.optaplanner.core.api.score.constraint.primdouble.DoubleConstraintMatchTotal;
import org.optaplanner.core.api.score.constraint.primint.IntConstraintMatch;
import org.optaplanner.core.api.score.constraint.primint.IntConstraintMatchTotal;
import org.optaplanner.core.api.score.constraint.primlong.LongConstraintMatch;
import org.optaplanner.core.api.score.constraint.primlong.LongConstraintMatchTotal;

/**
* Abstract superclass for {@link ScoreHolder}.
*/
public abstract class AbstractScoreHolder implements ScoreHolder, Serializable {

    protected final boolean constraintMatchEnabled;
    protected final Map<List<Object>, ConstraintMatchTotal> constraintMatchTotalMap;

    protected AbstractScoreHolder(boolean constraintMatchEnabled) {
        this.constraintMatchEnabled = constraintMatchEnabled;
        // TODO Can we set the initial capacity of this map more accurately? For example: number of rules
        constraintMatchTotalMap = constraintMatchEnabled
                ? new LinkedHashMap<List<Object>, ConstraintMatchTotal>() : null;
    }

    public boolean isConstraintMatchEnabled() {
        return constraintMatchEnabled;
    }

    public Collection<ConstraintMatchTotal> getConstraintMatchTotals() {
        return constraintMatchTotalMap.values();
    }

    // ************************************************************************
    // Worker methods
    // ************************************************************************

    protected void registerIntConstraintMatch(RuleContext kcontext, int scoreLevel, int weight,
            final IntConstraintUndoListener constraintUndoListener) {
        AgendaItem agendaItem = prepareAgendaItemForUnMatchListener(kcontext);
        if (constraintMatchEnabled) {
            // Not needed in fast code: Add ConstraintMatch
            constraintUndoListener.constraintMatchTotal = findIntConstraintMatchTotal(kcontext, scoreLevel);
            constraintUndoListener.constraintMatch = constraintUndoListener
                    .constraintMatchTotal.addConstraintMatch(kcontext, weight);
        }
        agendaItem.setActivationUnMatchListener(constraintUndoListener);
    }

    protected abstract class IntConstraintUndoListener implements ActivationUnMatchListener {

        private IntConstraintMatchTotal constraintMatchTotal;
        private IntConstraintMatch constraintMatch;

        public final void unMatch(RuleRuntime wm, Match activation) {
            undo();
            if (constraintMatchEnabled) {
                // Not needed in fast code: Remove ConstraintMatch
                constraintMatchTotal.removeConstraintMatch(constraintMatch);
            }
        }

        public abstract void undo();

    }

    private IntConstraintMatchTotal findIntConstraintMatchTotal(RuleContext kcontext, int scoreLevel) {
        Rule rule = kcontext.getRule();
        String constraintPackage = rule.getPackageName();
        String constraintName = rule.getName();
        List<Object> key = Arrays.<Object>asList(constraintPackage, constraintName, scoreLevel);
        IntConstraintMatchTotal matchTotal = (IntConstraintMatchTotal) constraintMatchTotalMap.get(key);
        if (matchTotal == null) {
            matchTotal = new IntConstraintMatchTotal(constraintPackage, constraintName, scoreLevel);
            constraintMatchTotalMap.put(key, matchTotal);
        }
        return matchTotal;
    }

    protected void registerLongConstraintMatch(RuleContext kcontext, int scoreLevel, long weight,
            final LongConstraintUndoListener constraintUndoListener) {
        AgendaItem agendaItem = prepareAgendaItemForUnMatchListener(kcontext);
        if (constraintMatchEnabled) {
            // Not needed in fast code: Add ConstraintMatch
            constraintUndoListener.constraintMatchTotal = findLongConstraintMatchTotal(kcontext, scoreLevel);
            constraintUndoListener.constraintMatch = constraintUndoListener
                    .constraintMatchTotal.addConstraintMatch(kcontext, weight);
        }
        agendaItem.setActivationUnMatchListener(constraintUndoListener);
    }

    protected abstract class LongConstraintUndoListener implements ActivationUnMatchListener {

        private LongConstraintMatchTotal constraintMatchTotal;
        private LongConstraintMatch constraintMatch;

        public final void unMatch(RuleRuntime wm, Match activation) {
            undo();
            if (constraintMatchEnabled) {
                // Not needed in fast code: Remove ConstraintMatch
                constraintMatchTotal.removeConstraintMatch(constraintMatch);
            }
        }

        public abstract void undo();

    }

    private LongConstraintMatchTotal findLongConstraintMatchTotal(RuleContext kcontext, int scoreLevel) {
        Rule rule = kcontext.getRule();
        String constraintPackage = rule.getPackageName();
        String constraintName = rule.getName();
        List<Object> key = Arrays.<Object>asList(constraintPackage, constraintName, scoreLevel);
        LongConstraintMatchTotal matchTotal = (LongConstraintMatchTotal) constraintMatchTotalMap.get(key);
        if (matchTotal == null) {
            matchTotal = new LongConstraintMatchTotal(constraintPackage, constraintName, scoreLevel);
            constraintMatchTotalMap.put(key, matchTotal);
        }
        return matchTotal;
    }

    protected void registerDoubleConstraintMatch(RuleContext kcontext, int scoreLevel, double weight,
            final DoubleConstraintUndoListener constraintUndoListener) {
        AgendaItem agendaItem = prepareAgendaItemForUnMatchListener(kcontext);
        if (constraintMatchEnabled) {
            // Not needed in fast code: Add ConstraintMatch
            constraintUndoListener.constraintMatchTotal = findDoubleConstraintMatchTotal(kcontext, scoreLevel);
            constraintUndoListener.constraintMatch = constraintUndoListener
                    .constraintMatchTotal.addConstraintMatch(kcontext, weight);
        }
        agendaItem.setActivationUnMatchListener(constraintUndoListener);
    }

    protected abstract class DoubleConstraintUndoListener implements ActivationUnMatchListener {

        private DoubleConstraintMatchTotal constraintMatchTotal;
        private DoubleConstraintMatch constraintMatch;

        public final void unMatch(RuleRuntime wm, Match activation) {
            undo();
            if (constraintMatchEnabled) {
                // Not needed in fast code: Remove ConstraintMatch
                constraintMatchTotal.removeConstraintMatch(constraintMatch);
            }
        }

        public abstract void undo();

    }

    private DoubleConstraintMatchTotal findDoubleConstraintMatchTotal(RuleContext kcontext, int scoreLevel) {
        Rule rule = kcontext.getRule();
        String constraintPackage = rule.getPackageName();
        String constraintName = rule.getName();
        List<Object> key = Arrays.<Object>asList(constraintPackage, constraintName, scoreLevel);
        DoubleConstraintMatchTotal matchTotal = (DoubleConstraintMatchTotal) constraintMatchTotalMap.get(key);
        if (matchTotal == null) {
            matchTotal = new DoubleConstraintMatchTotal(constraintPackage, constraintName, scoreLevel);
            constraintMatchTotalMap.put(key, matchTotal);
        }
        return matchTotal;
    }

    protected void registerBigDecimalConstraintMatch(RuleContext kcontext, int scoreLevel, BigDecimal weight,
            final BigDecimalConstraintUndoListener constraintUndoListener) {
        AgendaItem agendaItem = prepareAgendaItemForUnMatchListener(kcontext);
        if (constraintMatchEnabled) {
            // Not needed in fast code: Add ConstraintMatch
            constraintUndoListener.constraintMatchTotal = findBigDecimalConstraintMatchTotal(kcontext, scoreLevel);
            constraintUndoListener.constraintMatch = constraintUndoListener
                    .constraintMatchTotal.addConstraintMatch(kcontext, weight);
        }
        agendaItem.setActivationUnMatchListener(constraintUndoListener);
    }

    protected abstract class BigDecimalConstraintUndoListener implements ActivationUnMatchListener {

        private BigDecimalConstraintMatchTotal constraintMatchTotal;
        private BigDecimalConstraintMatch constraintMatch;

        public final void unMatch(RuleRuntime wm, Match activation) {
            undo();
            if (constraintMatchEnabled) {
                // Not needed in fast code: Remove ConstraintMatch
                constraintMatchTotal.removeConstraintMatch(constraintMatch);
            }
        }

        public abstract void undo();

    }

    private BigDecimalConstraintMatchTotal findBigDecimalConstraintMatchTotal(RuleContext kcontext, int scoreLevel) {
        Rule rule = kcontext.getRule();
        String constraintPackage = rule.getPackageName();
        String constraintName = rule.getName();
        List<Object> key = Arrays.<Object>asList(constraintPackage, constraintName, scoreLevel);
        BigDecimalConstraintMatchTotal matchTotal = (BigDecimalConstraintMatchTotal) constraintMatchTotalMap.get(key);
        if (matchTotal == null) {
            matchTotal = new BigDecimalConstraintMatchTotal(constraintPackage, constraintName, scoreLevel);
            constraintMatchTotalMap.put(key, matchTotal);
        }
        return matchTotal;
    }

    private AgendaItem prepareAgendaItemForUnMatchListener(RuleContext kcontext) {
        AgendaItem agendaItem = (AgendaItem) kcontext.getMatch();
        if (agendaItem.getActivationUnMatchListener() != null) {
            // Both parameters null because they are not used by the ActivationUnMatchListener created anyway
            agendaItem.getActivationUnMatchListener().unMatch(null, null);
        }
        return agendaItem;
    }

}
TOP

Related Classes of org.optaplanner.core.api.score.holder.AbstractScoreHolder

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.
ts)},i[r].l=1*new Date();a=s.createElement(o), m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m) })(window,document,'script','//www.google-analytics.com/analytics.js','ga'); ga('create', 'UA-20639858-1', 'auto'); ga('send', 'pageview');