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

org.drools.core.phreak.ReactiveObjectUtil Maven / Gradle / Ivy

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

import org.drools.core.common.BetaConstraints;
import org.drools.core.common.InternalFactHandle;
import org.drools.core.common.InternalWorkingMemory;
import org.drools.core.reteoo.LeftTuple;
import org.drools.core.reteoo.LeftTupleSinkNode;
import org.drools.core.reteoo.ReactiveFromNode;
import org.drools.core.reteoo.ReactiveFromNodeLeftTuple;
import org.drools.core.reteoo.RightTupleImpl;
import org.drools.core.rule.ContextEntry;
import org.drools.core.spi.PropagationContext;
import org.drools.core.spi.Tuple;

import java.util.Collection;

import static org.drools.core.phreak.PhreakFromNode.*;

public class ReactiveObjectUtil {

    public enum ModificationType {
        NONE, MODIFY, ADD, REMOVE
    }

    public static void notifyModification(ReactiveObject reactiveObject) {
        notifyModification( reactiveObject, reactiveObject.getLeftTuples(), ModificationType.MODIFY);
    }

    public static void notifyModification( Object object, Collection leftTuples, ModificationType type ) {
        for (Tuple leftTuple : leftTuples) {
            if (!( (ReactiveFromNodeLeftTuple) leftTuple ).updateModificationState( object, type )) {
                continue;
            }
            PropagationContext propagationContext = leftTuple.getPropagationContext();
            ReactiveFromNode node = (ReactiveFromNode)leftTuple.getTupleSink();

            LeftTupleSinkNode sink = node.getSinkPropagator().getFirstLeftTupleSink();
            InternalWorkingMemory wm = getInternalWorkingMemory(propagationContext);

            wm.addPropagation(new ReactivePropagation(object, (ReactiveFromNodeLeftTuple)leftTuple, propagationContext, node, sink, type));
        }
    }

    private static InternalWorkingMemory getInternalWorkingMemory(PropagationContext propagationContext) {
        InternalFactHandle fh = propagationContext.getFactHandle();
        return fh.getEntryPoint().getInternalWorkingMemory();
    }

    static class ReactivePropagation extends PropagationEntry.AbstractPropagationEntry {

        private final Object object;
        private final ReactiveFromNodeLeftTuple leftTuple;
        private final PropagationContext propagationContext;
        private final ReactiveFromNode node;
        private final LeftTupleSinkNode sink;
        private final ModificationType type;

        ReactivePropagation( Object object, ReactiveFromNodeLeftTuple leftTuple, PropagationContext propagationContext, ReactiveFromNode node, LeftTupleSinkNode sink, ModificationType type ) {
            this.object = object;
            this.leftTuple = leftTuple;
            this.propagationContext = propagationContext;
            this.node = node;
            this.sink = sink;
            this.type = type;
        }

        @Override
        public void execute( InternalWorkingMemory wm ) {
            if ( leftTuple.resetModificationState( object ) == ModificationType.NONE ) {
                return;
            }

            ReactiveFromNode.ReactiveFromMemory mem = wm.getNodeMemory(node);
            InternalFactHandle factHandle = node.createFactHandle( leftTuple, propagationContext, wm, object );

            if ( type != ModificationType.REMOVE && isAllowed( factHandle, node.getAlphaConstraints(), wm, mem ) ) {
                ContextEntry[] context = mem.getBetaMemory().getContext();
                BetaConstraints betaConstraints = node.getBetaConstraints();
                betaConstraints.updateFromTuple( context,
                                                 wm,
                                                 leftTuple );

                propagate( sink,
                           leftTuple,
                           new RightTupleImpl( factHandle ),
                           betaConstraints,
                           propagationContext,
                           context,
                           RuleNetworkEvaluator.useLeftMemory( node, leftTuple ),
                           mem.getStagedLeftTuples(),
                           null );
            } else {
                LeftTuple childLeftTuple = ((LeftTuple)leftTuple).getFirstChild();
                while (childLeftTuple != null) {
                    LeftTuple next = childLeftTuple.getHandleNext();
                    if ( object == childLeftTuple.getFactHandle().getObject() ) {
                        deleteChildLeftTuple( propagationContext, mem.getStagedLeftTuples(), null, childLeftTuple );
                    }
                    childLeftTuple = next;
                }
            }

            mem.getBetaMemory().setNodeDirty(wm);
        }
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy