package org.drools.chance.rule.constraint;
import org.drools.base.mvel.MVELCompilationUnit;
import org.drools.chance.rule.constraint.core.evaluators.ImperfectMvelConditionEvaluator;
import org.drools.chance.degree.Degree;
import org.drools.chance.degree.simple.SimpleDegree;
import org.drools.common.InternalFactHandle;
import org.drools.common.InternalWorkingMemory;
import org.drools.core.util.index.IndexUtil;
import org.drools.reteoo.LeftTuple;
import org.drools.rule.ContextEntry;
import org.drools.rule.Declaration;
import org.drools.rule.MVELDialectRuntimeData;
import org.drools.rule.constraint.MvelConditionEvaluator;
import org.drools.rule.constraint.MvelConstraint;
import org.drools.spi.FieldValue;
import org.drools.spi.InternalReadAccessor;
import org.mvel2.ParserConfiguration;
import org.mvel2.ParserContext;
import org.mvel2.compiler.CompiledExpression;
import org.mvel2.compiler.ExecutableStatement;
public class ImperfectMvelConstraint extends MvelConstraint implements ImperfectAlphaConstraint, ImperfectBetaConstraint {
private int refNodeId = -1;
private boolean wrapsPerfectConstraint = false;
private String label;
private boolean cutting;
public boolean isCutting() {
return cutting;
}
public void setCutting(boolean cutting) {
this.cutting = cutting;
}
public ImperfectMvelConstraint() {
}
public ImperfectMvelConstraint(String packageName, String expression, MVELCompilationUnit compilationUnit, IndexUtil.ConstraintType constraintType, FieldValue fieldValue, InternalReadAccessor extractor) {
super(packageName, expression, compilationUnit, constraintType, fieldValue, extractor);
}
public ImperfectMvelConstraint(String packageName, String expression, Declaration[] declarations, MVELCompilationUnit compilationUnit, boolean isDynamic) {
super(packageName, expression, declarations, compilationUnit, isDynamic);
}
public ImperfectMvelConstraint(String packageName, String expression, Declaration[] declarations, MVELCompilationUnit compilationUnit, IndexUtil.ConstraintType constraintType, Declaration indexingDeclaration, InternalReadAccessor extractor, boolean isUnification) {
super(packageName, expression, declarations, compilationUnit, constraintType, indexingDeclaration, extractor, isUnification);
}
public Degree match( InternalFactHandle handle, InternalWorkingMemory workingMemory, ContextEntry context ) {
return match( handle.getObject(), workingMemory, null );
}
protected Degree match(Object object, InternalWorkingMemory workingMemory, LeftTuple leftTuple) {
prepare( object, workingMemory, leftTuple );
if ( ! wrapsPerfectConstraint ) {
return ((ImperfectMvelConditionEvaluator) conditionEvaluator).match(object, workingMemory, leftTuple);
} else {
return conditionEvaluator.evaluate(object, workingMemory, leftTuple) ? SimpleDegree.TRUE : SimpleDegree.FALSE;
}
}
private void prepare(Object object, InternalWorkingMemory workingMemory, LeftTuple leftTuple) {
if ( ! jitted ) {
if ( conditionEvaluator == null) {
createImperfectMvelConditionEvaluator(workingMemory);
if ( TEST_JITTING && !isDynamic ) { // Only for test purposes
boolean mvelValue = forceJitEvaluator( object, workingMemory, leftTuple );
}
}
if ( ! isDynamic && invocationCounter.getAndIncrement() == JIT_THRESOLD ) {
jitEvaluator(object, workingMemory, leftTuple);
}
}
}
protected void createImperfectMvelConditionEvaluator(InternalWorkingMemory workingMemory) {
if (compilationUnit != null) {
MVELDialectRuntimeData data = getMVELDialectRuntimeData(workingMemory);
ExecutableStatement statement = (ExecutableStatement) compilationUnit.getCompiledExpression( data );
ParserConfiguration configuration = statement instanceof CompiledExpression ?
((CompiledExpression)statement).getParserConfiguration() :
data.getParserConfiguration();
if ( statement.getKnownEgressType().isAssignableFrom( Degree.class ) ) {
conditionEvaluator = new ImperfectMvelConditionEvaluator( compilationUnit, configuration, statement, getRequiredDeclarations(), getAccessedClass());
} else {
conditionEvaluator = new MvelConditionEvaluator( compilationUnit, configuration, statement, getRequiredDeclarations(), getAccessedClass() );
wrapsPerfectConstraint = true;
}
} else {
conditionEvaluator = new ImperfectMvelConditionEvaluator( getParserConfiguration(workingMemory), expression, getRequiredDeclarations(), getAccessedClass() );
}
}
public Degree matchCachedLeft( ContextEntry context, InternalFactHandle handle ) {
Object o = handle.getObject();
LeftTuple tup = ((MvelContextEntry) context).getLeftTuple();
InternalWorkingMemory wm = ((MvelContextEntry) context).getWorkingMemory();
prepare( o, wm, tup );
if ( ! wrapsPerfectConstraint ) {
return ((ImperfectMvelConditionEvaluator) conditionEvaluator).match( o, wm, tup );
} else {
return conditionEvaluator.evaluate( o, wm, tup ) ? SimpleDegree.TRUE : SimpleDegree.FALSE;
}
}
public Degree matchCachedRight( LeftTuple tuple, ContextEntry context ) {
Object o = tuple.getHandle().getObject();
LeftTuple tup = ((MvelContextEntry) context).getLeftTuple();
InternalWorkingMemory wm = ((MvelContextEntry) context).getWorkingMemory();
prepare( o, wm, tup );
if ( ! wrapsPerfectConstraint ) {
return ((ImperfectMvelConditionEvaluator) conditionEvaluator).match( o, wm, tup );
} else {
return conditionEvaluator.evaluate( o, wm, tup ) ? SimpleDegree.TRUE : SimpleDegree.FALSE;
}
}
public int getNodeId() {
return refNodeId;
}
public void setNodeId( int id ) {
refNodeId = id;
}
public String getLabel() {
return label;
}
public void setLabel(String label) {
this.label = label;
}
}