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

org.drools.core.reteoo.builder.BuildContext Maven / Gradle / Ivy

There is a newer version: 9.44.0.Final
Show newest version
/*
 * Copyright 2010 Red Hat, Inc. and/or its affiliates.
 *
 * 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.drools.core.reteoo.builder;

import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
import java.util.ListIterator;
import java.util.Stack;

import org.drools.core.common.BaseNode;
import org.drools.core.common.InternalWorkingMemory;
import org.drools.core.common.NetworkNode;
import org.drools.core.common.RuleBasePartitionId;
import org.drools.core.definitions.rule.impl.RuleImpl;
import org.drools.core.impl.InternalKnowledgeBase;
import org.drools.core.reteoo.KieComponentFactory;
import org.drools.core.reteoo.LeftTupleSource;
import org.drools.core.reteoo.ObjectSource;
import org.drools.core.reteoo.ObjectTypeNode;
import org.drools.core.reteoo.PathEndNode;
import org.drools.core.rule.EntryPointId;
import org.drools.core.rule.GroupElement;
import org.drools.core.rule.Pattern;
import org.drools.core.rule.RuleConditionElement;
import org.drools.core.rule.constraint.XpathConstraint;
import org.drools.core.spi.AlphaNodeFieldConstraint;
import org.drools.core.spi.BetaNodeFieldConstraint;
import org.drools.core.spi.RuleComponent;
import org.drools.core.time.TemporalDependencyMatrix;

import static org.drools.core.rule.TypeDeclaration.NEVER_EXPIRES;

/**
 * A build context for Reteoo Builder
 */
public class BuildContext {

    // tuple source to attach next node to
    private LeftTupleSource                  tupleSource;
    // object source to attach next node to
    private ObjectSource                     objectSource;
    // object type cache to check for cross products
    private LinkedList              objectType;
    // offset of the pattern
    private int                              currentPatternOffset;
    // rule base to add rules to
    private InternalKnowledgeBase            kBase;
    // rule being added at this moment
    private RuleImpl                         rule;
    private GroupElement                     subRule;
    // the rule component being processed at the moment
    private Stack             ruleComponent;
    // working memories attached to the given rulebase
    private InternalWorkingMemory[]          workingMemories;
    // a build stack to track nested elements
    private LinkedList buildstack;
    // beta constraints from the last pattern attached
    private List    betaconstraints;
    // alpha constraints from the last pattern attached
    private List   alphaConstraints;
    // xpath constraints from the last pattern attached
    private List            xpathConstraints;
    // the current entry point
    private EntryPointId                     currentEntryPoint;
    private boolean                          tupleMemoryEnabled;
    private boolean                          objectTypeNodeMemoryEnabled;
    private boolean                          query;

    private List                pathEndNodes = new ArrayList<>();
    /**
     * Stores the list of nodes being added that require partitionIds
     */
    private List                   nodes;
    /**
     * Stores the id of the partition this rule will be added to
     */
    private RuleBasePartitionId              partitionId;
    /**
     * the calculate temporal distance matrix
     */
    private TemporalDependencyMatrix         temporal;
    private ObjectTypeNode                   rootObjectTypeNode;
    private Pattern[]                        lastBuiltPatterns;
    // The reason why this is here is because forall can inject a
    //  "this == " + BASE_IDENTIFIER $__forallBaseIdentifier
    // Which we don't want to actually count in the case of forall node linking    
    private boolean                          emptyForAllBetaConstraints;
    private boolean                          attachPQN;
    private boolean                          terminated;

    private final KieComponentFactory        componentFactory;

    private String                           consequenceName;

    public BuildContext(final InternalKnowledgeBase kBase) {
        this.kBase = kBase;

        this.workingMemories = null;

        this.objectType = null;
        this.buildstack = null;

        this.tupleSource = null;
        this.objectSource = null;

        this.currentPatternOffset = 0;

        this.tupleMemoryEnabled = true;

        this.objectTypeNodeMemoryEnabled = true;

        this.currentEntryPoint = EntryPointId.DEFAULT;

        this.nodes = new LinkedList<>();

        this.partitionId = null;

        this.ruleComponent = new Stack<>();

        this.attachPQN = true;

        this.componentFactory = kBase.getConfiguration().getComponentFactory();

        this.emptyForAllBetaConstraints = false;
    }

    public boolean isEmptyForAllBetaConstraints() {
        return emptyForAllBetaConstraints;
    }

    void setEmptyForAllBetaConstraints() {
        this.emptyForAllBetaConstraints = true;
    }

