use of org.drools.impact.analysis.model.right.ModifyAction in project drools by kiegroup.
the class RhsParser method processModify.
private ModifyAction processModify(RuleContext context, MethodCallExpr consequenceExpr, MethodCallExpr statement, BlockStmt ruleVariablesBlock) {
String modifiedId = statement.getArgument(0).toString();
Class<?> modifiedClass = context.getDeclarationById(modifiedId).orElseThrow(() -> new RuntimeException("Unknown declaration: " + modifiedId)).getDeclarationClass();
ModifyAction action = new ModifyAction(modifiedClass);
if (statement.getArguments().size() > 1) {
String maskId = statement.getArgument(1).toString();
AssignExpr maskAssignExpr = ruleVariablesBlock.findAll(AssignExpr.class).stream().filter(assign -> ((VariableDeclarationExpr) assign.getTarget()).getVariable(0).toString().equals(maskId)).findFirst().orElseThrow(() -> new RuntimeException("Unknown mask: " + maskId));
MethodCallExpr maskMethod = ((MethodCallExpr) maskAssignExpr.getValue());
List<MethodCallExpr> modifyingExprs = consequenceExpr.findAll(MethodCallExpr.class).stream().filter(m -> m.getScope().map(s -> s.toString().equals(modifiedId) || s.toString().equals("(" + modifiedId + ")")).orElse(false)).collect(Collectors.toList());
for (int i = 1; i < maskMethod.getArguments().size(); i++) {
String property = maskMethod.getArgument(i).asStringLiteralExpr().asString();
String setter = "set" + ucFirst(property);
MethodCallExpr setterExpr = modifyingExprs.stream().filter(m -> m.getNameAsString().equals(setter)).filter(m -> m.getArguments().size() == 1).findFirst().orElse(null);
Object value = null;
if (setterExpr != null) {
Expression arg = setterExpr.getArgument(0);
arg = stripEnclosedAndCast(arg);
if (arg.isLiteralExpr()) {
value = literalToValue(arg.asLiteralExpr());
} else if (arg.isNameExpr()) {
value = ((ImpactAnalysisRuleContext) context).getBindVariableLiteralMap().get(arg.asNameExpr().getName().asString());
} else if (arg.isObjectCreationExpr()) {
value = objectCreationExprToValue((ObjectCreationExpr) arg, context);
}
}
Method accessor = ClassUtils.getAccessor(modifiedClass, property);
if (accessor != null && Map.class.isAssignableFrom(accessor.getReturnType())) {
String mapName = property;
List<MethodCallExpr> mapPutExprs = consequenceExpr.findAll(MethodCallExpr.class).stream().filter(m -> isMapPutExpr(m, modifiedId, accessor.getName())).collect(Collectors.toList());
mapPutExprs.stream().forEach(expr -> {
String mapKey = getLiteralString(context, expr.getArgument(0));
Object mapValue = getLiteralValue(context, expr.getArgument(1));
action.addModifiedProperty(new ModifiedMapProperty(mapName, mapKey, mapValue));
});
} else {
action.addModifiedProperty(new ModifiedProperty(property, value));
}
}
}
return action;
}
use of org.drools.impact.analysis.model.right.ModifyAction 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);
}
}
}
Aggregations