Search in sources :

Example 31 with ExprConstraintDescr

use of org.drools.drl.ast.descr.ExprConstraintDescr in project drools by kiegroup.

the class PatternBuilder method lookupObjectType.

private Declaration lookupObjectType(RuleBuildContext context, PatternDescr patternDescr) {
    List<? extends BaseDescr> descrs = patternDescr.getConstraint().getDescrs();
    if (descrs.size() != 1 || !(descrs.get(0) instanceof ExprConstraintDescr)) {
        return null;
    }
    ExprConstraintDescr descr = (ExprConstraintDescr) descrs.get(0);
    String expr = descr.getExpression();
    if (expr.charAt(0) != '/') {
        return null;
    }
    XpathAnalysis xpathAnalysis = XpathAnalysis.analyze(expr);
    if (xpathAnalysis.hasError()) {
        registerDescrBuildError(context, patternDescr, "Invalid xpath expression '" + expr + "': " + xpathAnalysis.getError());
        return null;
    }
    XpathPart firstXpathChunk = xpathAnalysis.getPart(0);
    String identifier = firstXpathChunk.getField();
    DeclarationScopeResolver resolver = context.getDeclarationResolver();
    if (resolver.hasDataSource(identifier)) {
        patternDescr.setObjectType(findObjectType(context, firstXpathChunk, identifier));
        FromDescr fromDescr = new FromDescr();
        fromDescr.setDataSource(new MVELExprDescr(identifier));
        patternDescr.setSource(fromDescr);
        patternDescr.removeAllConstraint();
        firstXpathChunk.getConstraints().forEach(s -> patternDescr.addConstraint(new ExprConstraintDescr(s)));
        if (!xpathAnalysis.isSinglePart()) {
            String xpathExpr = (patternDescr.getIdentifier() == null ? "" : patternDescr.getIdentifier() + " : ") + expr.substring(xpathAnalysis.getPart(1).getStart());
            patternDescr.addConstraint(new ExprConstraintDescr(xpathExpr));
            patternDescr.setIdentifier("$void$");
        }
    } else {
        Declaration declr = resolver.getDeclaration(identifier);
        if (declr == null) {
            registerDescrBuildError(context, patternDescr, "The identifier '" + identifier + "' is not in scope");
            return null;
        }
        patternDescr.setObjectType(declr.getExtractor().getExtractToClassName());
        expr = (patternDescr.getIdentifier() != null ? patternDescr.getIdentifier() + (patternDescr.isUnification() ? " := " : " : ") : "") + expr.substring(identifier.length() + 1);
        descr.setExpression(expr);
        return declr;
    }
    return null;
}
Also used : XpathPart(org.drools.compiler.rule.builder.XpathAnalysis.XpathPart) DeclarationScopeResolver(org.drools.core.spi.DeclarationScopeResolver) FromDescr(org.drools.drl.ast.descr.FromDescr) MVELExprDescr(org.drools.drl.ast.descr.MVELExprDescr) TypeDeclaration(org.drools.core.rule.TypeDeclaration) Declaration(org.drools.core.rule.Declaration) ExprConstraintDescr(org.drools.drl.ast.descr.ExprConstraintDescr)

Example 32 with ExprConstraintDescr

use of org.drools.drl.ast.descr.ExprConstraintDescr in project drools by kiegroup.

the class PatternBuilder method processConstraintsAndBinds.

/**
 * Process all constraints and bindings on this pattern
 */
private void processConstraintsAndBinds(RuleBuildContext context, PatternDescr patternDescr, Declaration xpathStartDeclaration, Pattern pattern) {
    DumperContext mvelCtx = new DumperContext().setRuleContext(context);
    for (BaseDescr b : patternDescr.getDescrs()) {
        String expression;
        boolean isPositional = false;
        if (b instanceof BindingDescr) {
            BindingDescr bind = (BindingDescr) b;
            expression = bind.getVariable() + (bind.isUnification() ? " := " : " : ") + bind.getExpression();
        } else if (b instanceof ExprConstraintDescr) {
            ExprConstraintDescr descr = (ExprConstraintDescr) b;
            expression = descr.getExpression();
            isPositional = descr.getType() == ExprConstraintDescr.Type.POSITIONAL;
        } else {
            expression = b.getText();
        }
        ConstraintConnectiveDescr result = parseExpression(context, patternDescr, b, expression);
        if (result == null) {
            return;
        }
        result.setNegated(b.isNegated());
        isPositional &= !(result.getDescrs().size() == 1 && result.getDescrs().get(0) instanceof BindingDescr);
        if (isPositional) {
            processPositional(context, patternDescr, xpathStartDeclaration, pattern, (ExprConstraintDescr) b);
        } else {
            // need to build the actual constraint
            List<Constraint> constraints = build(context, patternDescr, xpathStartDeclaration, pattern, result, mvelCtx);
            pattern.addConstraints(constraints);
        }
    }
    TypeDeclaration typeDeclaration = getTypeDeclaration(pattern, context);
    if (typeDeclaration != null && typeDeclaration.isPropertyReactive()) {
        for (String field : lookAheadFieldsOfIdentifier(context.getRuleDescr(), patternDescr)) {
            addFieldToPatternWatchlist(pattern, typeDeclaration, field);
        }
    }
}
Also used : BindingDescr(org.drools.drl.ast.descr.BindingDescr) XpathConstraint(org.drools.core.rule.constraint.XpathConstraint) PredicateConstraint(org.drools.core.rule.PredicateConstraint) NegConstraint(org.drools.core.rule.constraint.NegConstraint) Constraint(org.drools.core.spi.Constraint) BaseDescr(org.drools.drl.ast.descr.BaseDescr) DumperContext(org.drools.compiler.lang.DumperContext) ConstraintConnectiveDescr(org.drools.drl.ast.descr.ConstraintConnectiveDescr) TypeDeclaration(org.drools.core.rule.TypeDeclaration) ExprConstraintDescr(org.drools.drl.ast.descr.ExprConstraintDescr)

Example 33 with ExprConstraintDescr

use of org.drools.drl.ast.descr.ExprConstraintDescr in project drools by kiegroup.

the class PatternBuilder method buildXPathDescr.