    /**
     * @return the currentPatternOffset
     */
    public int getCurrentPatternOffset() {
        return this.currentPatternOffset;
    }

    /**
     * @param currentPatternIndex the currentPatternOffset to set
     */
    void setCurrentPatternOffset(final int currentPatternIndex) {
        this.currentPatternOffset = currentPatternIndex;
        this.syncObjectTypesWithPatternOffset();
    }

    private void syncObjectTypesWithPatternOffset() {
        if (this.objectType == null) {
            this.objectType = new LinkedList<>();
        }
        while (this.objectType.size() > this.currentPatternOffset) {
            this.objectType.removeLast();
        }
    }

    /**
     * @return the objectSource
     */
    public ObjectSource getObjectSource() {
        return this.objectSource;
    }

    /**
     * @param objectSource the objectSource to set
     */
    public void setObjectSource(final ObjectSource objectSource) {
        this.objectSource = objectSource;
    }

    /**
     * @return the objectType
     */
    public LinkedList getObjectType() {
        if (this.objectType == null) {
            this.objectType = new LinkedList<>();
        }
        return this.objectType;
    }

    /**
     * @param objectType the objectType to set
     */
    public void setObjectType(final LinkedList objectType) {
        if (this.objectType == null) {
            this.objectType = new LinkedList<>();
        }
        this.objectType = objectType;
    }

    /**
     * @return the tupleSource
     */
    public LeftTupleSource getTupleSource() {
        return this.tupleSource;
    }

    /**
     * @param tupleSource the tupleSource to set
     */
    public void setTupleSource(final LeftTupleSource tupleSource) {
        this.tupleSource = tupleSource;
    }

    public void incrementCurrentPatternOffset() {
        this.currentPatternOffset++;
    }

    public void decrementCurrentPatternOffset() {
        this.currentPatternOffset--;
        this.syncObjectTypesWithPatternOffset();
    }

    /**
     * Returns context rulebase
     */
    public InternalKnowledgeBase getKnowledgeBase() {
        return this.kBase;
    }

    /**
     * Return the array of working memories associated with the given
     * rulebase.
     */
    public InternalWorkingMemory[] getWorkingMemories() {
        if (this.workingMemories == null) {
            this.workingMemories = this.kBase.getWorkingMemories();
        }
        return this.workingMemories;
    }

    /**
     * Returns an Id for the next node
     */
    public int getNextId() {
        return kBase.getReteooBuilder().getIdGenerator().getNextId();
    }

    public int getNextId(String topic) {
        return kBase.getReteooBuilder().getIdGenerator().getNextId(topic);
    }

    /**
     * Method used to undo previous id assignment
     */
    public void releaseId(NetworkNode node) {
        kBase.getReteooBuilder().getIdGenerator().releaseId(rule, node);
    }

    /**
     * Adds the rce to the build stack
     */
    public void push(final RuleConditionElement rce) {
        if (this.buildstack == null) {
            this.buildstack = new LinkedList<>();
        }
        this.buildstack.addLast(rce);
    }

    /**
     * Removes the top stack element
     */
    public RuleConditionElement pop() {
        if (this.buildstack == null) {
            this.buildstack = new LinkedList<>();
        }
        return this.buildstack.removeLast();
    }

    /**
     * Returns the top stack element without removing it
     */
    public RuleConditionElement peek() {
        if (this.buildstack == null) {
            this.buildstack = new LinkedList<>();
        }
        return this.buildstack.getLast();
    }

    /**
     * Returns a list iterator to iterate over the stacked elements
     */
    ListIterator stackIterator() {
        if (this.buildstack == null) {
            this.buildstack = new LinkedList<>();
        }
        return this.buildstack.listIterator(this.buildstack.size());
    }

    public List getBetaconstraints() {
        return this.betaconstraints;
    }

    public void setBetaconstraints(final List betaconstraints) {
        this.betaconstraints = betaconstraints;
    }

    public List getAlphaConstraints() {
        return alphaConstraints;
    }

    void setAlphaConstraints(List alphaConstraints) {
        this.alphaConstraints = alphaConstraints;
    }

    List getXpathConstraints() {
        return xpathConstraints;
    }

    List getPathEndNodes() {
        return pathEndNodes;
    }

    public void addPathEndNode(PathEndNode node) {
        pathEndNodes.add(node);
    }

    void setXpathConstraints(List xpathConstraints) {
        this.xpathConstraints = xpathConstraints;
    }

    public boolean isTupleMemoryEnabled() {
        return this.tupleMemoryEnabled;
    }

    public void setTupleMemoryEnabled(boolean hasLeftMemory) {
        this.tupleMemoryEnabled = hasLeftMemory;
    }

    public boolean isObjectTypeNodeMemoryEnabled() {
        return objectTypeNodeMemoryEnabled;
    }

    public void setObjectTypeNodeMemoryEnabled(boolean hasObjectTypeMemory) {
        this.objectTypeNodeMemoryEnabled = hasObjectTypeMemory;
    }

    public boolean isQuery() {
        return query;
    }

    /**
     * @return the currentEntryPoint
     */
    public EntryPointId getCurrentEntryPoint() {
        return currentEntryPoint;
    }

    /**
     * @param currentEntryPoint the currentEntryPoint to set
     */
    public void setCurrentEntryPoint(EntryPointId currentEntryPoint) {
        this.currentEntryPoint = currentEntryPoint;
    }

    /**
     * @return the nodes
     */
    public List getNodes() {
        return nodes;
    }

    BaseNode getLastNode() {
        return nodes.get(nodes.size()-1);
    }

    /**
     * @param nodes the nodes to set
     */
    public void setNodes(List nodes) {
        this.nodes = nodes;
    }

    /**
     * @return the partitionId
     */
    public RuleBasePartitionId getPartitionId() {
        return partitionId;
    }

    /**
     * @param partitionId the partitionId to set
     */
    public void setPartitionId(RuleBasePartitionId partitionId) {
        this.partitionId = partitionId;
    }

    public boolean isStreamMode() {
        // eager rules don't need to use the event queue
        return this.temporal != null && !rule.isEager();
    }

    public long getExpirationOffset(Pattern pattern) {
        return temporal != null ? temporal.getExpirationOffset( pattern ) : NEVER_EXPIRES;
    }

    void setTemporalDistance(TemporalDependencyMatrix temporal) {
        this.temporal = temporal;
    }

    public RuleImpl getRule() {
        return rule;
    }

    public void setRule(RuleImpl rule) {
        this.rule = rule;
        if (rule.isQuery()) {
            this.query = true;
        }
    }

    public GroupElement getSubRule() {
        return subRule;
    }

    void setSubRule(GroupElement subRule) {
        this.subRule = subRule;
    }

    /**
     * Removes the top element from the rule component stack.
     * The rule component stack is used to add trackability to
     * the ReteOO nodes so that they can be linked to the rule
     * components that originated them.
     */
    public RuleComponent popRuleComponent() {
        return this.ruleComponent.pop();
    }

    /**
     * Peeks at the top element from the rule component stack.
     * The rule component stack is used to add trackability to
     * the ReteOO nodes so that they can be linked to the rule
     * components that originated them.
     */
    public RuleComponent peekRuleComponent() {
        return this.ruleComponent.isEmpty() ? null : this.ruleComponent.peek();
    }

    /**
     * Adds the ruleComponent to the top of the rule component stack.
     * The rule component stack is used to add trackability to
     * the ReteOO nodes so that they can be linked to the rule
     * components that originated them.
     */
    public void pushRuleComponent(RuleComponent ruleComponent) {
        this.ruleComponent.push(ruleComponent);
    }

    public ObjectTypeNode getRootObjectTypeNode() {
        return rootObjectTypeNode;
    }

    public void setRootObjectTypeNode(ObjectTypeNode source) {
        rootObjectTypeNode = source;
    }

    public Pattern[] getLastBuiltPatterns() {
        return lastBuiltPatterns;
    }

    public void setLastBuiltPattern(Pattern lastBuiltPattern) {
        if (this.lastBuiltPatterns == null) {
            this.lastBuiltPatterns = new Pattern[]{lastBuiltPattern, null};
        } else {
            this.lastBuiltPatterns[1] = this.lastBuiltPatterns[0];
            this.lastBuiltPatterns[0] = lastBuiltPattern;
        }
    }

    boolean isAttachPQN() {
        return attachPQN;
    }

    void setAttachPQN(final boolean attachPQN) {
        this.attachPQN = attachPQN;
    }

    public KieComponentFactory getComponentFactory() {
        return componentFactory;
    }

    boolean isTerminated() {
        return terminated;
    }

    void setTerminated(boolean terminated) {
        this.terminated = terminated;
    }

    public String getConsequenceName() {
        return consequenceName;
    }

    public void setConsequenceName( String consequenceName ) {
        this.consequenceName = consequenceName;
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy