⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 tokenevaluator.java

📁 jboss规则引擎
💻 JAVA
📖 第 1 页 / 共 2 页
字号:
package org.drools.leaps;

/*
 * Copyright 2005 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.
 */

import org.drools.common.InternalFactHandle;
import org.drools.leaps.util.Table;
import org.drools.leaps.util.TableIterator;
import org.drools.rule.EvalCondition;
import org.drools.rule.InvalidRuleException;

/**
 * helper class that does condition evaluation on token when working memory does
 * seek. all methods are static
 * 
 * @author Alexander Bagerman
 * 
 */
final class TokenEvaluator {
    /**
     * this method does nested loops iterations on all relavant fact tables and
     * evaluates rules conditions
     * 
     * @param token
     * @throws NoMatchesFoundException
     * @throws Exception
     * @throws InvalidRuleException
     */
    final static protected void evaluate( final Token token )
            throws NoMatchesFoundException, InvalidRuleException {
        final LeapsWorkingMemory workingMemory = (LeapsWorkingMemory) token.getWorkingMemory( );
        final LeapsRule leapsRule = token.getCurrentRuleHandle( ).getLeapsRule( );
        // sometimes there is no normal conditions, only not and exists
        final int numberOfColumns = leapsRule.getNumberOfColumns( );
        // if (numberOfColumns > 0) {
        final int dominantFactPosition = token.getCurrentRuleHandle( )
                                              .getDominantPosition( );
        final InternalFactHandle dominantFactHandle = token.getDominantFactHandle( );
        if (leapsRule.getColumnConstraintsAtPosition( dominantFactPosition )
                     .isAllowedAlpha( dominantFactHandle, token, workingMemory )) {
            final Class dominantClass = leapsRule.getColumnClassObjectTypeAtPosition( dominantFactPosition );
            final TableIterator[] iterators = new TableIterator[numberOfColumns];
            // getting iterators first
            for (int i = 0; i < numberOfColumns; i++) {
                if (i == dominantFactPosition) {
                    iterators[i] = Table.singleItemIterator( dominantFactHandle );
                }
                else {
                    final Class columnClass = leapsRule.getColumnClassObjectTypeAtPosition( i );
                    final ColumnConstraints constraints = leapsRule.getColumnConstraintsAtPosition( i );
                    final FactTable factTable = workingMemory.getFactTable( columnClass );
                    final LeapsFactHandle startFactHandle = ( dominantClass == columnClass ) ? new LeapsFactHandle( dominantFactHandle.getRecency( ) - 1,
                                                                                                                    new Object( ) )
                            : (LeapsFactHandle) dominantFactHandle;
                    //
                    if (i > 0 && constraints.isAlphaPresent( )) {
                        iterators[i] = factTable.constrainedIteratorFromPositionToTableStart( workingMemory,
                                                                                              constraints,
                                                                                              startFactHandle,
                                                                                              ( token.isResume( ) ? (LeapsFactHandle) token.get( i )
                                                                                                      : startFactHandle ) );
                    }
                    else {
                        iterators[i] = factTable.iteratorFromPositionToTableStart( startFactHandle,
                                                                                   ( token.isResume( ) ? (LeapsFactHandle) token.get( i )
                                                                                           : startFactHandle ) );
                    }
                }
            }

            // check if any iterators are empty to abort
            // check if we resume and any starting facts disappeared than we
            // do not do skip on resume
            boolean doReset = false;
            boolean skip = token.isResume( );
            TableIterator currentIterator;
            for (int i = 0; i < numberOfColumns; i++) {
                currentIterator = iterators[i];
                // check if one of them is empty and immediate return
                if (currentIterator.isEmpty( )) {
                    throw new NoMatchesFoundException( );
                }
                else {
                    if (!doReset) {
                        if (skip && currentIterator.hasNext( )
                                && !currentIterator.peekNext( ).equals( token.get( i ) )) {
                            // we tried to resume but our fact handle at marker
                            // disappear no need to resume just reset all interators
                            // positioned at the marker where we stoped last time
                            skip = false;
                            doReset = true;
                        }
                    }
                    else {
                        currentIterator.reset( );
                    }
                }
            }

            // iterating is done in nested loop
            // column position in the nested loop
            int jj = 0;
            boolean done = false;
            final int stopIteratingCount = numberOfColumns - 1;
            while (!done) {
                currentIterator = iterators[jj];
                if (!currentIterator.hasNext( )) {
                    if (jj == 0) {
                        done = true;
                    }
                    else {
                        // nothing for this column, go back and check next
                        // on the one level up in nested loop
                        currentIterator.reset( );
                        jj = jj - 1;
                        if (skip) {
                            skip = false;
                        }
                    }
                }
                else {
                    final LeapsFactHandle currentFactHandle = (LeapsFactHandle) currentIterator.next( );
                    // check if match found we need to check only beta for
                    // dominant fact
                    // alpha was already checked
                    boolean localMatch = false;
                    if (!skip) {
                        if (jj != 0 || jj == dominantFactPosition) {
                            localMatch = leapsRule.getColumnConstraintsAtPosition( jj )
                                                  .isAllowedBeta( currentFactHandle,
                                                                  token,
                                                                  workingMemory );
                        }
                        else {
                            localMatch = leapsRule.getColumnConstraintsAtPosition( jj )
                                                  .isAllowed( currentFactHandle,
                                                              token,
                                                              workingMemory );
                        }
                    }
                    if (localMatch || skip) {
                        token.set( jj, currentFactHandle );
                        // start iteratating next iterator or for the last
                        // one check negative conditions and fire consequence
                        if (jj == stopIteratingCount) {
                            if (!skip) {
                                if (processAfterAllPositiveConstraintOk( token.getTuple( ),
                                                                         leapsRule,
                                                                         workingMemory )) {
                                    return;
                                }
                            }
                            else {
                                skip = false;
                            }
                        }
                        else {
                            jj = jj + 1;
                        }
                    }
                }
            }
        }
        // nothing was found. inform caller about it
        throw new NoMatchesFoundException( );
    }

    /**
     * Makes final check on eval, exists and not conditions after all column
     * values isAllowed by column constraints
     * 
     * @param token
     * @param leapsRule
     * @param workingMemory

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -