use of org.drools.impact.analysis.model.left.Constraint in project drools by kiegroup.
the class LhsParser method parseConstraint.
private void parseConstraint(RuleContext context, PatternDescr patternDescr, Pattern pattern, ConstraintParser constraintParser, BaseDescr constraintDescr) {
ConstraintExpression constraintExpression = ConstraintExpression.createConstraintExpression(context, pattern.getPatternClass(), constraintDescr, false);
DrlxParseResult drlxParseResult = constraintParser.drlxParse(pattern.getPatternClass(), patternDescr.getIdentifier(), constraintExpression, false);
if (drlxParseResult.isSuccess()) {
SingleDrlxParseSuccess result = (SingleDrlxParseSuccess) drlxParseResult;
if (!result.getReactOnProperties().isEmpty()) {
result.getReactOnProperties().forEach(pattern::addReactOn);
} else {
pattern.setClassReactive(true);
}
if (result.getRight() != null) {
Constraint constraint = new Constraint();
constraint = parseExpressionInConstraint(context, constraint, result.getLeft());
boolean valueOnLeft = constraint.getValue() != null;
constraint = parseExpressionInConstraint(context, constraint, result.getRight());
if (constraint.getValue() != null) {
// the constraint is relevant for impact analysis only if it checks a fixed value
constraint.setType(decode(result.getDecodeConstraintType(), valueOnLeft));
pattern.addConstraint(constraint);
}
} else if (result.getExprBinding() != null && result.getExpr() != null && result.getExpr().isLiteralExpr()) {
((ImpactAnalysisRuleContext) context).getBindVariableLiteralMap().put(result.getExprBinding(), ParserUtil.literalToValue(result.getExpr().asLiteralExpr()));
} else if (isPredicateMethodCall(result)) {
MethodCallExpr mce = result.getExpr().asMethodCallExpr();
addConstraintIfBooleanProperty(pattern, mce, true);
} else if (isNegatedPredicateMethodCall(result)) {
MethodCallExpr mce = result.getExpr().asUnaryExpr().getExpression().asMethodCallExpr();
addConstraintIfBooleanProperty(pattern, mce, false);
}
}
}
use of org.drools.impact.analysis.model.left.Constraint in project drools by kiegroup.
the class LhsParser method addConstraintIfBooleanProperty.
private void addConstraintIfBooleanProperty(Pattern pattern, MethodCallExpr mce, boolean value) {
if (isThisExpression(mce.getScope().orElse(null))) {
String methodName = mce.getName().asString();
String prop = ClassUtils.getter2property(methodName);
if (prop != null) {
Method method = MethodUtils.findMethod(pattern.getPatternClass(), methodName, new Class[0]);
if (method != null && isBooleanBoxedUnboxed(method.getReturnType())) {
Constraint constraint = new Constraint(Constraint.Type.EQUAL, prop, value);
pattern.addConstraint(constraint);
}
}
}
}
use of org.drools.impact.analysis.model.left.Constraint in project drools by kiegroup.
the class ModelToGraphConverter method processModify.
private void processModify(GraphAnalysis graphAnalysis, String pkgName, String ruleName, ModifyAction action) {
Node source = graphAnalysis.getNode(fqdn(pkgName, ruleName));
Class<?> modifiedClass = action.getActionClass();
if (!graphAnalysis.isRegisteredClass(modifiedClass)) {
// Not likely happen but not invalid
logger.warn("Not found {} in reactiveMap", modifiedClass);
return;
}
List<ModifiedProperty> modifiedProperties = action.getModifiedProperties();
for (ModifiedProperty modifiedProperty : modifiedProperties) {
String property = modifiedProperty.getProperty();
for (AnalyzedRule reactedRule : graphAnalysis.getRulesReactiveTo(modifiedClass, property)) {
List<Constraint> constraints = reactedRule.getRule().getLhs().getPatterns().stream().filter(pattern -> pattern.getPatternClass() == modifiedClass).flatMap(pattern -> pattern.getConstraints().stream()).filter(constraint -> constraint.getProperty() != null && constraint.getProperty().equals(property)).filter(constraint -> {
if (constraint instanceof MapConstraint) {
return doesAssertSameKey((MapConstraint) constraint, modifiedProperty);
} else {
return true;
}
}).collect(Collectors.toList());
ReactivityType combinedLinkType = ReactivityType.UNKNOWN;
if (constraints.isEmpty()) {
// This rule is reactive to the property but cannot find its constraint (e.g. [age > $a] non-literal constraint). It means UNKNOWN impact
combinedLinkType = ReactivityType.UNKNOWN;
} else {
// If constraints contain at least one POSITIVE, we consider it's POSITIVE.
for (Constraint constraint : constraints) {
ReactivityType linkType = linkType(constraint, modifiedProperty);
if (linkType == ReactivityType.POSITIVE) {
combinedLinkType = ReactivityType.POSITIVE;
break;
} else if (linkType == ReactivityType.NEGATIVE) {
// NEGATIVE is stronger than UNKNOWN (but may be configurable)
combinedLinkType = ReactivityType.NEGATIVE;
} else if (combinedLinkType == ReactivityType.NEGATIVE && linkType == ReactivityType.UNKNOWN) {
// Don't overwrite with UNKNOWN
} else {
// UNKNOWN
combinedLinkType = linkType;
}
}
}
if (reactedRule.getReactivityType() == ReactivityType.NEGATIVE) {
combinedLinkType = combinedLinkType.negate();
}
Node target = graphAnalysis.getNode(fqdn(pkgName, reactedRule.getRule().getName()));
linkNodesIfExpected(source, target, combinedLinkType);
}
}
}
use of org.drools.impact.analysis.model.left.Constraint in project drools by kiegroup.
the class ModelToGraphConverter method processInsert.
private void processInsert(GraphAnalysis graphAnalysis, String pkgName, String ruleName, InsertAction action) {
Node source = graphAnalysis.getNode(fqdn(pkgName, ruleName));
Class<?> insertedClass = action.getActionClass();
if (!graphAnalysis.isRegisteredClass(insertedClass)) {
// Not likely happen but not invalid
logger.warn("Not found {} in reactiveMap", insertedClass);
return;
}
// property based link
List<InsertedProperty> insertedProperties = action.getInsertedProperties();
for (InsertedProperty insertedProperty : insertedProperties) {
String property = insertedProperty.getProperty();
for (AnalyzedRule reactedRule : graphAnalysis.getRulesReactiveTo(insertedClass, property)) {
List<Pattern> patterns = reactedRule.getRule().getLhs().getPatterns().stream().filter(pattern -> pattern.getPatternClass() == insertedClass).collect(Collectors.toList());
for (Pattern pattern : patterns) {
List<Constraint> constraints = pattern.getConstraints().stream().filter(constraint -> constraint.getProperty() != null && constraint.getProperty().equals(property)).collect(Collectors.toList());
ReactivityType combinedLinkType = ReactivityType.UNKNOWN;
if (constraints.isEmpty()) {
// This rule is reactive to the property but cannot find its constraint (e.g. [age > $a] non-literal constraint). It means UNKNOWN impact
combinedLinkType = ReactivityType.UNKNOWN;
} else {
// If constraints contain at least one POSITIVE, we consider it's POSITIVE.
for (Constraint constraint : constraints) {
ReactivityType linkType = linkType(constraint, insertedProperty);
if (linkType == ReactivityType.POSITIVE) {
combinedLinkType = ReactivityType.POSITIVE;
break;
} else if (linkType == ReactivityType.NEGATIVE) {
// NEGATIVE is stronger than UNKNOWN (but may be configurable)
combinedLinkType = ReactivityType.NEGATIVE;
} else if (combinedLinkType == ReactivityType.NEGATIVE && linkType == ReactivityType.UNKNOWN) {
// Don't overwrite with UNKNOWN
} else {
// UNKNOWN
combinedLinkType = linkType;
}
}
}
if (combinedLinkType == ReactivityType.NEGATIVE) {
// TODO: handle "exists" case
continue;
}
if (combinedLinkType == ReactivityType.POSITIVE && !pattern.isPositive()) {
// POSITIVE insert in not() means NEGATIVE
combinedLinkType = combinedLinkType.negate();
}
Node target = graphAnalysis.getNode(fqdn(pkgName, reactedRule.getRule().getName()));
linkNodesIfExpected(source, target, combinedLinkType);
}
}
}
// class based link
for (AnalyzedRule reactedRule : graphAnalysis.getRulesReactiveToWithoutProperty(insertedClass)) {
Node target = graphAnalysis.getNode(fqdn(pkgName, reactedRule.getRule().getName()));
linkNodesIfExpected(source, target, reactedRule.getReactivityType());
}
}
Aggregations