/* * 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.base; import org.drools.core.base.extractors.ConstantValueReader; import org.drools.core.base.extractors.SelfReferenceClassFieldReader; import org.drools.core.base.field.ObjectFieldImpl; import org.drools.core.common.InternalFactHandle; import org.drools.core.common.InternalWorkingMemory; import org.drools.core.rule.Declaration; import org.drools.core.rule.VariableRestriction.VariableContextEntry; import org.drools.core.spi.Evaluator; import org.drools.core.spi.FieldValue; import org.drools.core.spi.InternalReadAccessor; import org.drools.core.time.Interval; import static org.drools.core.base.mvel.MVELCompilationUnit.getFactHandle; /** * An EvaluatorWrapper is used when executing MVEL expressions * that have operator calls rewritten as: * * operator.evaluate( leftArg, rightArg ) * */ public class EvaluatorWrapper implements Evaluator { private static final long serialVersionUID = 520L; private static final SelfReferenceClassFieldReader extractor = new SelfReferenceClassFieldReader( Object.class ); private Evaluator evaluator; private transient InternalWorkingMemory workingMemory; private Declaration leftBinding; private Declaration rightBinding; private transient InternalFactHandle leftHandle; private transient InternalFactHandle rightHandle; private InternalReadAccessor leftExtractor; private InternalReadAccessor rightExtractor; private boolean selfLeft; private boolean selfRight; private String bindingName; public EvaluatorWrapper(Evaluator evaluator, Declaration leftBinding, Declaration rightBinding) { this.evaluator = evaluator; this.leftBinding = leftBinding; this.rightBinding = rightBinding; init(); } private void init() { leftExtractor = leftBinding == null || leftBinding.getExtractor() == null ? extractor : leftBinding.getExtractor(); rightExtractor = rightBinding == null || rightBinding.getExtractor() == null ? extractor : rightBinding.getExtractor(); selfLeft = leftBinding == null || leftBinding.getIdentifier().equals("this"); selfRight = rightBinding == null || rightBinding.getIdentifier().equals("this"); } /** * This method is called when operators are rewritten as function calls. For instance, * * x after y * * Is rewritten as * * after.evaluate( x, y ) * * @return */ public boolean evaluate(Object left, Object right) { if (rightHandle == null || rightBinding == null) { return evaluator.evaluate( workingMemory, leftBinding != null ? leftExtractor : new ConstantValueReader(left), leftHandle, new ObjectFieldImpl(right) ); } return evaluator.evaluate( workingMemory, leftBinding != null ? leftExtractor : new ConstantValueReader(left), leftHandle, rightExtractor, rightHandle ); } /** * @return * @see org.drools.core.spi.Evaluator#getValueType() */ public ValueType getValueType() { return evaluator.getValueType(); } /** * @return * @see org.drools.core.spi.Evaluator#getOperator() */ public org.kie.api.runtime.rule.Operator getOperator() { return evaluator.getOperator(); } /** * @return * @see org.drools.core.spi.Evaluator#getCoercedValueType() */ public ValueType getCoercedValueType() { return evaluator.getCoercedValueType(); } /** * @param workingMemory * @param extractor * @param factHandle * @param value * @return * @see org.drools.core.spi.Evaluator#evaluate(org.drools.core.common.InternalWorkingMemory, org.drools.core.spi.InternalReadAccessor, InternalFactHandle, org.drools.core.spi.FieldValue) */ public boolean evaluate(InternalWorkingMemory workingMemory, InternalReadAccessor extractor, InternalFactHandle factHandle, FieldValue value) { return evaluator.evaluate( workingMemory, extractor, factHandle, value ); } /** * @param workingMemory * @param leftExtractor * @param left * @param rightExtractor * @param right * @return * @see org.drools.core.spi.Evaluator#evaluate(org.drools.core.common.InternalWorkingMemory, org.drools.core.spi.InternalReadAccessor, InternalFactHandle, org.drools.core.spi.InternalReadAccessor, InternalFactHandle) */ public boolean evaluate(InternalWorkingMemory workingMemory, InternalReadAccessor leftExtractor, InternalFactHandle left, InternalReadAccessor rightExtractor, InternalFactHandle right) { return evaluator.evaluate( workingMemory, leftExtractor, left, rightExtractor, right ); } /** * @param workingMemory * @param context * @param right * @return * @see org.drools.core.spi.Evaluator#evaluateCachedLeft(org.drools.core.common.InternalWorkingMemory, org.drools.core.rule.VariableRestriction.VariableContextEntry, InternalFactHandle) */ public boolean evaluateCachedLeft(InternalWorkingMemory workingMemory, VariableContextEntry context, InternalFactHandle right) { return evaluator.evaluateCachedLeft( workingMemory, context, right ); } /** * @param workingMemory * @param context * @param left * @return * @see org.drools.core.spi.Evaluator#evaluateCachedRight(org.drools.core.common.InternalWorkingMemory, org.drools.core.rule.VariableRestriction.VariableContextEntry, InternalFactHandle) */ public boolean evaluateCachedRight(InternalWorkingMemory workingMemory, VariableContextEntry context, InternalFactHandle left) { return evaluator.evaluateCachedRight( workingMemory, context, left ); } /** * @return * @see org.drools.core.spi.Evaluator#isTemporal() */ public boolean isTemporal() { return evaluator.isTemporal(); } /** * @return * @see org.drools.core.spi.Evaluator#getInterval() */ public Interval getInterval() { return evaluator.getInterval(); } public void loadHandles(InternalWorkingMemory workingMemory, InternalFactHandle[] handles, InternalFactHandle rightHandle) { this.workingMemory = workingMemory; leftHandle = selfLeft ? null : getFactHandle(leftBinding, handles); if (leftHandle == null) { leftHandle = rightHandle; } this.rightHandle = selfRight ? rightHandle : getFactHandle(rightBinding, handles); } @Override public String toString() { return this.evaluator.toString(); } public static SelfReferenceClassFieldReader getExtractor() { return extractor; } public Evaluator getEvaluator() { return evaluator; } public InternalWorkingMemory getWorkingMemory() { return workingMemory; } public Declaration getLeftBinding() { return leftBinding; } public Declaration getRightBinding() { return rightBinding; } public InternalFactHandle getLeftHandle() { return leftHandle; } public InternalFactHandle getRightHandle() { return rightHandle; } public InternalReadAccessor getLeftExtractor() { return leftExtractor; } public InternalReadAccessor getRightExtractor() { return rightExtractor; } public boolean isSelfLeft() { return selfLeft; } public boolean isSelfRight() { return selfRight; } public String getBindingName() { return bindingName; } public void setBindingName( String bindingName ) { this.bindingName = bindingName; } }