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());
}
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;
}
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);
}
}
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 };
}
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());
}
Aggregations