use of org.drools.impact.analysis.model.left.Pattern in project drools by kiegroup.
the class ModelToGraphConverter method generateGraphAnalysis.
private GraphAnalysis generateGraphAnalysis(AnalysisModel model) {
GraphAnalysis graphAnalysis = new GraphAnalysis();
for (Package pkg : model.getPackages()) {
List<Rule> rules = pkg.getRules();
for (Rule rule : rules) {
graphAnalysis.addNode(new Node(rule));
LeftHandSide lhs = rule.getLhs();
List<Pattern> patterns = lhs.getPatterns();
for (Pattern pattern : patterns) {
Class<?> patternClass = pattern.getPatternClass();
Collection<String> reactOnFields = pattern.getReactOnFields();
if (pattern.isClassReactive()) {
// Pattern which cannot analyze reactivity (e.g. Person(blackBoxMethod())) so reacts to all properties
graphAnalysis.addClassReactiveRule(patternClass, rule, pattern.isPositive());
} else if (reactOnFields.isEmpty()) {
// Pattern without constraint (e.g. Person()) so doesn't react to properties (only react to insert/delete)
graphAnalysis.addInsertReactiveRule(patternClass, rule, pattern.isPositive());
} else {
for (String field : reactOnFields) {
graphAnalysis.addPropertyReactiveRule(patternClass, field, rule, pattern.isPositive());
}
}
}
}
}
return graphAnalysis;
}
use of org.drools.impact.analysis.model.left.Pattern in project drools by kiegroup.
the class LhsParser method parsePattern.
private Pattern parsePattern(RuleContext context, PatternDescr patternDescr, boolean positive) {
if (context.getRuleUnitDescr() != null) {
patternDescr = PatternUtil.normalizeOOPathPattern(patternDescr, context);
}
String type = patternDescr.getObjectType();
Class<?> patternClass;
try {
patternClass = pkgRegistry.getTypeResolver().resolveType(type);
} catch (ClassNotFoundException e) {
throw new RuntimeException(e);
}
Pattern pattern = new Pattern(patternClass, positive);
if (patternDescr.getIdentifier() != null) {
context.addDeclaration(patternDescr.getIdentifier(), patternClass);
}
ConstraintParser constraintParser = ConstraintParser.defaultConstraintParser(context, packageModel);
for (BaseDescr constraintDescr : patternDescr.getConstraint().getDescrs()) {
parseConstraint(context, patternDescr, pattern, constraintParser, constraintDescr);
}
return pattern;
}
use of org.drools.impact.analysis.model.left.Pattern 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.Pattern 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