Search in sources :

Example 21 with Declaration

use of org.drools.core.rule.Declaration in project drools by kiegroup.

the class MVELDialect method getMVELCompilationUnit.

public MVELCompilationUnit getMVELCompilationUnit(final String expression, final AnalysisResult analysis, Declaration[] previousDeclarations, Declaration[] localDeclarations, final Map<String, Class<?>> otherInputVariables, final PackageBuildContext context, String contextIndeifier, Class kcontextClass, boolean readLocalsFromTuple, MVELCompilationUnit.Scope scope) {
    Map<String, Class> resolvedInputs = new LinkedHashMap<String, Class>();
    List<String> ids = new ArrayList<String>();
    if (analysis.getBoundIdentifiers().getThisClass() != null || (localDeclarations != null && localDeclarations.length > 0)) {
        Class cls = analysis.getBoundIdentifiers().getThisClass();
        ids.add("this");
        resolvedInputs.put("this", // the only time cls is null is in accumumulate's acc/reverse
        (cls != null) ? cls : Object.class);
    }
    ids.add(contextIndeifier);
    resolvedInputs.put(contextIndeifier, kcontextClass);
    ids.add("kcontext");
    resolvedInputs.put("kcontext", kcontextClass);
    if (scope.hasRule()) {
        ids.add("rule");
        resolvedInputs.put("rule", Rule.class);
    }
    List<String> strList = new ArrayList<String>();
    for (String identifier : analysis.getIdentifiers()) {
        Class<?> type = analysis.getBoundIdentifiers().resolveVarType(identifier);
        if (type != null) {
            strList.add(identifier);
            ids.add(identifier);
            resolvedInputs.put(identifier, type);
        }
    }
    String[] globalIdentifiers = strList.toArray(new String[strList.size()]);
    strList.clear();
    for (String op : analysis.getBoundIdentifiers().getOperators().keySet()) {
        strList.add(op);
        ids.add(op);
        resolvedInputs.put(op, context.getConfiguration().getComponentFactory().getExpressionProcessor().getEvaluatorWrapperClass());
    }
    EvaluatorWrapper[] operators = new EvaluatorWrapper[strList.size()];
    for (int i = 0; i < operators.length; i++) {
        operators[i] = analysis.getBoundIdentifiers().getOperators().get(strList.get(i));
    }
    if (previousDeclarations != null) {
        for (Declaration decl : previousDeclarations) {
            if (analysis.getBoundIdentifiers().getDeclrClasses().containsKey(decl.getIdentifier())) {
                ids.add(decl.getIdentifier());
                resolvedInputs.put(decl.getIdentifier(), decl.getDeclarationClass());
            }
        }
    }
    if (localDeclarations != null) {
        for (Declaration decl : localDeclarations) {
            if (analysis.getBoundIdentifiers().getDeclrClasses().containsKey(decl.getIdentifier())) {
                ids.add(decl.getIdentifier());
                resolvedInputs.put(decl.getIdentifier(), decl.getDeclarationClass());
            }
        }
    }
    // "not bound" identifiers could be drools, kcontext and rule
    // but in the case of accumulate it could be vars from the "init" section.
    // String[] otherIdentifiers = otherInputVariables == null ? new String[]{} : new String[otherInputVariables.size()];
    strList = new ArrayList<String>();
    if (otherInputVariables != null) {
        MVELAnalysisResult mvelAnalysis = (MVELAnalysisResult) analysis;
        for (Entry<String, Class<?>> stringClassEntry : otherInputVariables.entrySet()) {
            if ((!analysis.getNotBoundedIdentifiers().contains(stringClassEntry.getKey()) && !mvelAnalysis.getMvelVariables().keySet().contains(stringClassEntry.getKey())) || "rule".equals(stringClassEntry.getKey())) {
                // and rule was already included
                continue;
            }
            ids.add(stringClassEntry.getKey());
            strList.add(stringClassEntry.getKey());
            resolvedInputs.put(stringClassEntry.getKey(), stringClassEntry.getValue());
        }
    }
    String[] otherIdentifiers = strList.toArray(new String[strList.size()]);
    String[] inputIdentifiers = new String[resolvedInputs.size()];
    String[] inputTypes = new String[resolvedInputs.size()];
    int i = 0;
    for (String id : ids) {
        inputIdentifiers[i] = id;
        inputTypes[i++] = resolvedInputs.get(id).getName();
    }
    String name;
    if (context != null && context.getPkg() != null && context.getPkg().getName() != null) {
        if (context instanceof RuleBuildContext) {
            name = context.getPkg().getName() + "." + ((RuleBuildContext) context).getRuleDescr().getClassName();
        } else {
            name = context.getPkg().getName() + ".Unknown";
        }
    } else {
        name = "Unknown";
    }
    return new MVELCompilationUnit(name, expression, globalIdentifiers, operators, previousDeclarations, localDeclarations, otherIdentifiers, inputIdentifiers, inputTypes, languageLevel, ((MVELAnalysisResult) analysis).isTypesafe(), readLocalsFromTuple);
}
Also used : EvaluatorWrapper(org.drools.core.base.EvaluatorWrapper) RuleBuildContext(org.drools.compiler.rule.builder.RuleBuildContext) ArrayList(java.util.ArrayList) MVELCompilationUnit(org.drools.core.base.mvel.MVELCompilationUnit) LinkedHashMap(java.util.LinkedHashMap) Declaration(org.drools.core.rule.Declaration)

Example 22 with Declaration

use of org.drools.core.rule.Declaration in project drools by kiegroup.

the class MVELSalienceBuilder method build.

public void build(RuleBuildContext context) {
    boolean typesafe = context.isTypesafe();
    // pushing consequence LHS into the stack for variable resolution
    context.getDeclarationResolver().pushOnBuildStack(context.getRule().getLhs());
    try {
        // This builder is re-usable in other dialects, so specify by name
        MVELDialect dialect = (MVELDialect) context.getDialect("mvel");
        Map<String, Declaration> decls = context.getDeclarationResolver().getDeclarations(context.getRule());
        MVELAnalysisResult analysis = (MVELAnalysisResult) dialect.analyzeExpression(context, context.getRuleDescr(), context.getRuleDescr().getSalience(), new BoundIdentifiers(DeclarationScopeResolver.getDeclarationClasses(decls), context));
        context.setTypesafe(analysis.isTypesafe());
        final BoundIdentifiers usedIdentifiers = analysis.getBoundIdentifiers();
        int i = usedIdentifiers.getDeclrClasses().keySet().size();
        Declaration[] previousDeclarations = new Declaration[i];
        i = 0;
        for (String id : usedIdentifiers.getDeclrClasses().keySet()) {
            previousDeclarations[i++] = decls.get(id);
        }
        Arrays.sort(previousDeclarations, SortDeclarations.instance);
        MVELCompilationUnit unit = dialect.getMVELCompilationUnit(context.getRuleDescr().getSalience(), analysis, previousDeclarations, null, null, context, "drools", KnowledgeHelper.class, false, MVELCompilationUnit.Scope.EXPRESSION);
        MVELSalienceExpression expr = new MVELSalienceExpression(unit, dialect.getId());
        context.getRule().setSalience(KiePolicyHelper.isPolicyEnabled() ? new SafeSalience(expr) : expr);
        MVELDialectRuntimeData data = (MVELDialectRuntimeData) context.getPkg().getDialectRuntimeRegistry().getDialectData("mvel");
        data.addCompileable(context.getRule(), expr);
        expr.compile(data, context.getRule());
    } catch (final Exception e) {
        copyErrorLocation(e, context.getRuleDescr());
        context.addError(new DescrBuildError(context.getParentDescr(), context.getRuleDescr(), null, "Unable to build expression for 'salience' : " + e.getMessage() + "'" + context.getRuleDescr().getSalience() + "'"));
    } finally {
        context.setTypesafe(typesafe);
    }
}
Also used : SafeSalience(org.drools.core.definitions.rule.impl.RuleImpl.SafeSalience) MVELCompilationUnit(org.drools.core.base.mvel.MVELCompilationUnit) BoundIdentifiers(org.drools.compiler.compiler.BoundIdentifiers) MVELDialectRuntimeData(org.drools.core.rule.MVELDialectRuntimeData) DescrBuildError(org.drools.compiler.compiler.DescrBuildError) MVELSalienceExpression(org.drools.core.base.mvel.MVELSalienceExpression) Declaration(org.drools.core.rule.Declaration)

Example 23 with Declaration

use of org.drools.core.rule.Declaration in project drools by kiegroup.

the class PatternBuilder method createImplicitBindings.

public static void createImplicitBindings(final RuleBuildContext context, final Pattern pattern, final Set<String> unboundIdentifiers, final BoundIdentifiers boundIdentifiers, final List<Declaration> factDeclarations) {
    for (Iterator<String> it = unboundIdentifiers.iterator(); it.hasNext(); ) {
        String identifier = it.next();
        Declaration declaration = createDeclarationObject(context, identifier, pattern);
        // that we would need to know about
        if (declaration != null) {
            factDeclarations.add(declaration);
            // implicit bindings need to be added to "local" declarations, as they are nolonger unbound
            boundIdentifiers.getDeclrClasses().put(identifier, declaration.getDeclarationClass());
            it.remove();
        }
    }
}
Also used : Declaration(org.drools.core.rule.Declaration) TypeDeclaration(org.drools.core.rule.TypeDeclaration)

Example 24 with Declaration

use of org.drools.core.rule.Declaration in project drools by kiegroup.

the class QueryBuilder method build.

public Pattern build(final RuleBuildContext context, final QueryDescr queryDescr) {
    ObjectType queryObjectType = ClassObjectType.DroolsQuery_ObjectType;
    final Pattern pattern = new Pattern(context.getNextPatternId(), // offset is 0 by default
    0, queryObjectType, null);
    final InternalReadAccessor extractor = PatternBuilder.getFieldReadAccessor(context, queryDescr, pattern, "name", null, true);
    final QueryNameConstraint constraint = new QueryNameConstraint(extractor, queryDescr.getName());
    PatternBuilder.registerReadAccessor(context, queryObjectType, "name", constraint);
    // adds appropriate constraint to the pattern
    pattern.addConstraint(constraint);
    ObjectType argsObjectType = ClassObjectType.DroolsQuery_ObjectType;
    InternalReadAccessor arrayExtractor = PatternBuilder.getFieldReadAccessor(context, queryDescr, null, argsObjectType, "elements", null, true);
    QueryImpl query = ((QueryImpl) context.getRule());
    String[] params;
    String[] types;
    int numParams = queryDescr.getParameters().length;
    if (query.isAbductive()) {
        params = Arrays.copyOf(queryDescr.getParameters(), queryDescr.getParameters().length + 1);
        types = Arrays.copyOf(queryDescr.getParameterTypes(), queryDescr.getParameterTypes().length + 1);
    } else {
        params = queryDescr.getParameters();
        types = queryDescr.getParameterTypes();
    }
    Declaration[] declarations = new Declaration[params.length];
    Class<?> abductionReturnKlass = null;
    if (query.isAbductive()) {
        Abductive abductive = queryDescr.getTypedAnnotation(Abductive.class);
        abductionReturnKlass = abductive.target();
        params[numParams] = "";
        types[numParams] = abductionReturnKlass.getName();
    }
    int i = 0;
    try {
        for (i = 0; i < params.length; i++) {
            Declaration declr = pattern.addDeclaration(params[i]);
            // this bit is different, notice its the ArrayElementReader that we wire up to, not the declaration.
            ArrayElementReader reader = new ArrayElementReader(arrayExtractor, i, context.getDialect().getTypeResolver().resolveType(types[i]));
            PatternBuilder.registerReadAccessor(context, argsObjectType, "elements", reader);
            declr.setReadAccessor(reader);
            declarations[i] = declr;
        }
        query.setParameters(declarations);
    } catch (ClassNotFoundException e) {
        context.addError(new DescrBuildError(context.getParentDescr(), queryDescr, e, "Unable to resolve type '" + types[i] + " for parameter" + params[i]));
    }
    context.setPrefixPattern(pattern);
    if (query.isAbductive()) {
        String returnName = "";
        try {
            AnnotationDescr ann = queryDescr.getAnnotation(Abductive.class);
            Object[] argsVal = ((Object[]) ann.getValue("args"));
            String[] args = argsVal != null ? Arrays.copyOf(argsVal, argsVal.length, String[].class) : null;
            returnName = types[numParams];
            ObjectType objectType = new ClassObjectType(abductionReturnKlass, false);
            objectType = context.getPkg().getClassFieldAccessorStore().wireObjectType(objectType, (AbductiveQuery) query);
            ((AbductiveQuery) query).setReturnType(objectType, params, args, declarations);
        } catch (NoSuchMethodException e) {
            context.addError(new DescrBuildError(context.getParentDescr(), queryDescr, e, "Unable to resolve abducible constructor for type : " + returnName + " with types " + Arrays.toString(types)));
        } catch (IllegalArgumentException e) {
            context.addError(new DescrBuildError(context.getParentDescr(), queryDescr, e, e.getMessage()));
        }
    }
    return pattern;
}
Also used : Pattern(org.drools.core.rule.Pattern) QueryNameConstraint(org.drools.core.rule.constraint.QueryNameConstraint) ClassObjectType(org.drools.core.base.ClassObjectType) Abductive(org.drools.core.beliefsystem.abductive.Abductive) AnnotationDescr(org.drools.compiler.lang.descr.AnnotationDescr) QueryNameConstraint(org.drools.core.rule.constraint.QueryNameConstraint) ClassObjectType(org.drools.core.base.ClassObjectType) ObjectType(org.drools.core.spi.ObjectType) QueryImpl(org.drools.core.rule.QueryImpl) DescrBuildError(org.drools.compiler.compiler.DescrBuildError) InternalReadAccessor(org.drools.core.spi.InternalReadAccessor) ArrayElementReader(org.drools.core.base.extractors.ArrayElementReader) Declaration(org.drools.core.rule.Declaration) AbductiveQuery(org.drools.core.rule.AbductiveQuery)

Example 25 with Declaration

use of org.drools.core.rule.Declaration in project drools by kiegroup.

the class ASMPredicateStubBuilder method createStubPredicate.

private void createStubPredicate(final ClassGenerator generator, final InvokerDataProvider data, final Map vars) {
    generator.setInterfaces(PredicateStub.class, CompiledInvoker.class).addField(ACC_PRIVATE + ACC_VOLATILE, "predicate", PredicateExpression.class);
    generator.addMethod(ACC_PUBLIC, "createContext", generator.methodDescr(Object.class), new ClassGenerator.MethodBody() {

        public void body(MethodVisitor mv) {
            mv.visitInsn(ACONST_NULL);
            mv.visitInsn(ARETURN);
        }
    }).addMethod(ACC_PUBLIC, "evaluate", generator.methodDescr(Boolean.TYPE, InternalFactHandle.class, Tuple.class, Declaration[].class, Declaration[].class, WorkingMemory.class, Object.class), new String[] { "java/lang/Exception" }, new ClassGenerator.MethodBody() {

        public void body(MethodVisitor mv) {
            Label syncStart = new Label();
            Label syncEnd = new Label();
            Label l1 = new Label();
            Label l2 = new Label();
            mv.visitTryCatchBlock(syncStart, l1, l2, null);
            Label l3 = new Label();
            mv.visitTryCatchBlock(l2, l3, l2, null);
            getFieldFromThis("predicate", PredicateExpression.class);
            mv.visitJumpInsn(IFNONNULL, syncEnd);
            mv.visitVarInsn(ALOAD, 0);
            mv.visitInsn(DUP);
            mv.visitVarInsn(ASTORE, 7);
            // synchronized(this) {
            mv.visitInsn(MONITORENTER);
            mv.visitLabel(syncStart);
            getFieldFromThis("predicate", PredicateExpression.class);
            // if (predicate == null) ...
            Label ifNotInitialized = new Label();
            mv.visitJumpInsn(IFNONNULL, ifNotInitialized);
            mv.visitVarInsn(ALOAD, 0);
            mv.visitVarInsn(ALOAD, 2);
            mv.visitVarInsn(ALOAD, 3);
            mv.visitVarInsn(ALOAD, 4);
            mv.visitVarInsn(ALOAD, 5);
            // ... PredicateGenerator.generate(this, tuple, declarations, declarations, workingMemory)
            invokeStatic(PredicateGenerator.class, "generate", null, PredicateStub.class, Tuple.class, Declaration[].class, Declaration[].class, WorkingMemory.class);
            mv.visitLabel(ifNotInitialized);
            mv.visitVarInsn(ALOAD, 7);
            mv.visitInsn(MONITOREXIT);
            mv.visitLabel(l1);
            mv.visitJumpInsn(GOTO, syncEnd);
            mv.visitLabel(l2);
            mv.visitVarInsn(ASTORE, 8);
            mv.visitVarInsn(ALOAD, 7);
            mv.visitInsn(MONITOREXIT);
            mv.visitLabel(l3);
            mv.visitVarInsn(ALOAD, 8);
            mv.visitInsn(ATHROW);
            mv.visitLabel(syncEnd);
            // } end of synchronized
            getFieldFromThis("predicate", PredicateExpression.class);
            mv.visitVarInsn(ALOAD, 1);
            mv.visitVarInsn(ALOAD, 2);
            mv.visitVarInsn(ALOAD, 3);
            mv.visitVarInsn(ALOAD, 4);
            mv.visitVarInsn(ALOAD, 5);
            mv.visitVarInsn(ALOAD, 6);
            invokeInterface(PredicateExpression.class, "evaluate", Boolean.TYPE, InternalFactHandle.class, Tuple.class, Declaration[].class, Declaration[].class, WorkingMemory.class, Object.class);
            mv.visitInsn(IRETURN);
        }
    }).addMethod(ACC_PUBLIC, "setPredicate", generator.methodDescr(null, PredicateExpression.class), new ClassGenerator.MethodBody() {

        public void body(MethodVisitor mv) {
            putFieldInThisFromRegistry("predicate", PredicateExpression.class, 1);
            mv.visitInsn(RETURN);
        }
    });
}
Also used : ClassGenerator(org.drools.core.rule.builder.dialect.asm.ClassGenerator) PredicateStub(org.drools.core.rule.builder.dialect.asm.PredicateStub) Label(org.mvel2.asm.Label) Declaration(org.drools.core.rule.Declaration) PredicateExpression(org.drools.core.spi.PredicateExpression) CompiledInvoker(org.drools.core.spi.CompiledInvoker) MethodVisitor(org.mvel2.asm.MethodVisitor)

Aggregations

Declaration (org.drools.core.rule.Declaration)115 Pattern (org.drools.core.rule.Pattern)42 ClassObjectType (org.drools.core.base.ClassObjectType)29 InternalReadAccessor (org.drools.core.spi.InternalReadAccessor)27 TypeDeclaration (org.drools.core.rule.TypeDeclaration)24 InternalFactHandle (org.drools.core.common.InternalFactHandle)22 ArrayList (java.util.ArrayList)19 HashMap (java.util.HashMap)17 BoundIdentifiers (org.drools.compiler.compiler.BoundIdentifiers)17 DescrBuildError (org.drools.compiler.compiler.DescrBuildError)16 Test (org.junit.Test)16 KnowledgeHelper (org.drools.core.spi.KnowledgeHelper)14 InternalWorkingMemory (org.drools.core.common.InternalWorkingMemory)12 WorkingMemory (org.drools.core.WorkingMemory)11 MVELCompilationUnit (org.drools.core.base.mvel.MVELCompilationUnit)11 RuleImpl (org.drools.core.definitions.rule.impl.RuleImpl)11 MvelConstraint (org.drools.core.rule.constraint.MvelConstraint)10 Consequence (org.drools.core.spi.Consequence)10 Constraint (org.drools.core.spi.Constraint)10 AnalysisResult (org.drools.compiler.compiler.AnalysisResult)9