private Constraint buildXPathDescr(RuleBuildContext context, PatternDescr patternDescr, Declaration xpathStartDeclaration, Pattern pattern, ExpressionDescr descr, DumperContext mvelCtx) {
    String expression = descr.getExpression();
    XpathAnalysis xpathAnalysis = XpathAnalysis.analyze(expression);
    if (xpathAnalysis.hasError()) {
        registerDescrBuildError(context, patternDescr, "Invalid xpath expression '" + expression + "': " + xpathAnalysis.getError());
        return null;
    }
    XpathConstraint xpathConstraint = new XpathConstraint();
    ObjectType objectType = pattern.getObjectType();
    if (objectType.isTemplate()) {
        throw new UnsupportedOperationException("xpath is not supported with fact templates");
    }
    Class<?> patternClass = ((ClassObjectType) objectType).getClassType();
    List<Class<?>> backReferenceClasses = new ArrayList<>();
    backReferenceClasses.add(patternClass);
    XpathBackReference backRef = new XpathBackReference(pattern, backReferenceClasses);
    pattern.setBackRefDeclarations(backRef);
    ObjectType originalType = pattern.getObjectType();
    ObjectType currentObjectType = originalType;
    mvelCtx.setInXpath(true);
    try {
        // then the xpathoffset must be adjusted by -1, as pattern is not actually added to the rete network
        for (XpathAnalysis.XpathPart part : xpathAnalysis) {
            XpathConstraint.XpathChunk xpathChunk = xpathConstraint.addChunck(patternClass, part.getField(), part.getIndex(), part.isIterate(), part.isLazy());
            // make sure the Pattern is wired up to correct ClassObjectType and set as a target for rewiring
            context.getPkg().wireObjectType(currentObjectType, xpathChunk);
            if (xpathChunk == null) {
                registerDescrBuildError(context, patternDescr, "Invalid xpath expression '" + expression + "': cannot access " + part.getField() + " on " + patternClass);
                pattern.setObjectType(originalType);
                return null;
            }
            if (part.getInlineCast() != null) {
                try {
                    patternClass = context.getDialect().getTypeResolver().resolveType(part.getInlineCast());
                } catch (ClassNotFoundException e) {
                    registerDescrBuildError(context, patternDescr, "Unknown class " + part.getInlineCast() + " in xpath expression '" + expression + "'");
                    return null;
                }
                part.addInlineCastConstraint(patternClass);
                currentObjectType = getObjectType(context, patternDescr, patternClass.getName());
                xpathChunk.setReturnedType(currentObjectType);
            } else {
                patternClass = xpathChunk.getReturnedClass();
                currentObjectType = getObjectType(context, patternDescr, patternClass.getName());
            }
            context.increaseXpathChuckNr();
            pattern.setObjectType(currentObjectType);
            backReferenceClasses.add(0, patternClass);
            backRef.reset();
            for (String constraint : part.getConstraints()) {
                ConstraintConnectiveDescr result = parseExpression(context, patternDescr, new ExprConstraintDescr(constraint), constraint);
                if (result == null) {
                    continue;
                }
                // preserving this, as the recursive build() resets it
                int chunkNbr = context.getXpathChuckNr();
                for (Constraint c : build(context, patternDescr, xpathStartDeclaration, pattern, result, mvelCtx)) {
                    xpathChunk.addConstraint(c);
                }
                context.setXpathChuckNr(chunkNbr);
            }
        }
        xpathConstraint.setXpathStartDeclaration(xpathStartDeclaration);
        if (descr instanceof BindingDescr) {
            Declaration pathDeclr = pattern.addDeclaration(((BindingDescr) descr).getVariable());
            pathDeclr.setxPathOffset(context.getXpathChuckNr());
            xpathConstraint.setDeclaration(pathDeclr);
        }
    } finally {
        mvelCtx.setInXpath(false);
        pattern.setBackRefDeclarations(null);
        pattern.setObjectType(originalType);
        context.resetXpathChuckNr();
    }
    return xpathConstraint;
}
Also used : XpathConstraint(org.drools.core.rule.constraint.XpathConstraint) BindingDescr(org.drools.drl.ast.descr.BindingDescr) AcceptsClassObjectType(org.drools.core.spi.AcceptsClassObjectType) ClassObjectType(org.drools.core.base.ClassObjectType) XpathConstraint(org.drools.core.rule.constraint.XpathConstraint) PredicateConstraint(org.drools.core.rule.PredicateConstraint) NegConstraint(org.drools.core.rule.constraint.NegConstraint) Constraint(org.drools.core.spi.Constraint) ArrayList(java.util.ArrayList) XpathBackReference(org.drools.core.rule.XpathBackReference) XpathConstraint(org.drools.core.rule.constraint.XpathConstraint) PredicateConstraint(org.drools.core.rule.PredicateConstraint) NegConstraint(org.drools.core.rule.constraint.NegConstraint) Constraint(org.drools.core.spi.Constraint) AcceptsClassObjectType(org.drools.core.spi.AcceptsClassObjectType) FactTemplateObjectType(org.drools.core.facttemplates.FactTemplateObjectType) ClassObjectType(org.drools.core.base.ClassObjectType) ObjectType(org.drools.core.spi.ObjectType) XpathPart(org.drools.compiler.rule.builder.XpathAnalysis.XpathPart) ConstraintConnectiveDescr(org.drools.drl.ast.descr.ConstraintConnectiveDescr) TypeDeclaration(org.drools.core.rule.TypeDeclaration) Declaration(org.drools.core.rule.Declaration) ExprConstraintDescr(org.drools.drl.ast.descr.ExprConstraintDescr)

Example 34 with ExprConstraintDescr

use of org.drools.drl.ast.descr.ExprConstraintDescr in project drools by kiegroup.

the class PatternDescrBuilderImpl method constraint.

public PatternDescrBuilder<P> constraint(String constraint) {
    ExprConstraintDescr constr = new ExprConstraintDescr(constraint);
    constr.setType(ExprConstraintDescr.Type.NAMED);
    constr.setPosition(descr.getConstraint().getDescrs().size());
    constr.setResource(descr.getResource());
    descr.addConstraint(constr);
    return this;
}
Also used : ExprConstraintDescr(org.drools.drl.ast.descr.ExprConstraintDescr)

Example 35 with ExprConstraintDescr

use of org.drools.drl.ast.descr.ExprConstraintDescr in project drools by kiegroup.

the class Query method buildPattern.

@Override
public void buildPattern() {
    NameExpr queryCall = new NameExpr(toQueryDef(pattern.getObjectType()));
    MethodCallExpr callCall = new MethodCallExpr(queryCall, QUERY_INVOCATION_CALL);
    callCall.addArgument("" + !pattern.isQuery());
    if (!constraintDescrs.isEmpty()) {
        List<QueryParameter> queryParams = packageModel.queryVariables(queryName);
        if (queryParams.size() != constraintDescrs.size()) {
            context.addCompilationError(new InvalidExpressionErrorResult("Wrong number of argument invoking query '" + queryName + "'"));
            return;
        }
        Expression[] queryArgs = new Expression[queryParams.size()];
        for (int i = 0; i < constraintDescrs.size(); i++) {
            BaseDescr baseDescr = constraintDescrs.get(i);
            String itemText = baseDescr.getText();
            boolean isPositional = baseDescr instanceof ExprConstraintDescr && ((ExprConstraintDescr) baseDescr).getType() == ExprConstraintDescr.Type.POSITIONAL;
            boolean isBinding = baseDescr instanceof BindingDescr || itemText.contains(":");
            if ((!isPositional) && (!isBinding)) {
                // error, can't have non binding slots.
                context.addCompilationError(new InvalidExpressionErrorResult("Query's must use positional or bindings, not field constraints: " + itemText));
            } else if (isPositional && isBinding) {
                // error, can't have positional binding slots.
                context.addCompilationError(new InvalidExpressionErrorResult("Query's can't use positional bindings: " + itemText));
            }
            int colonPos = itemText.indexOf(':');
            if (colonPos > 0) {
                String bindingId = itemText.substring(0, colonPos).trim();
                String paramName = itemText.substring(colonPos + 1).trim();
                for (int j = 0; j < queryParams.size(); j++) {
                    if (queryParams.get(j).getName().equals(paramName)) {
                        addQueryArg(queryParams, queryArgs, bindingId, j);
                        break;
                    } else if (queryParams.get(j).getName().equals(bindingId)) {
                        addQueryArg(queryParams, queryArgs, paramName, j);
                        break;
                    }
                }
            } else {
                addQueryArg(queryParams, queryArgs, itemText, i);
            }
        }
        for (Expression queryArg : queryArgs) {
            callCall.addArgument(queryArg);
        }
    }
    context.addExpression(callCall);
}
Also used : BindingDescr(org.drools.drl.ast.descr.BindingDescr) QueryParameter(org.drools.modelcompiler.builder.generator.QueryParameter) NameExpr(com.github.javaparser.ast.expr.NameExpr) InvalidExpressionErrorResult(org.drools.modelcompiler.builder.errors.InvalidExpressionErrorResult) Expression(com.github.javaparser.ast.expr.Expression) StaticJavaParser.parseExpression(com.github.javaparser.StaticJavaParser.parseExpression) BaseDescr(org.drools.drl.ast.descr.BaseDescr) ExprConstraintDescr(org.drools.drl.ast.descr.ExprConstraintDescr) MethodCallExpr(com.github.javaparser.ast.expr.MethodCallExpr)

Aggregations

ExprConstraintDescr (org.drools.drl.ast.descr.ExprConstraintDescr)75 PatternDescr (org.drools.drl.ast.descr.PatternDescr)65 Test (org.junit.Test)56 RuleDescr (org.drools.drl.ast.descr.RuleDescr)37 AndDescr (org.drools.drl.ast.descr.AndDescr)34 PackageDescr (org.drools.drl.ast.descr.PackageDescr)23 BaseDescr (org.drools.drl.ast.descr.BaseDescr)11 BindingDescr (org.drools.drl.ast.descr.BindingDescr)10 Cheese (org.drools.mvel.compiler.Cheese)9 KnowledgeBuilderImpl (org.drools.compiler.builder.impl.KnowledgeBuilderImpl)8 GlobalDescr (org.drools.drl.ast.descr.GlobalDescr)5 NotDescr (org.drools.drl.ast.descr.NotDescr)5 Declaration (org.drools.core.rule.Declaration)4 KiePMMLFieldOperatorValue (org.kie.pmml.models.drools.ast.KiePMMLFieldOperatorValue)4 KiePMMLOperatorValue (org.kie.pmml.models.drools.tuples.KiePMMLOperatorValue)4 Element (org.w3c.dom.Element)4 ArrayList (java.util.ArrayList)3 List (java.util.List)3 RuleImpl (org.drools.core.definitions.rule.impl.RuleImpl)3 PredicateConstraint (org.drools.core.rule.PredicateConstraint)3