Search in sources :

Example 56 with ConstraintConnectiveDescr

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

the class QueryElementBuilder method build.

public RuleConditionElement build(RuleBuildContext context, BaseDescr descr, QueryImpl query) {
    PatternDescr patternDescr = (PatternDescr) descr;
    Declaration[] params = query.getParameters();
    List<BaseDescr> args = (List<BaseDescr>) patternDescr.getDescrs();
    List<Declaration> requiredDeclarations = new ArrayList<>();
    ObjectType argsObjectType = ClassObjectType.ObjectArray_ObjectType;
    InternalReadAccessor arrayReader = new SelfReferenceClassFieldReader(Object[].class);
    Pattern pattern = new Pattern(context.getNextPatternId(), // tupleIndex is 0 by default
    0, // patternIndex is 0 by default
    0, argsObjectType, null);
    if (!StringUtils.isEmpty(patternDescr.getIdentifier())) {
        if (query.isAbductive()) {
            Declaration declr = context.getDeclarationResolver().getDeclaration(patternDescr.getIdentifier());
            if (declr != null && !patternDescr.isUnification()) {
                context.addError(new DescrBuildError(context.getParentDescr(), descr, null, "Duplicate declaration " + patternDescr.getIdentifier() + ", unable to bind abducted value"));
            }
        } else {
            context.addError(new DescrBuildError(context.getParentDescr(), descr, null, "Query binding is not supported by non-abductive queries : " + patternDescr.getIdentifier()));
        }
    }
    boolean addAbductiveReturnArgument = query.isAbductive() && !StringUtils.isEmpty(patternDescr.getIdentifier()) && args.size() < params.length;
    if (addAbductiveReturnArgument) {
        ExprConstraintDescr extraDescr = new ExprConstraintDescr(patternDescr.getIdentifier());
        extraDescr.setPosition(patternDescr.getConstraint().getDescrs().size());
        extraDescr.setType(ExprConstraintDescr.Type.POSITIONAL);
        args.add(extraDescr);
    }
    QueryArgument[] arguments = new QueryArgument[params.length];
    // Deal with the constraints, both positional and bindings
    for (BaseDescr base : args) {
        String expression = null;
        boolean isPositional = false;
        boolean isBinding = false;
        BindingDescr bind = null;
        ConstraintConnectiveDescr result = null;
        if (base instanceof BindingDescr) {
            bind = (BindingDescr) base;
            expression = bind.getVariable() + (bind.isUnification() ? " := " : " : ") + bind.getExpression();
            isBinding = true;
        } else {
            if (base instanceof ExprConstraintDescr) {
                ExprConstraintDescr ecd = (ExprConstraintDescr) base;
                expression = ecd.getExpression();
                isPositional = ecd.getType() == ExprConstraintDescr.Type.POSITIONAL;
            } else {
                expression = base.getText();
            }
            result = parseExpression(context, patternDescr, expression);
            if (result == null) {
                // error, can't parse expression.
                context.addError(new DescrBuildError(context.getParentDescr(), descr, null, "Unable to parse constraint: \n" + expression));
                continue;
            }
            isBinding = result.getDescrs().size() == 1 && result.getDescrs().get(0) instanceof BindingDescr;
            if (isBinding) {
                bind = (BindingDescr) result.getDescrs().get(0);
            }
        }
        if ((!isPositional) && (!isBinding)) {
            // error, can't have non binding slots.
            context.addError(new DescrBuildError(context.getParentDescr(), descr, null, "Query's must use positional or bindings, not field constraints:\n" + expression));
        } else if (isPositional && isBinding) {
            // error, can't have positional binding slots.
            context.addError(new DescrBuildError(context.getParentDescr(), descr, null, "Query's can't use positional bindings:\n" + expression));
        } else if (isPositional) {
            processPositional(context, query, params, arguments, requiredDeclarations, arrayReader, pattern, base, expression, result);
        } else {
            // it is binding
            processBinding(context, descr, params, arguments, requiredDeclarations, arrayReader, pattern, bind);
        }
    }
    List<Integer> varIndexList = new ArrayList<>();
    for (int i = 0; i < arguments.length; i++) {
        if (!(arguments[i] instanceof QueryArgument.Declr)) {
            if (arguments[i] instanceof QueryArgument.Var) {
                varIndexList.add(i);
            }
            continue;
        }
        Class actual = ((QueryArgument.Declr) arguments[i]).getArgumentClass();
        Declaration formalArgument = query.getParameters()[i];
        Class formal = formalArgument.getDeclarationClass();
        // input argument require a broader type, while output types require a narrower type, so we check for both.
        if (!ClassUtils.isTypeCompatibleWithArgumentType(actual, formal) && !ClassUtils.isTypeCompatibleWithArgumentType(formal, actual)) {
            context.addError(new DescrBuildError(context.getParentDescr(), descr, null, "Query is being invoked with known argument of type " + actual + " at position " + i + ", but the expected query argument is of type " + formal));
        }
    }
    return new QueryElement(pattern, query.getName(), arguments, toIntArray(varIndexList), requiredDeclarations.toArray(new Declaration[requiredDeclarations.size()]), !patternDescr.isQuery(), query.isAbductive());
}
Also used : BindingDescr(org.drools.drl.ast.descr.BindingDescr) QueryArgument(org.drools.core.rule.QueryArgument) PatternDescr(org.drools.drl.ast.descr.PatternDescr) ArrayList(java.util.ArrayList) QueryElement(org.drools.core.rule.QueryElement) ClassObjectType(org.drools.core.base.ClassObjectType) ObjectType(org.drools.core.spi.ObjectType) InternalReadAccessor(org.drools.core.spi.InternalReadAccessor) ArrayList(java.util.ArrayList) List(java.util.List) Declaration(org.drools.core.rule.Declaration) ConstraintConnectiveDescr(org.drools.drl.ast.descr.ConstraintConnectiveDescr) Pattern(org.drools.core.rule.Pattern) DescrBuildError(org.drools.compiler.compiler.DescrBuildError) SelfReferenceClassFieldReader(org.drools.core.base.extractors.SelfReferenceClassFieldReader) BaseDescr(org.drools.drl.ast.descr.BaseDescr) ExprConstraintDescr(org.drools.drl.ast.descr.ExprConstraintDescr)

Example 57 with ConstraintConnectiveDescr

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

the class PatternBuilder method parseExpression.

protected ConstraintConnectiveDescr parseExpression(final RuleBuildContext context, final PatternDescr patternDescr, final BaseDescr original, final String expression) {
    DrlExprParser parser = new DrlExprParser(context.getConfiguration().getLanguageLevel());
    ConstraintConnectiveDescr result = parser.parse(expression);
    result.setResource(patternDescr.getResource());
    result.copyLocation(original);
    if (parser.hasErrors()) {
        for (DroolsParserException error : parser.getErrors()) {
            registerDescrBuildError(context, patternDescr, "Unable to parse pattern expression:\n" + error.getMessage());
        }
        return null;
    }
    return result;
}
Also used : ConstraintConnectiveDescr(org.drools.drl.ast.descr.ConstraintConnectiveDescr) DrlExprParser(org.drools.drl.parser.DrlExprParser) DroolsParserException(org.drools.drl.parser.DroolsParserException)

Example 58 with ConstraintConnectiveDescr

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

the class DescrDumper method processConstraint.

private void processConstraint(StringBuilder sbuilder, ExprConstraintDescr base, boolean isInsideRelCons, DumperContext context) {
    DrlExprParser expr = new DrlExprParser(context.getRuleContext().getConfiguration().getLanguageLevel());
    ConstraintConnectiveDescr result = expr.parse(base.getExpression());
    if (result.getDescrs().size() == 1) {
        dump(sbuilder, result.getDescrs().get(0), 0, isInsideRelCons, context);
    } else {
        dump(sbuilder, result, 0, isInsideRelCons, context);
    }
}
Also used : ConstraintConnectiveDescr(org.drools.drl.ast.descr.ConstraintConnectiveDescr) DrlExprParser(org.drools.drl.parser.DrlExprParser)

Example 59 with ConstraintConnectiveDescr

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

the class DescrDumper method processInlineCast.

private String[] processInlineCast(String expr, AtomicExprDescr atomicExpr, ConstraintConnectiveDescr ccd, DumperContext context, int sharpPos, int parentIdx, int childIdx) {
    // convert "field1#Class.field2" in ["field1 instanceof Class && ", "((Class)field1).field2"]
    String field1 = expr.substring(0, sharpPos).trim();
    int sharpPos2 = expr.indexOf('#', sharpPos + 1);
    String part2 = sharpPos2 < 0 ? expr.substring(sharpPos + 1).trim() : expr.substring(sharpPos + 1, sharpPos2).trim();
    String[] classAndField = splitInClassAndField(part2, context);
    BaseDescr desc = parentIdx >= 0 ? ccd.getDescrs().get(parentIdx) : null;
    if (classAndField == null) {
        return new String[] { "", expr };
    } else if (desc instanceof AtomicExprDescr && classAndField.length == 1) {
        return new String[] { "", field1 + " instanceof " + classAndField[0] };
    }
    String className = classAndField[0];
    String castedExpression = classAndField.length == 1 ? "((" + className + ")" + field1 + ")" : "((" + className + ")" + field1 + ")." + classAndField[1] + (sharpPos2 > 0 ? expr.substring(sharpPos2) : "");
    RelationalExprDescr check = new RelationalExprDescr("instanceof", false, null, new AtomicExprDescr(field1), new AtomicExprDescr(className));
    if (ccd.getConnective() == ConnectiveType.AND || ccd.getConnective() == ConnectiveType.INC_AND) {
        ccd.getDescrs().add(childIdx, check);
    } else {
        if (desc instanceof ConstraintConnectiveDescr) {
            ((ConstraintConnectiveDescr) desc).getDescrs().add(childIdx, check);
        } else {
            ConstraintConnectiveDescr localAnd = new ConstraintConnectiveDescr(ConnectiveType.AND);
            BaseDescr original = ccd.getDescrs().remove(parentIdx);
            localAnd.getDescrs().add(check);
            localAnd.getDescrs().add(original);
            ccd.getDescrs().add(parentIdx, localAnd);
        }
    }
    atomicExpr.setRewrittenExpression(castedExpression);
    String innerCheck = check + " && ";
    return new String[] { innerCheck, castedExpression };
}
Also used : BaseDescr(org.drools.drl.ast.descr.BaseDescr) AtomicExprDescr(org.drools.drl.ast.descr.AtomicExprDescr) ConstraintConnectiveDescr(org.drools.drl.ast.descr.ConstraintConnectiveDescr) RelationalExprDescr(org.drools.drl.ast.descr.RelationalExprDescr)

Example 60 with ConstraintConnectiveDescr

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

the class ExprConstraintDescrVisitor method visit.

public void visit(ExprConstraintDescr descr) {
    DrlExprParser drlExprParser = new DrlExprParser(LanguageLevelOption.DRL5);
    ConstraintConnectiveDescr constraintConnectiveDescr = drlExprParser.parse(descr.getExpression());
    visit(constraintConnectiveDescr.getDescrs());
}
Also used : ConstraintConnectiveDescr(org.drools.drl.ast.descr.ConstraintConnectiveDescr) DrlExprParser(org.drools.drl.parser.DrlExprParser)

Aggregations

ConstraintConnectiveDescr (org.drools.drl.ast.descr.ConstraintConnectiveDescr)60 Test (org.junit.Test)29 BaseDescr (org.drools.drl.ast.descr.BaseDescr)23 BindingDescr (org.drools.drl.ast.descr.BindingDescr)17 AtomicExprDescr (org.drools.drl.ast.descr.AtomicExprDescr)15 RelationalExprDescr (org.drools.drl.ast.descr.RelationalExprDescr)12 AnnotationDescr (org.drools.drl.ast.descr.AnnotationDescr)8 DumperContext (org.drools.compiler.lang.DumperContext)7 DrlExprParser (org.drools.drl.parser.DrlExprParser)6 PredicateConstraint (org.drools.core.rule.PredicateConstraint)4 NegConstraint (org.drools.core.rule.constraint.NegConstraint)4 XpathConstraint (org.drools.core.rule.constraint.XpathConstraint)4 Constraint (org.drools.core.spi.Constraint)4 ArrayList (java.util.ArrayList)3 DescrBuildError (org.drools.compiler.compiler.DescrBuildError)3 Declaration (org.drools.core.rule.Declaration)3 ExprConstraintDescr (org.drools.drl.ast.descr.ExprConstraintDescr)3 DroolsParserException (org.drools.drl.parser.DroolsParserException)3 ClassObjectType (org.drools.core.base.ClassObjectType)2 QueryArgument (org.drools.core.rule.QueryArgument)2