use of org.drools.drl.ast.descr.ConstraintConnectiveDescr in project drools by kiegroup.
the class PatternBuilder method build.
private void build(RuleBuildContext context, PatternDescr patternDescr, Declaration xpathStartDeclaration, Pattern pattern, BaseDescr original, String expr) {
ConstraintConnectiveDescr result = parseExpression(context, patternDescr, original, expr);
if (result == null) {
return;
}
result.copyLocation(original);
DumperContext mvelCtx = new DumperContext().setRuleContext(context);
List<Constraint> constraints = build(context, patternDescr, xpathStartDeclaration, pattern, result, mvelCtx);
pattern.addConstraints(constraints);
}
use of org.drools.drl.ast.descr.ConstraintConnectiveDescr 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);
}
}
}
use of org.drools.drl.ast.descr.ConstraintConnectiveDescr 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;
}
use of org.drools.drl.ast.descr.ConstraintConnectiveDescr in project drools by kiegroup.
the class QueryElementBuilder method parseExpression.
private ConstraintConnectiveDescr parseExpression(final RuleBuildContext context, final PatternDescr patternDescr, final String expression) {
DrlExprParser parser = new DrlExprParser(context.getConfiguration().getLanguageLevel());
ConstraintConnectiveDescr result = parser.parse(expression);
if (result == null || parser.hasErrors()) {
for (DroolsParserException error : parser.getErrors()) {
context.addError(new DescrBuildError(context.getParentDescr(), patternDescr, null, "Unable to parser 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 processConnectiveDescr.
protected void processConnectiveDescr(StringBuilder sbuilder, BaseDescr base, int parentPriority, boolean isInsideRelCons, DumperContext context) {
ConstraintConnectiveDescr ccd = (ConstraintConnectiveDescr) base;
boolean wrapParenthesis = parentPriority > ccd.getConnective().getPrecedence();
if (wrapParenthesis) {
sbuilder.append("( ");
}
boolean first = true;
List<BaseDescr> descrs = new ArrayList<>(ccd.getDescrs());
for (BaseDescr constr : descrs) {
if (!(constr instanceof BindingDescr)) {
if (first) {
first = false;
} else {
sbuilder.append(" ");
sbuilder.append(ccd.getConnective().toString());
sbuilder.append(" ");
}
}
context.incOpenCcd();
dump(sbuilder, constr, ccd, ccd.getDescrs().indexOf(constr), ccd.getConnective().getPrecedence(), isInsideRelCons, context);
context.decOpenCcd();
}
if (first) {
// means all children were actually only bindings, replace by just true
sbuilder.append("true");
}
if (wrapParenthesis) {
sbuilder.append(" )");
}
}
Aggregations