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

org.drools.core.reteoo.TimerNode Maven / Gradle / Ivy

There is a newer version: 9.44.0.Final
Show newest version
/*
 * Copyright 2005 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;

import java.io.IOException;
import java.io.ObjectInput;
import java.io.ObjectOutput;
import java.util.Arrays;

import org.drools.core.RuleBaseConfiguration;
import org.drools.core.common.InternalFactHandle;
import org.drools.core.common.InternalWorkingMemory;
import org.drools.core.common.Memory;
import org.drools.core.common.MemoryFactory;
import org.drools.core.common.UpdateContext;
import org.drools.core.reteoo.builder.BuildContext;
import org.drools.core.rule.Declaration;
import org.drools.core.spi.PropagationContext;
import org.drools.core.time.impl.Timer;
import org.drools.core.util.AbstractBaseLinkedListNode;
import org.drools.core.util.index.TupleList;

public class TimerNode extends LeftTupleSource
        implements
        LeftTupleSinkNode,
        MemoryFactory {

    private static final long serialVersionUID = 510l;
    private Timer             timer;
    private String[]          calendarNames;
    private boolean           tupleMemoryEnabled;
    private Declaration[][]   declarations;
    private LeftTupleSinkNode previousTupleSinkNode;
    private LeftTupleSinkNode nextTupleSinkNode;

    // ------------------------------------------------------------
    // Constructors
    // ------------------------------------------------------------
    public TimerNode() {

    }

    public TimerNode(final int id,
                     final LeftTupleSource tupleSource,
                     final Timer timer,
                     final String[] calendarNames,
                     final Declaration[][]   declarations,
                     final BuildContext context) {
        super(id, context);
        setLeftTupleSource(tupleSource);
        this.timer = timer;
        this.calendarNames = calendarNames;
        this.declarations = declarations;
        this.tupleMemoryEnabled = context.isTupleMemoryEnabled();

        initMasks(context, tupleSource);

        hashcode = calculateHashCode();
    }

    public void readExternal(ObjectInput in) throws IOException,
            ClassNotFoundException {
        super.readExternal(in);
        timer = (Timer) in.readObject();
        calendarNames = (String[]) in.readObject();
        tupleMemoryEnabled = in.readBoolean();
        declarations = ( Declaration[][] ) in.readObject();
    }

    public void writeExternal(ObjectOutput out) throws IOException {
        super.writeExternal(out);
        out.writeObject(timer);
        out.writeObject( calendarNames );
        out.writeBoolean(tupleMemoryEnabled);
        out.writeObject( declarations );
    }

    public void attach(BuildContext context) {
        this.leftInput.addTupleSink(this, context);
    }

    public void networkUpdated(UpdateContext updateContext) {
        this.leftInput.networkUpdated(updateContext);
    }

    public Timer getTimer() {
        return this.timer;
    }

    public String[] getCalendarNames() {
        return this.calendarNames;
    }

    public Declaration[][] getDeclarations() {
        return this.declarations;
    }

    /**
     * Produce a debug string.
     *
     * @return The debug string.
     */
    public String toString() {
        return "[TimerNode(" + this.id + "): cond=" + this.timer + " calendars=" + ((calendarNames == null) ? "null" : Arrays.asList(calendarNames)) + "]";
    }

    private int calculateHashCode() {
        int hash = this.leftInput.hashCode() ^ this.timer.hashCode();
        if (calendarNames != null) {
            for ( String calendarName : calendarNames ) {
                hash = hash ^ calendarName.hashCode();
            }
        }
        return hash;
    }

    public boolean equals(final Object object) {
        return this == object ||
               ( internalEquals( object ) && this.leftInput.thisNodeEquals(((TimerNode)object).leftInput) );
    }

    @Override
    protected boolean internalEquals( Object object ) {
        if ( object == null || !(object instanceof TimerNode) || this.hashCode() != object.hashCode() ) {
            return false;
        }

        TimerNode other = (TimerNode) object;
        if (calendarNames != null) {
            if (other.getCalendarNames() == null || other.getCalendarNames().length != calendarNames.length) {
                return false;
            }

            for (int i = 0; i < calendarNames.length; i++) {
                if (!other.getCalendarNames()[i].equals(calendarNames[i])) {
                    return false;
                }
            }
        }

        return Arrays.deepEquals( declarations, other.declarations ) &&
               this.timer.equals(other.timer);
    }

    public TimerNodeMemory createMemory(final RuleBaseConfiguration config, InternalWorkingMemory wm) {
        return new TimerNodeMemory();
    }

    @Override
    public LeftTuple createPeer(LeftTuple original) {
        EvalNodeLeftTuple peer = new EvalNodeLeftTuple();
        peer.initPeer((BaseLeftTuple) original, this);
        original.setPeer(peer);
        return peer;
    }

    protected boolean doRemove(final RuleRemovalContext context,
                            final ReteooBuilder builder,
                            final InternalWorkingMemory[] workingMemories) {
        if (!this.isInUse()) {
            getLeftTupleSource().removeTupleSink(this);
            return true;
        }
        return false;
    }

    public boolean isLeftTupleMemoryEnabled() {
        return tupleMemoryEnabled;
    }

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

    /**
     * Returns the next node
     *
     * @return The next TupleSinkNode
     */
    public LeftTupleSinkNode getNextLeftTupleSinkNode() {
        return this.nextTupleSinkNode;
    }

    /**
     * Sets the next node
     *
     * @param next The next TupleSinkNode
     */
    public void setNextLeftTupleSinkNode(final LeftTupleSinkNode next) {
        this.nextTupleSinkNode = next;
    }

    /**
     * Returns the previous node
     *
     * @return The previous TupleSinkNode
     */
    public LeftTupleSinkNode getPreviousLeftTupleSinkNode() {
        return this.previousTupleSinkNode;
    }

    /**
     * Sets the previous node
     *
     * @param previous The previous TupleSinkNode
     */
    public void setPreviousLeftTupleSinkNode(final LeftTupleSinkNode previous) {
        this.previousTupleSinkNode = previous;
    }

    public short getType() {
        return NodeTypeEnums.TimerConditionNode;
    }

    public LeftTuple createLeftTuple(InternalFactHandle factHandle,
                                     Sink sink,
                                     boolean leftTupleMemoryEnabled) {
        return new EvalNodeLeftTuple(factHandle, sink, leftTupleMemoryEnabled);
    }

    public LeftTuple createLeftTuple(final InternalFactHandle factHandle,
                                     final LeftTuple leftTuple,
                                     final Sink sink) {
        return new EvalNodeLeftTuple(factHandle, leftTuple, sink);
    }

    public LeftTuple createLeftTuple(LeftTuple leftTuple,
                                     Sink sink,
                                     PropagationContext pctx, boolean leftTupleMemoryEnabled) {
        return new EvalNodeLeftTuple(leftTuple, sink, pctx, leftTupleMemoryEnabled);
    }

    public LeftTuple createLeftTuple(LeftTuple leftTuple,
                                     RightTuple rightTuple,
                                     Sink sink) {
        return new EvalNodeLeftTuple(leftTuple, rightTuple, sink);
    }

    public LeftTuple createLeftTuple(LeftTuple leftTuple,
                                     RightTuple rightTuple,
                                     LeftTuple currentLeftChild,
                                     LeftTuple currentRightChild,
                                     Sink sink,
                                     boolean leftTupleMemoryEnabled) {
        return new EvalNodeLeftTuple(leftTuple, rightTuple, currentLeftChild, currentRightChild, sink, leftTupleMemoryEnabled);
    }

    @Override
    public ObjectTypeNode getObjectTypeNode() {
        return leftInput.getObjectTypeNode();
    }

    public static class TimerNodeMemory extends AbstractBaseLinkedListNode
            implements
            SegmentNodeMemory {

        private static final long serialVersionUID = 510l;
        private TupleList insertOrUpdateLeftTuples;
        private TupleList deleteLeftTuples;
        private SegmentMemory memory;
        private long          nodePosMaskBit;


        public TimerNodeMemory() {
            this.insertOrUpdateLeftTuples = new TupleList();
            this.deleteLeftTuples = new TupleList();
        }

        public TupleList getInsertOrUpdateLeftTuples() {
            return this.insertOrUpdateLeftTuples;
        }

        public TupleList getDeleteLeftTuples() {
            return this.deleteLeftTuples;
        }

        public short getNodeType() {
            return NodeTypeEnums.TimerConditionNode;
        }

        public SegmentMemory getSegmentMemory() {
            return this.memory;
        }

        public void setSegmentMemory(SegmentMemory smem) {
            this.memory = smem;
        }

        public long getNodePosMaskBit() {
            return nodePosMaskBit;
        }

        public void setNodePosMaskBit(long segmentPos) {
            this.nodePosMaskBit = segmentPos;
        }

        public void setNodeDirtyWithoutNotify() {
            memory.updateDirtyNodeMask( nodePosMaskBit );
        }

        public void setNodeCleanWithoutNotify() {
            memory.updateCleanNodeMask( nodePosMaskBit );
        }

        public void reset() {
            insertOrUpdateLeftTuples.clear();
            deleteLeftTuples.clear();
        }
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy