📄 tokenevaluator.java
字号:
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 + -