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

org.drools.core.rule.VariableRestriction 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.rule;

import org.drools.core.base.ValueType;
import org.drools.core.base.evaluators.AfterEvaluatorDefinition.AfterEvaluator;
import org.drools.core.base.evaluators.BeforeEvaluatorDefinition.BeforeEvaluator;
import org.drools.core.base.evaluators.MeetsEvaluatorDefinition.MeetsEvaluator;
import org.drools.core.base.evaluators.MetByEvaluatorDefinition.MetByEvaluator;
import org.drools.core.common.EventFactHandle;
import org.drools.core.common.InternalFactHandle;
import org.drools.core.common.InternalWorkingMemory;
import org.drools.core.spi.Evaluator;
import org.drools.core.spi.InternalReadAccessor;
import org.drools.core.spi.Tuple;

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

public class VariableRestriction {

    private VariableRestriction() { }

    public static VariableContextEntry createContextEntry(InternalReadAccessor fieldExtractor,
                                                          Declaration declaration,
                                                          Evaluator evaluator) {
        ValueType coerced = evaluator.getCoercedValueType();
        
        if ( evaluator.isTemporal() ) {
            if ( evaluator instanceof BeforeEvaluator || evaluator instanceof MeetsEvaluator) {
                return new LeftStartRightEndContextEntry( fieldExtractor,
                                                         declaration, 
                                                         evaluator );
            }
            
            if ( evaluator instanceof AfterEvaluator || evaluator instanceof MetByEvaluator  ) {
                return new LeftEndRightStartContextEntry( fieldExtractor,
                                                         declaration, 
                                                         evaluator );
            }        

            // else
            return new TemporalVariableContextEntry( fieldExtractor,
                                                     declaration,
                                                     evaluator );          
        }
        


        if ( coerced.isBoolean() ) {
            return new BooleanVariableContextEntry( fieldExtractor,
                                                    declaration,
                                                    evaluator );
        } else if ( coerced.isFloatNumber() ) {
            return new DoubleVariableContextEntry( fieldExtractor,
                                                   declaration,
                                                   evaluator );
        } else if ( coerced.isIntegerNumber() || coerced.isEvent() ) {
            return new LongVariableContextEntry( fieldExtractor,
                                                 declaration,
                                                 evaluator );
        } else if ( coerced.isChar() ) {
            return new CharVariableContextEntry( fieldExtractor,
                                                 declaration,
                                                 evaluator );
        } else {
            return new ObjectVariableContextEntry( fieldExtractor,
                                                   declaration,
                                                   evaluator );
        }
    }

    public static abstract class VariableContextEntry
        implements
        ContextEntry {
        public InternalReadAccessor  extractor;
        public Evaluator             evaluator;
        public Object                object;
        public Declaration           declaration;
        public Tuple                 tuple;
        public ContextEntry          entry;
        public boolean               leftNull;
        public boolean               rightNull;
        public InternalWorkingMemory workingMemory;

        public VariableContextEntry() {
        }

        public VariableContextEntry(final InternalReadAccessor extractor,
                                    final Declaration declaration,
                                    final Evaluator evaluator) {
            this.extractor = extractor;
            this.declaration = declaration;
            this.evaluator = evaluator;
        }

        public void readExternal(ObjectInput in) throws IOException,
                                                ClassNotFoundException {
            workingMemory = (InternalWorkingMemory) in.readObject();
            extractor = (InternalReadAccessor) in.readObject();
            evaluator = (Evaluator) in.readObject();
            object = in.readObject();
            declaration = (Declaration) in.readObject();
            tuple = (Tuple) in.readObject();
            entry = (ContextEntry) in.readObject();
            leftNull = in.readBoolean();
            rightNull = in.readBoolean();
        }

        public void writeExternal(ObjectOutput out) throws IOException {
            out.writeObject( workingMemory );
            out.writeObject( extractor );
            out.writeObject( evaluator );
            out.writeObject( object );
            out.writeObject( declaration );
            out.writeObject( tuple );
            out.writeObject( entry );
            out.writeBoolean( leftNull );
            out.writeBoolean( rightNull );
        }

        public ContextEntry getNext() {
            return this.entry;
        }

        public void setNext(final ContextEntry entry) {
            this.entry = entry;
        }

        public InternalReadAccessor getFieldExtractor() {
            return this.extractor;
        }

        public Object getObject() {
            return this.object;
        }

        public Tuple getTuple() {
            return this.tuple;
        }

        public Declaration getVariableDeclaration() {
            return this.declaration;
        }

        public boolean isLeftNull() {
            return this.leftNull;
        }

        public boolean isRightNull() {
            return this.rightNull;
        }

        public void resetTuple() {
            this.tuple = null;
        }

        public void resetFactHandle() {
            this.object = null;
        }
    }

    public static class ObjectVariableContextEntry extends VariableContextEntry {

        private static final long serialVersionUID = 510l;
        public Object             left;
        public Object             right;

        public ObjectVariableContextEntry() {
        }

        public ObjectVariableContextEntry(final InternalReadAccessor extractor,
                                          final Declaration declaration,
                                          final Evaluator evaluator) {
            super( extractor,
                   declaration,
                   evaluator );
        }

        public void readExternal(ObjectInput in) throws IOException,
                                                ClassNotFoundException {
            super.readExternal( in );
            left = in.readObject();
            right = in.readObject();
        }

        public void writeExternal(ObjectOutput out) throws IOException {
            super.writeExternal( out );
            out.writeObject( left );
            out.writeObject( right );
        }

        public void updateFromTuple(final InternalWorkingMemory workingMemory,
                                    final Tuple tuple) {
            this.tuple = tuple;
            this.workingMemory = workingMemory;
            this.leftNull = this.declaration.getExtractor().isNullValue( workingMemory,
                                                                         tuple.getObject( this.declaration ) );
            this.left = this.declaration.getExtractor().getValue( workingMemory,
                                                                  tuple.getObject( this.declaration ) );
        }

        public void updateFromFactHandle(final InternalWorkingMemory workingMemory,
                                         final InternalFactHandle handle) {
            this.object = handle.getObject();
            this.workingMemory = workingMemory;
            this.rightNull = this.extractor.isNullValue( workingMemory,
                                                         handle.getObject() );
            this.right = this.extractor.getValue( workingMemory,
                                                  handle.getObject() );
        }

        public void resetTuple() {
            this.left = null;
            this.tuple = null;
        }

        public void resetFactHandle() {
            this.right = null;
            this.object = null;
        }
    }

    public static class LongVariableContextEntry extends VariableContextEntry {

        private static final long serialVersionUID = 510l;

        public long               left;
        public long               right;

        public LongVariableContextEntry() {
        }

        public LongVariableContextEntry(final InternalReadAccessor extractor,
                                        final Declaration declaration,
                                        final Evaluator evaluator) {
            super( extractor,
                   declaration,
                   evaluator );
        }

        public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {
            super.readExternal( in );
            left = in.readLong();
            right = in.readLong();
        }

        public void writeExternal(ObjectOutput out) throws IOException {
            super.writeExternal( out );
            out.writeLong( left );
            out.writeLong( right );
        }

        public void updateFromTuple(final InternalWorkingMemory workingMemory,
                                    final Tuple tuple) {
            this.tuple = tuple;
            this.workingMemory = workingMemory;
            this.leftNull = this.declaration.getExtractor().isNullValue( workingMemory,
                                                                         tuple.getObject( this.declaration ) );

            if ( !leftNull ) {
                this.left = this.declaration.getExtractor().getLongValue( workingMemory,
                                                                          tuple.getObject( this.declaration ) );
            } else {
                this.left = 0;
            }
        }

        public void updateFromFactHandle(final InternalWorkingMemory workingMemory,
                                         final InternalFactHandle handle) {
            this.object = handle.getObject();
            this.workingMemory = workingMemory;
            this.rightNull = this.extractor.isNullValue( workingMemory,
                                                         handle.getObject());

            if ( !rightNull ) { // avoid a NullPointerException
                this.right = this.extractor.getLongValue( workingMemory,
                                                          handle.getObject() );
            } else {
                this.right = 0;
            }
        }
    }

    public static class CharVariableContextEntry extends VariableContextEntry {

        private static final long serialVersionUID = 510l;

        public char               left;
        public char               right;

        public CharVariableContextEntry() {
        }

        public CharVariableContextEntry(final InternalReadAccessor extractor,
                                        final Declaration declaration,
                                        final Evaluator evaluator) {
            super( extractor,
                   declaration,
                   evaluator );
        }

        public void readExternal(ObjectInput in) throws IOException,
                                                ClassNotFoundException {
            super.readExternal( in );
            left = in.readChar();
            right = in.readChar();
        }

        public void writeExternal(ObjectOutput out) throws IOException {
            super.writeExternal( out );
            out.writeChar( left );
            out.writeChar( right );
        }

        public void updateFromTuple(final InternalWorkingMemory workingMemory,
                                    final Tuple tuple) {
            this.tuple = tuple;
            this.workingMemory = workingMemory;
            this.leftNull = this.declaration.getExtractor().isNullValue( workingMemory,
                                                                         tuple.getObject( this.declaration ));

            if ( !leftNull ) {
                this.left = this.declaration.getExtractor().getCharValue( workingMemory,
                                                                          tuple.getObject( this.declaration ) );
            } else {
                this.left = 0;
            }
        }

        public void updateFromFactHandle(final InternalWorkingMemory workingMemory,
                                         final InternalFactHandle handle) {
            this.object = handle.getObject();
            this.workingMemory = workingMemory;
            this.rightNull = this.extractor.isNullValue( workingMemory,
                                                         handle.getObject());

            if ( !rightNull ) { // avoid a NullPointerException
                this.right = this.extractor.getCharValue( workingMemory,
                                                          handle.getObject() );
            } else {
                this.right = 0;
            }
        }
    }

    public static class DoubleVariableContextEntry extends VariableContextEntry {

        private static final long serialVersionUID = 510l;

        public double             left;
        public double             right;

        public DoubleVariableContextEntry() {
        }

        public DoubleVariableContextEntry(final InternalReadAccessor extractor,
                                          final Declaration declaration,
                                          final Evaluator evaluator) {
            super( extractor,
                   declaration,
                   evaluator );
        }

        public void readExternal(ObjectInput in) throws IOException,
                                                ClassNotFoundException {
            super.readExternal( in );
            left = in.readDouble();
            right = in.readDouble();
        }

        public void writeExternal(ObjectOutput out) throws IOException {
            super.writeExternal( out );
            out.writeDouble( left );
            out.writeDouble( right );
        }

        public void updateFromTuple(final InternalWorkingMemory workingMemory,
                                    final Tuple tuple) {
            this.tuple = tuple;
            this.workingMemory = workingMemory;
            this.leftNull = this.declaration.getExtractor().isNullValue( workingMemory,
                                                                         tuple.getObject( this.declaration ) );

            if ( !leftNull ) {
                this.left = this.declaration.getExtractor().getDoubleValue( workingMemory,
                                                                            tuple.getObject( this.declaration ) );
            } else {
                this.left = 0;
            }
        }

        public void updateFromFactHandle(final InternalWorkingMemory workingMemory,
                                         final InternalFactHandle handle) {
            this.object = handle.getObject();
            this.workingMemory = workingMemory;
            this.rightNull = this.extractor.isNullValue( workingMemory,
                                                         handle.getObject() );

            if ( !rightNull ) { // avoid a NullPointerException
                this.right = this.extractor.getDoubleValue( workingMemory,
                                                            handle.getObject() );
            } else {
                this.right = 0;
            }
        }
    }

    public static class BooleanVariableContextEntry extends VariableContextEntry {

        private static final long serialVersionUID = 510l;
        public boolean            left;
        public boolean            right;

        public BooleanVariableContextEntry() {
        }

        public BooleanVariableContextEntry(final InternalReadAccessor extractor,
                                           final Declaration declaration,
                                           final Evaluator evaluator) {
            super( extractor,
                   declaration,
                   evaluator );
        }

        public void readExternal(ObjectInput in) throws IOException,
                                                ClassNotFoundException {
            super.readExternal( in );
            left = in.readBoolean();
            right = in.readBoolean();
        }

        public void writeExternal(ObjectOutput out) throws IOException {
            super.writeExternal( out );
            out.writeBoolean( left );
            out.writeBoolean( right );
        }

        public void updateFromTuple(final InternalWorkingMemory workingMemory,
                                    final Tuple tuple) {
            this.tuple = tuple;
            this.workingMemory = workingMemory;
            this.leftNull = this.declaration.getExtractor().isNullValue( workingMemory,
                                                                         tuple.getObject( this.declaration ) );

            this.left = !leftNull && this.declaration.getExtractor().getBooleanValue( workingMemory, tuple.getObject( this.declaration ) );
        }

        public void updateFromFactHandle(final InternalWorkingMemory workingMemory,
                                         final InternalFactHandle handle) {
            this.object = handle.getObject();
            this.workingMemory = workingMemory;
            this.rightNull = this.extractor.isNullValue( workingMemory,
                                                         handle.getObject() );

            // avoid a NullPointerException
            this.right = !rightNull && this.extractor.getBooleanValue( workingMemory, handle.getObject() );
        }
    }
    
    public static abstract class TimestampedContextEntry extends VariableContextEntry {
        public long               timestamp;

        public TimestampedContextEntry() {
        }

        public TimestampedContextEntry(final InternalReadAccessor extractor,
                                             final Declaration declaration,
                                             final Evaluator evaluator) {
            super( extractor,
                   declaration,
                   evaluator );
        }

        @Override
        public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {
            super.readExternal( in );
            timestamp = in.readLong();
        }

        @Override
        public void writeExternal(ObjectOutput out) throws IOException {
            super.writeExternal( out );
            out.writeLong( timestamp );
        }

        protected abstract long getTimestampFromTuple( Tuple tuple );
        protected abstract long getTimestampFromFactHandle( InternalFactHandle handle );

        @Override
        public void updateFromTuple(final InternalWorkingMemory workingMemory,
                                    final Tuple tuple) {
            this.tuple = tuple;
            this.workingMemory = workingMemory;

            if ( this.declaration.getExtractor().isSelfReference() ) {
                this.timestamp = getTimestampFromTuple( tuple );
            } else {
                this.leftNull = this.declaration.getExtractor().isNullValue( workingMemory,
                                                                             tuple.getObject( this.declaration ) );
                if ( !leftNull ) { // avoid a NullPointerException
                    this.timestamp = this.declaration.getExtractor().getLongValue( workingMemory,
                                                                                   tuple.getObject( this.declaration ) );
                } else {
                    this.timestamp = 0;
                }
            }
        }

        @Override
        public void updateFromFactHandle(final InternalWorkingMemory workingMemory,
                                         final InternalFactHandle handle) {
            this.object = handle.getObject();
            this.workingMemory = workingMemory;

            if ( this.extractor.isSelfReference() ) {
                this.timestamp = getTimestampFromFactHandle( handle );
            } else {
                this.rightNull = this.extractor.isNullValue( workingMemory,
                                                             handle.getObject());
                if ( !rightNull ) { // avoid a NullPointerException
                    this.timestamp = this.extractor.getLongValue( workingMemory,
                                                                  handle.getObject() );
                } else {
                    this.timestamp = 0;
                }
            }
        }
    }

    public static class LeftStartRightEndContextEntry extends TimestampedContextEntry {

        private static final long serialVersionUID = 510l;

        public LeftStartRightEndContextEntry() {
        }

        public LeftStartRightEndContextEntry(final InternalReadAccessor extractor,
                                             final Declaration declaration,
                                             final Evaluator evaluator) {
            super( extractor,
                   declaration,
                   evaluator );
        }

        @Override
        protected long getTimestampFromTuple( Tuple tuple ) {
            return ((EventFactHandle) tuple.get( this.declaration )).getStartTimestamp();
        }

        @Override
        protected long getTimestampFromFactHandle( InternalFactHandle handle ) {
            return ((EventFactHandle)handle).getEndTimestamp();
        }
    }
    
    public static class LeftEndRightStartContextEntry extends TimestampedContextEntry {

        private static final long serialVersionUID = 510l;

        public LeftEndRightStartContextEntry() {
        }

        public LeftEndRightStartContextEntry(final InternalReadAccessor extractor,
                                            final Declaration declaration,
                                            final Evaluator evaluator) {
            super( extractor,
                   declaration,
                   evaluator );
        }

        @Override
        protected long getTimestampFromTuple( Tuple tuple ) {
            return ((EventFactHandle) tuple.get( this.declaration )).getEndTimestamp();
        }

        @Override
        protected long getTimestampFromFactHandle( InternalFactHandle handle ) {
            return ((EventFactHandle)handle).getStartTimestamp();
        }
    }
    
    public static class TemporalVariableContextEntry extends VariableContextEntry {

        private static final long serialVersionUID = 510l;

        public long               startTS;
        public long               endTS;

        public TemporalVariableContextEntry() {
        }

        public TemporalVariableContextEntry(final InternalReadAccessor extractor,
                                            final Declaration declaration,
                                            final Evaluator evaluator) {
            super( extractor,
                   declaration,
                   evaluator );
        }

        public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {
            super.readExternal( in );
            startTS = in.readLong();
            endTS = in.readLong();
        }

        public void writeExternal(ObjectOutput out) throws IOException {
            super.writeExternal( out );
            out.writeLong( startTS );
            out.writeLong( startTS );
        }

        public void updateFromTuple(final InternalWorkingMemory workingMemory,
                                    final Tuple tuple) {
            this.tuple = tuple;
            this.workingMemory = workingMemory;
            
            if ( this.declaration.getExtractor().isSelfReference() ) {
                EventFactHandle efh = ((EventFactHandle)tuple.get( this.declaration ));
                this.startTS = efh.getStartTimestamp();
                this.endTS = efh.getEndTimestamp();
            } else {
              this.leftNull = this.declaration.getExtractor().isNullValue( workingMemory,
                                                                           tuple.getObject( this.declaration ) );
              if ( !leftNull ) { // avoid a NullPointerException
                  this.startTS = this.declaration.getExtractor().getLongValue( workingMemory,
                                                                             tuple.getObject( this.declaration ) );
                } else {
                    this.startTS = 0;
                }    
              endTS = startTS;
            }
        }

        public void updateFromFactHandle(final InternalWorkingMemory workingMemory,
                                         final InternalFactHandle handle) {
            this.object = handle.getObject(); 
            this.workingMemory = workingMemory;
            
            if ( this.extractor.isSelfReference() ) {
                this.startTS = ((EventFactHandle)handle).getStartTimestamp();
                this.endTS = ((EventFactHandle)handle).getEndTimestamp();
            } else {
              this.rightNull = this.extractor.isNullValue( workingMemory,
                                                           handle.getObject());
              if ( !rightNull ) { // avoid a NullPointerException
                  this.startTS = this.extractor.getLongValue( workingMemory,
                                                              handle.getObject() );
              } else {
                    this.startTS = 0;
              }  
              endTS = startTS;
            }
        }
    }       
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy