Search in sources :

Example 6 with EvaluatorWrapper

use of org.drools.compiler.rule.builder.EvaluatorWrapper in project drools by kiegroup.

the class MVELConstraintBuilder method buildVariableConstraint.

public Constraint buildVariableConstraint(RuleBuildContext context, Pattern pattern, String expression, Declaration[] declarations, String leftValue, OperatorDescr operatorDescr, String rightValue, InternalReadAccessor extractor, Declaration requiredDeclaration, RelationalExprDescr relDescr, Map<String, OperatorDescr> aliases) {
    if (!isMvelOperator(operatorDescr.getOperator())) {
        if (requiredDeclaration == null) {
            return null;
        }
        EvaluatorDefinition.Target right = getRightTarget(extractor);
        EvaluatorDefinition.Target left = (requiredDeclaration.isPatternDeclaration() && !(Date.class.isAssignableFrom(requiredDeclaration.getDeclarationClass()) || Number.class.isAssignableFrom(requiredDeclaration.getDeclarationClass()))) ? EvaluatorDefinition.Target.HANDLE : EvaluatorDefinition.Target.FACT;
        final Evaluator evaluator = getEvaluator(context, relDescr, extractor.getValueType(), operatorDescr.getOperator(), relDescr.isNegated(), relDescr.getParametersText(), left, right);
        return new EvaluatorConstraint(new Declaration[] { requiredDeclaration }, evaluator, extractor);
    }
    boolean isUnification = requiredDeclaration != null && requiredDeclaration.getPattern().getObjectType().equals(new ClassObjectType(DroolsQuery.class)) && Operator.BuiltInOperator.EQUAL.getSymbol().equals(operatorDescr.getOperator());
    if (isUnification && leftValue.equals(rightValue)) {
        expression = resolveUnificationAmbiguity(expression, declarations, leftValue, rightValue);
    }
    expression = normalizeMVELVariableExpression(expression, leftValue, rightValue, relDescr);
    IndexUtil.ConstraintType constraintType = IndexUtil.ConstraintType.decode(operatorDescr.getOperator(), operatorDescr.isNegated());
    MVELCompilationUnit compilationUnit = isUnification ? null : buildCompilationUnit(context, pattern, expression, aliases);
    EvaluatorWrapper[] operators = getOperators(buildOperators(context, pattern, relDescr, aliases));
    return new MVELConstraint(Collections.singletonList(context.getPkg().getName()), expression, declarations, operators, compilationUnit, constraintType, requiredDeclaration, extractor, isUnification);
}
Also used : EvaluatorWrapper(org.drools.compiler.rule.builder.EvaluatorWrapper) ClassObjectType(org.drools.core.base.ClassObjectType) IndexUtil(org.drools.core.util.index.IndexUtil) MVELCompilationUnit(org.drools.mvel.expr.MVELCompilationUnit) MvelEvaluator.createMvelEvaluator(org.drools.mvel.expr.MvelEvaluator.createMvelEvaluator) MvelEvaluator(org.drools.mvel.expr.MvelEvaluator) ReteEvaluator(org.drools.core.common.ReteEvaluator) Evaluator(org.drools.core.spi.Evaluator) AfterEvaluatorDefinition(org.drools.mvel.evaluators.AfterEvaluatorDefinition) DuringEvaluatorDefinition(org.drools.mvel.evaluators.DuringEvaluatorDefinition) IncludesEvaluatorDefinition(org.drools.mvel.evaluators.IncludesEvaluatorDefinition) StartedByEvaluatorDefinition(org.drools.mvel.evaluators.StartedByEvaluatorDefinition) BeforeEvaluatorDefinition(org.drools.mvel.evaluators.BeforeEvaluatorDefinition) MetByEvaluatorDefinition(org.drools.mvel.evaluators.MetByEvaluatorDefinition) MeetsEvaluatorDefinition(org.drools.mvel.evaluators.MeetsEvaluatorDefinition) FinishesEvaluatorDefinition(org.drools.mvel.evaluators.FinishesEvaluatorDefinition) OverlappedByEvaluatorDefinition(org.drools.mvel.evaluators.OverlappedByEvaluatorDefinition) StartsEvaluatorDefinition(org.drools.mvel.evaluators.StartsEvaluatorDefinition) CoincidesEvaluatorDefinition(org.drools.mvel.evaluators.CoincidesEvaluatorDefinition) OverlapsEvaluatorDefinition(org.drools.mvel.evaluators.OverlapsEvaluatorDefinition) StrEvaluatorDefinition(org.drools.mvel.evaluators.StrEvaluatorDefinition) EvaluatorDefinition(org.drools.compiler.rule.builder.EvaluatorDefinition) FinishedByEvaluatorDefinition(org.drools.mvel.evaluators.FinishedByEvaluatorDefinition) DroolsQuery(org.drools.core.base.DroolsQuery)

Example 7 with EvaluatorWrapper

use of org.drools.compiler.rule.builder.EvaluatorWrapper in project drools by kiegroup.

the class MVELConstraintBuilder method analyzeExpression.

private static MVELAnalysisResult analyzeExpression(String expr, ParserConfiguration conf, BoundIdentifiers availableIdentifiers) {
    if (expr.trim().length() <= 0) {
        MVELAnalysisResult result = analyze((Set<String>) Collections.EMPTY_SET, availableIdentifiers);
        result.setMvelVariables(new HashMap<String, Class<?>>());
        result.setTypesafe(true);
        return result;
    }
    MVEL.COMPILER_OPT_ALLOW_NAKED_METH_CALL = true;
    MVEL.COMPILER_OPT_ALLOW_OVERRIDE_ALL_PROPHANDLING = true;
    MVEL.COMPILER_OPT_ALLOW_RESOLVE_INNERCLASSES_WITH_DOTNOTATION = true;
    MVEL.COMPILER_OPT_SUPPORT_JAVA_STYLE_CLASS_LITERALS = true;
    // first compilation is for verification only
    final ParserContext parserContext1 = new ParserContext(conf);
    if (availableIdentifiers.getThisClass() != null) {
        parserContext1.addInput("this", availableIdentifiers.getThisClass());
    }
    if (availableIdentifiers.getOperators() != null) {
        for (Map.Entry<String, EvaluatorWrapper> opEntry : availableIdentifiers.getOperators().entrySet()) {
            parserContext1.addInput(opEntry.getKey(), opEntry.getValue().getClass());
        }
    }
    parserContext1.setStrictTypeEnforcement(false);
    parserContext1.setStrongTyping(false);
    Class<?> returnType;
    try {
        returnType = MVEL.analyze(expr, parserContext1);
    } catch (Exception e) {
        return null;
    }
    Set<String> requiredInputs = new HashSet<>(parserContext1.getInputs().keySet());
    Map<String, Class> variables = parserContext1.getVariables();
    // MVEL includes direct fields of context object in non-strict mode. so we need to strip those
    if (availableIdentifiers.getThisClass() != null) {
        requiredInputs.removeIf(s -> PropertyTools.getFieldOrAccessor(availableIdentifiers.getThisClass(), s) != null);
    }
    // now, set the required input types and compile again
    final ParserContext parserContext2 = new ParserContext(conf);
    parserContext2.setStrictTypeEnforcement(true);
    parserContext2.setStrongTyping(true);
    for (String input : requiredInputs) {
        if ("this".equals(input)) {
            continue;
        }
        if (WM_ARGUMENT.equals(input)) {
            parserContext2.addInput(input, InternalWorkingMemory.class);
            continue;
        }
        Class<?> cls = availableIdentifiers.resolveType(input);
        if (cls == null) {
            if (input.equals("rule")) {
                cls = Rule.class;
            }
        }
        if (cls != null) {
            parserContext2.addInput(input, cls);
        }
    }
    if (availableIdentifiers.getThisClass() != null) {
        parserContext2.addInput("this", availableIdentifiers.getThisClass());
    }
    try {
        returnType = MVEL.analyze(expr, parserContext2);
    } catch (Exception e) {
        return null;
    }
    requiredInputs = new HashSet<>();
    requiredInputs.addAll(parserContext2.getInputs().keySet());
    requiredInputs.addAll(variables.keySet());
    variables = parserContext2.getVariables();
    MVELAnalysisResult result = analyze(requiredInputs, availableIdentifiers);
    result.setReturnType(returnType);
    result.setMvelVariables((Map<String, Class<?>>) (Map) variables);
    result.setTypesafe(true);
    return result;
}
Also used : EvaluatorWrapper(org.drools.compiler.rule.builder.EvaluatorWrapper) IOException(java.io.IOException) MVELAnalysisResult(org.drools.mvel.builder.MVELAnalysisResult) ParserContext(org.mvel2.ParserContext) Map(java.util.Map) HashMap(java.util.HashMap) HashSet(java.util.HashSet)

Example 8 with EvaluatorWrapper

use of org.drools.compiler.rule.builder.EvaluatorWrapper in project drools by kiegroup.

the class JavaExprAnalyzer method analyze.

/**
 * Analyze an expression.
 *
 * @param availableIdentifiers
 *            Total set of declarations available.
 * @param result
 *            The AST for the expression.
 *
 * @return The <code>Set</code> of declarations used by the expression.
 */
private JavaAnalysisResult analyze(JavaAnalysisResult result, BoundIdentifiers availableIdentifiers) {
    final Set<String> identifiers = result.getIdentifiers();
    final Set<String> notBound = new HashSet<>(identifiers);
    Map<String, Class<?>> usedDecls = new HashMap<>();
    Map<String, Class<?>> usedGlobals = new HashMap<>();
    Map<String, EvaluatorWrapper> usedOperators = new HashMap<>();
    for (Entry<String, Class<?>> entry : availableIdentifiers.getDeclrClasses().entrySet()) {
        if (identifiers.contains(entry.getKey())) {
            usedDecls.put(entry.getKey(), entry.getValue());
            notBound.remove(entry.getKey());
        }
    }
    for (String identifier : identifiers) {
        Class<?> type = availableIdentifiers.resolveVarType(identifier);
        if (type != null) {
            usedGlobals.put(identifier, type);
            notBound.remove(identifier);
        }
    }
    for (Map.Entry<String, EvaluatorWrapper> op : availableIdentifiers.getOperators().entrySet()) {
        if (identifiers.contains(op.getKey())) {
            usedOperators.put(op.getKey(), op.getValue());
            notBound.remove(op.getKey());
        }
    }
    BoundIdentifiers boundIdentifiers = new BoundIdentifiers(usedDecls, availableIdentifiers.getContext(), usedOperators, availableIdentifiers.getThisClass());
    boundIdentifiers.setGlobals(usedGlobals);
    result.setBoundIdentifiers(boundIdentifiers);
    result.setNotBoundedIdentifiers(notBound);
    return result;
}
Also used : EvaluatorWrapper(org.drools.compiler.rule.builder.EvaluatorWrapper) HashMap(java.util.HashMap) BoundIdentifiers(org.drools.compiler.compiler.BoundIdentifiers) HashMap(java.util.HashMap) Map(java.util.Map) HashSet(java.util.HashSet)

Example 9 with EvaluatorWrapper

use of org.drools.compiler.rule.builder.EvaluatorWrapper in project drools by kiegroup.

the class MVELConstraintBuilder method buildLiteralConstraint.

public Constraint buildLiteralConstraint(RuleBuildContext context, Pattern pattern, ValueType vtype, FieldValue field, String expression, String leftValue, String operator, boolean negated, String rightValue, InternalReadAccessor extractor, LiteralRestrictionDescr restrictionDescr, Map<String, OperatorDescr> aliases) {
    if (!isMvelOperator(operator)) {
        Evaluator evaluator = buildLiteralEvaluator(context, extractor, restrictionDescr, vtype);
        if (evaluator != null && evaluator.isTemporal()) {
            try {
                field = FieldFactory.getInstance().getFieldValue(field.getValue(), ValueType.DATE_TYPE);
            } catch (Exception e) {
                context.addError(new DescrBuildError(context.getParentDescr(), restrictionDescr, null, e.getMessage()));
            }
        }
        return new EvaluatorConstraint(field, evaluator, extractor);
    }
    String mvelExpr = normalizeMVELLiteralExpression(vtype, field, expression, leftValue, operator, rightValue, negated, restrictionDescr);
    IndexUtil.ConstraintType constraintType = IndexUtil.ConstraintType.decode(operator, negated);
    if (constraintType == IndexUtil.ConstraintType.EQUAL && negated) {
        mvelExpr = normalizeDoubleNegation(mvelExpr);
    }
    MVELCompilationUnit compilationUnit = buildCompilationUnit(context, pattern, mvelExpr, aliases);
    EvaluatorWrapper[] operators = getOperators(buildOperators(context, pattern, restrictionDescr, aliases));
    return new MVELConstraint(context.getPkg().getName(), mvelExpr, compilationUnit, constraintType, field, extractor, operators);
}
Also used : DescrBuildError(org.drools.compiler.compiler.DescrBuildError) PatternBuilder.registerDescrBuildError(org.drools.compiler.rule.builder.PatternBuilder.registerDescrBuildError) EvaluatorWrapper(org.drools.compiler.rule.builder.EvaluatorWrapper) IndexUtil(org.drools.core.util.index.IndexUtil) MVELCompilationUnit(org.drools.mvel.expr.MVELCompilationUnit) MvelEvaluator.createMvelEvaluator(org.drools.mvel.expr.MvelEvaluator.createMvelEvaluator) MvelEvaluator(org.drools.mvel.expr.MvelEvaluator) ReteEvaluator(org.drools.core.common.ReteEvaluator) Evaluator(org.drools.core.spi.Evaluator) IOException(java.io.IOException)

Example 10 with EvaluatorWrapper

use of org.drools.compiler.rule.builder.EvaluatorWrapper in project drools by kiegroup.

the class ASMConditionEvaluatorJitter method jitEvaluator.

public static ConditionEvaluator jitEvaluator(String expression, Condition condition, Declaration[] declarations, EvaluatorWrapper[] operators, ClassLoader classLoader, Tuple tuple) {
    ClassGenerator generator = new ClassGenerator(getUniqueClassName(), classLoader).setInterfaces(ConditionEvaluator.class).addStaticField(ACC_PRIVATE | ACC_FINAL, "EXPRESSION", String.class, expression).addField(ACC_PRIVATE | ACC_FINAL, "declarations", Declaration[].class);
    generator.addMethod(ACC_PUBLIC, "evaluate", generator.methodDescr(boolean.class, InternalFactHandle.class, ReteEvaluator.class, Tuple.class), new EvaluateMethodGenerator(condition, declarations, operators, tuple));
    if (operators.length == 0) {
        generator.addDefaultConstructor(new ClassGenerator.MethodBody() {

            public void body(MethodVisitor mv) {
                putFieldInThisFromRegistry("declarations", Declaration[].class, 1);
                mv.visitInsn(RETURN);
            }
        }, Declaration[].class);
        return generator.newInstance(Declaration[].class, declarations);
    }
    generator.addField(ACC_PRIVATE | ACC_FINAL, "operators", EvaluatorWrapper[].class);
    generator.addDefaultConstructor(new ClassGenerator.MethodBody() {

        public void body(MethodVisitor mv) {
            putFieldInThisFromRegistry("declarations", Declaration[].class, 1);
            putFieldInThisFromRegistry("operators", EvaluatorWrapper[].class, 2);
            mv.visitInsn(RETURN);
        }
    }, Declaration[].class, EvaluatorWrapper[].class);
    return generator.newInstance(Declaration[].class, declarations, EvaluatorWrapper[].class, operators);
}
Also used : ReteEvaluator(org.drools.core.common.ReteEvaluator) ClassGenerator(org.drools.mvel.asm.ClassGenerator) EvaluatorWrapper(org.drools.compiler.rule.builder.EvaluatorWrapper) Declaration(org.drools.core.rule.Declaration) InternalFactHandle(org.drools.core.common.InternalFactHandle) GeneratorHelper.matchDeclarationsToTuple(org.drools.mvel.asm.GeneratorHelper.matchDeclarationsToTuple) Tuple(org.drools.core.spi.Tuple) MethodVisitor(org.mvel2.asm.MethodVisitor)

Aggregations

EvaluatorWrapper (org.drools.compiler.rule.builder.EvaluatorWrapper)10 HashMap (java.util.HashMap)4 HashSet (java.util.HashSet)4 Map (java.util.Map)4 InternalFactHandle (org.drools.core.common.InternalFactHandle)3 ReteEvaluator (org.drools.core.common.ReteEvaluator)3 Declaration (org.drools.core.rule.Declaration)3 MVELCompilationUnit (org.drools.mvel.expr.MVELCompilationUnit)3 IOException (java.io.IOException)2 BoundIdentifiers (org.drools.compiler.compiler.BoundIdentifiers)2 DescrBuildError (org.drools.compiler.compiler.DescrBuildError)2 RuleBuildContext (org.drools.compiler.rule.builder.RuleBuildContext)2 Evaluator (org.drools.core.spi.Evaluator)2 IndexUtil (org.drools.core.util.index.IndexUtil)2 ParserContext (org.mvel2.ParserContext)2 ArrayList (java.util.ArrayList)1 LinkedHashMap (java.util.LinkedHashMap)1 Entry (java.util.Map.Entry)1 RecognitionException (org.antlr.runtime.RecognitionException)1 EvaluatorDefinition (org.drools.compiler.rule.builder.EvaluatorDefinition)1