Search in sources :

Example 1 with QueryArgument

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

the class QueryElementBuilder method processPositional.

private void processPositional(RuleBuildContext context, QueryImpl query, Declaration[] params, QueryArgument[] arguments, List<Declaration> requiredDeclarations, InternalReadAccessor arrayReader, Pattern pattern, BaseDescr base, String expression, ConstraintConnectiveDescr result) {
    int pos = ((ExprConstraintDescr) base).getPosition();
    if (pos >= arguments.length) {
        context.addError(new DescrBuildError(context.getParentDescr(), base, null, "Unable to parse query '" + query.getName() + "', as postion " + pos + " for expression '" + expression + "' does not exist on query size " + arguments.length));
        return;
    }
    boolean isVariable = isVariable(expression);
    DeclarationScopeResolver declarationResolver = context.getDeclarationResolver();
    Declaration declr = isVariable ? declarationResolver.getDeclaration(expression) : null;
    if (declr != null) {
        // it exists, so it's an input
        requiredDeclarations.add(declr);
        arguments[pos] = new QueryArgument.Declr(declr);
    } else if (isVariable && expression.indexOf('.') < 0) {
        arguments[pos] = getVariableQueryArgument(arrayReader, params, pos, pattern, expression);
    } else {
        // it's an expression and thus an input
        AnalysisResult analysisResult = analyzeExpression(context, base, expression);
        if (analysisResult == null || analysisResult.getIdentifiers().isEmpty()) {
            arguments[pos] = getLiteralQueryArgument(context, base, result);
        } else {
            List<Declaration> declarations = new ArrayList<Declaration>();
            for (String identifier : analysisResult.getIdentifiers()) {
                Declaration declaration = declarationResolver.getDeclaration(identifier);
                if (declaration != null) {
                    declarations.add(declaration);
                }
            }
            if (declarations.size() == analysisResult.getIdentifiers().size()) {
                arguments[pos] = new QueryArgument.Expression(declarations, expression, getParserContext(context));
            } else {
                arguments[pos] = getLiteralQueryArgument(context, base, result);
            }
        }
    }
}
Also used : QueryArgument(org.drools.core.rule.QueryArgument) DeclarationScopeResolver(org.drools.core.spi.DeclarationScopeResolver) AnalysisResult(org.drools.compiler.compiler.AnalysisResult) DescrBuildError(org.drools.compiler.compiler.DescrBuildError) ArrayList(java.util.ArrayList) List(java.util.List) Declaration(org.drools.core.rule.Declaration) ExprConstraintDescr(org.drools.compiler.lang.descr.ExprConstraintDescr)

Example 2 with QueryArgument

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

the class QueryElementBuilder method processBinding.

@SuppressWarnings("unchecked")
private void processBinding(RuleBuildContext context, BaseDescr descr, Declaration[] params, QueryArgument[] arguments, List<Declaration> requiredDeclarations, InternalReadAccessor arrayReader, Pattern pattern, BindingDescr bind) {
    Declaration declr = context.getDeclarationResolver().getDeclaration(bind.getVariable());
    if (declr != null) {
        // check right maps to a slot, otherwise we can't reverse this and should error
        int pos = getPos(bind.getExpression(), params);
        if (pos >= 0) {
            // slot exist, reverse and continue
            String slot = bind.getExpression();
            String var = bind.getVariable();
            bind.setVariable(slot);
            bind.setExpression(var);
        } else {
        // else error, we cannot find the slot to unify against
        }
    }
    // left does not already exist, is it a slot?
    int pos = getPos(bind.getVariable(), params);
    if (pos >= 0) {
        // it's an input on a slot, is the input using bindings?
        declr = context.getDeclarationResolver().getDeclaration(bind.getExpression());
        if (declr != null) {
            requiredDeclarations.add(declr);
            arguments[pos] = new QueryArgument.Declr(declr);
        } else {
            // it must be a literal/expression
            // it's an expression and thus an input
            DrlExprParser parser = new DrlExprParser(context.getConfiguration().getLanguageLevel());
            ConstraintConnectiveDescr bresult = parser.parse(bind.getExpression());
            if (parser.hasErrors()) {
                for (DroolsParserException error : parser.getErrors()) {
                    context.addError(new DescrBuildError(context.getParentDescr(), descr, null, "Unable to parser pattern expression:\n" + error.getMessage()));
                }
                return;
            }
            arguments[pos] = getLiteralQueryArgument(context, descr, bresult);
        }
    } else {
        // this is creating a new output binding
        // we know it doesn't exist, as we already checked for left == var
        pos = getPos(bind.getExpression(), params);
        if (pos < 0) {
            // error this must be a binding on a slot
            context.addError(new DescrBuildError(context.getParentDescr(), descr, null, "named argument does not exist:\n" + bind.getExpression()));
            return;
        }
        arguments[pos] = getVariableQueryArgument(arrayReader, params, pos, pattern, bind.getVariable());
    }
}
Also used : QueryArgument(org.drools.core.rule.QueryArgument) DescrBuildError(org.drools.compiler.compiler.DescrBuildError) Declaration(org.drools.core.rule.Declaration) ConstraintConnectiveDescr(org.drools.compiler.lang.descr.ConstraintConnectiveDescr) DrlExprParser(org.drools.compiler.compiler.DrlExprParser) DroolsParserException(org.drools.compiler.compiler.DroolsParserException)

Example 3 with QueryArgument

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

the class QueryElementBuilder method build.

@SuppressWarnings("unchecked")
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<Declaration>();
    ObjectType argsObjectType = ClassObjectType.ObjectArray_ObjectType;
    InternalReadAccessor arrayReader = new SelfReferenceClassFieldReader(Object[].class);
    Pattern pattern = new Pattern(context.getNextPatternId(), 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<Integer>();
    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.compiler.lang.descr.BindingDescr) QueryArgument(org.drools.core.rule.QueryArgument) PatternDescr(org.drools.compiler.lang.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.compiler.lang.descr.ConstraintConnectiveDescr) Pattern(org.drools.core.rule.Pattern) DescrBuildError(org.drools.compiler.compiler.DescrBuildError) SelfReferenceClassFieldReader(org.drools.core.base.extractors.SelfReferenceClassFieldReader) BaseDescr(org.drools.compiler.lang.descr.BaseDescr) ExprConstraintDescr(org.drools.compiler.lang.descr.ExprConstraintDescr)

Example 4 with QueryArgument

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

the class KiePackagesBuilder method buildQueryPattern.

private RuleConditionElement buildQueryPattern(RuleContext ctx, QueryCallPattern queryPattern) {
    Pattern pattern = new Pattern(ctx.getNextPatternIndex(), 0, ClassObjectType.ObjectArray_ObjectType, null);
    InternalReadAccessor arrayReader = new SelfReferenceClassFieldReader(Object[].class);
    QueryArgument[] arguments = new QueryArgument[queryPattern.getArguments().length];
    List<Integer> varIndexList = new ArrayList<>();
    List<Declaration> requiredDeclarations = new ArrayList<>();
    for (int i = 0; i < queryPattern.getArguments().length; i++) {
        Argument arg = queryPattern.getArguments()[i];
        if (arg instanceof Variable) {
            Variable var = ((Variable) arg);
            Declaration decl = ctx.getDeclaration(var);
            if (decl != null) {
                requiredDeclarations.add(decl);
                arguments[i] = new QueryArgument.Declr(decl);
            } else {
                ArrayElementReader reader = new ArrayElementReader(arrayReader, i, arg.getType());
                pattern.addDeclaration(var.getName()).setReadAccessor(reader);
                arguments[i] = QueryArgument.VAR;
                varIndexList.add(i);
            }
        } else if (arg instanceof Value) {
            arguments[i] = new QueryArgument.Literal(((Value) arg).getValue());
        } else {
            throw new UnsupportedOperationException();
        }
    }
    return new QueryElement(pattern, queryPattern.getQuery().getName(), arguments, varIndexList.stream().mapToInt(i -> i).toArray(), requiredDeclarations.toArray(new Declaration[requiredDeclarations.size()]), queryPattern.isOpen(), // TODO: query.isAbductive() );
    false);
}
Also used : QueryCallPattern(org.drools.model.patterns.QueryCallPattern) AccumulatePattern(org.drools.model.AccumulatePattern) Pattern(org.drools.core.rule.Pattern) QueryArgument(org.drools.core.rule.QueryArgument) PrototypeVariable(org.drools.model.PrototypeVariable) Variable(org.drools.model.Variable) QueryArgument(org.drools.core.rule.QueryArgument) Argument(org.drools.model.Argument) ArrayList(java.util.ArrayList) QueryElement(org.drools.core.rule.QueryElement) SingleConstraint(org.drools.model.SingleConstraint) QueryNameConstraint(org.drools.core.rule.constraint.QueryNameConstraint) LambdaConstraint(org.drools.modelcompiler.constraints.LambdaConstraint) FlowDSL.entryPoint(org.drools.model.FlowDSL.entryPoint) UnificationConstraint(org.drools.modelcompiler.constraints.UnificationConstraint) EntryPoint(org.drools.model.EntryPoint) Constraint(org.drools.model.Constraint) SalienceInteger(org.drools.core.base.SalienceInteger) SelfReferenceClassFieldReader(org.drools.core.base.extractors.SelfReferenceClassFieldReader) InternalReadAccessor(org.drools.core.spi.InternalReadAccessor) Value(org.drools.model.Value) ArrayElementReader(org.drools.core.base.extractors.ArrayElementReader) Declaration(org.drools.core.rule.Declaration) WindowDeclaration(org.drools.core.rule.WindowDeclaration) TypeDeclarationUtil.createTypeDeclaration(org.drools.modelcompiler.util.TypeDeclarationUtil.createTypeDeclaration) TypeDeclaration(org.drools.core.rule.TypeDeclaration)

Aggregations

Declaration (org.drools.core.rule.Declaration)4 QueryArgument (org.drools.core.rule.QueryArgument)4 ArrayList (java.util.ArrayList)3 DescrBuildError (org.drools.compiler.compiler.DescrBuildError)3 List (java.util.List)2 ConstraintConnectiveDescr (org.drools.compiler.lang.descr.ConstraintConnectiveDescr)2 ExprConstraintDescr (org.drools.compiler.lang.descr.ExprConstraintDescr)2 SelfReferenceClassFieldReader (org.drools.core.base.extractors.SelfReferenceClassFieldReader)2 Pattern (org.drools.core.rule.Pattern)2 QueryElement (org.drools.core.rule.QueryElement)2 InternalReadAccessor (org.drools.core.spi.InternalReadAccessor)2 AnalysisResult (org.drools.compiler.compiler.AnalysisResult)1 DrlExprParser (org.drools.compiler.compiler.DrlExprParser)1 DroolsParserException (org.drools.compiler.compiler.DroolsParserException)1 BaseDescr (org.drools.compiler.lang.descr.BaseDescr)1 BindingDescr (org.drools.compiler.lang.descr.BindingDescr)1 PatternDescr (org.drools.compiler.lang.descr.PatternDescr)1 ClassObjectType (org.drools.core.base.ClassObjectType)1 SalienceInteger (org.drools.core.base.SalienceInteger)1 ArrayElementReader (org.drools.core.base.extractors.ArrayElementReader)1