use of org.drools.model.patterns.CompositePatterns in project drools by kiegroup.
the class ViewFlowBuilder method viewItem2Condition.
private static Condition viewItem2Condition(ViewItem viewItem, Condition condition, BuildContext ctx) {
if (viewItem instanceof AbstractExprViewItem) {
((PatternImpl) condition).addWatchedProps(((AbstractExprViewItem) viewItem).getWatchedProps());
}
if (viewItem instanceof Expr1ViewItemImpl) {
Expr1ViewItemImpl expr = (Expr1ViewItemImpl) viewItem;
if (expr.getPredicate() != null) {
((PatternImpl) condition).addConstraint(new SingleConstraint1(expr));
}
return condition;
}
if (viewItem instanceof ExprNViewItem) {
((PatternImpl) condition).addConstraint(SingleConstraint.createConstraint((ExprNViewItem) viewItem));
return condition;
}
if (viewItem instanceof TemporalExprViewItem) {
TemporalExprViewItem expr = (TemporalExprViewItem) viewItem;
((PatternImpl) condition).addConstraint(new TemporalConstraint(expr));
return condition;
}
if (viewItem instanceof AccumulateExprViewItem) {
AccumulateExprViewItem acc = (AccumulateExprViewItem) viewItem;
for (AccumulateFunction accFunc : acc.getAccumulateFunctions()) {
ctx.usedVars.add(accFunc.getVariable());
}
final Condition newCondition = acc.getExpr() instanceof InputViewItem ? condition : viewItem2Condition(acc.getExpr(), condition, ctx);
return new AccumulatePatternImpl(newCondition, acc.getAccumulateFunctions());
}
if (viewItem instanceof CombinedExprViewItem) {
CombinedExprViewItem combined = (CombinedExprViewItem) viewItem;
CompositePatterns patterns = viewItems2Condition(new BuildContext(ctx, combined.getExpressions()), combined.getType(), false);
return patterns.getSubConditions().size() == 1 ? patterns.getSubConditions().get(0) : patterns;
}
throw new UnsupportedOperationException("Unknown ViewItem: " + viewItem);
}
use of org.drools.model.patterns.CompositePatterns in project drools by kiegroup.
the class ViewFlowBuilder method viewItems2Condition.
private static CompositePatterns viewItems2Condition(BuildContext ctx, Condition.Type type, boolean topLevel) {
List<Condition> conditions = new ArrayList<>();
Map<Variable<?>, Condition> conditionMap = new HashMap<>();
Map<String, Consequence> consequences = topLevel ? new LinkedHashMap<>() : null;
Iterator<RuleItem> ruleItemIterator = ctx.ruleItems.iterator();
while (ruleItemIterator.hasNext()) {
Map<Variable<?>, InputViewItemImpl<?>> scopedInputs = type.createsScope() ? new LinkedHashMap<>(ctx.inputs) : ctx.inputs;
RuleItem ruleItem = ruleItemIterator.next();
if (ruleItem instanceof FixedValueItem) {
conditions.add(new EvalImpl(((FixedValueItem) ruleItem).isValue()));
continue;
}
if (ruleItem instanceof Consequence) {
if (!topLevel) {
throw new IllegalStateException("A consequence can be only a top level item");
}
Consequence consequence = (Consequence) ruleItem;
String name = ruleItemIterator.hasNext() ? generateName("consequence") : RuleImpl.DEFAULT_CONSEQUENCE_NAME;
consequences.put(name, consequence);
conditions.add(new NamedConsequenceImpl(name, consequence.isBreaking()));
continue;
}
if (ruleItem instanceof ConditionalConsequence) {
if (!topLevel) {
throw new IllegalStateException("A consequence can be only a top level item");
}
conditions.add(createConditionalNamedConsequence(consequences, (ConditionalConsequence) ruleItem));
continue;
}
ViewItem viewItem = (ViewItem) ruleItem;
if (viewItem instanceof CombinedExprViewItem) {
CombinedExprViewItem combined = (CombinedExprViewItem) viewItem;
conditions.add(viewItems2Condition(new BuildContext(ctx, combined.getExpressions(), scopedInputs), combined.getType(), false));
continue;
}
if (viewItem instanceof QueryCallViewItem) {
QueryCallViewItem query = ((QueryCallViewItem) viewItem);
for (Argument arg : query.getArguments()) {
if (arg instanceof Variable) {
ctx.usedVars.add(((Variable) arg));
}
}
conditions.add(new QueryCallPattern(query));
continue;
}
if (viewItem instanceof Binding) {
Binding bindViewItem = (Binding) viewItem;
PatternImpl pattern = (PatternImpl) conditionMap.get(bindViewItem.getInputVariable());
if (pattern == null) {
// This should probably be the bindViewItem.getBoundVariable() instead of the input
// as the input variables can be many
pattern = new PatternImpl(bindViewItem.getInputVariable());
pattern.addWatchedProps(bindViewItem.getWatchedProps());
ctx.usedVars.add(bindViewItem.getInputVariable());
conditions.add(pattern);
conditionMap.put(bindViewItem.getInputVariable(), pattern);
}
pattern.addBinding(bindViewItem);
ctx.usedVars.add(viewItem.getFirstVariable());
ctx.addBinding(bindViewItem);
scopedInputs.putIfAbsent(viewItem.getFirstVariable(), (InputViewItemImpl) input(viewItem.getFirstVariable()));
continue;
}
Variable<?> patterVariable = findPatterVariable(viewItem, scopedInputs.keySet());
if (viewItem instanceof InputViewItemImpl) {
scopedInputs.put(patterVariable, (InputViewItemImpl) viewItem);
PatternImpl condition = new PatternImpl(patterVariable);
condition.addWatchedProps(((InputViewItemImpl) viewItem).getWatchedProps());
conditions.add(condition);
conditionMap.put(patterVariable, condition);
ctx.usedVars.add(patterVariable);
continue;
}
if (viewItem instanceof ExistentialExprViewItem) {
ExistentialExprViewItem existential = ((ExistentialExprViewItem) viewItem);
if (patterVariable != null && !existential.isQueryExpression()) {
registerInputsFromViewItem(existential.getExpression(), conditionMap, scopedInputs, patterVariable);
}
Condition condition = new PatternImpl(patterVariable, SingleConstraint.TRUE, ctx.bindings.get(patterVariable));
conditions.add(new ExistentialPatternImpl(viewItem2Condition(existential.getExpression(), condition, new BuildContext(ctx, new LinkedHashMap<>())), existential.getType()));
continue;
}
if (ruleItem instanceof ExprViewItem && ctx.boundVars.contains(patterVariable)) {
conditions.add(new EvalImpl(createConstraint((ExprViewItem) ruleItem)));
continue;
}
ctx.usedVars.add(patterVariable);
Condition condition;
if (type == Type.AND) {
condition = conditionMap.get(patterVariable);
if (condition == null) {
condition = new PatternImpl(patterVariable, SingleConstraint.TRUE, ctx.bindings.get(patterVariable));
conditions.add(condition);
if (!(viewItem instanceof AccumulateExprViewItem)) {
conditionMap.put(patterVariable, condition);
}
scopedInputs.putIfAbsent(patterVariable, (InputViewItemImpl) input(patterVariable));
}
} else {
condition = new PatternImpl(patterVariable);
conditions.add(condition);
}
addInputFromVariableSource(scopedInputs, patterVariable);
registerInputsFromViewItem(viewItem, conditionMap, scopedInputs, null);
Condition modifiedPattern = viewItem2Condition(viewItem, condition, new BuildContext(ctx, scopedInputs));
conditions.set(conditions.indexOf(condition), modifiedPattern);
if (type == Type.AND && !(viewItem instanceof AccumulateExprViewItem)) {
conditionMap.put(patterVariable, modifiedPattern);
}
}
return new CompositePatterns(type, conditions, ctx.usedVars, consequences);
}
use of org.drools.model.patterns.CompositePatterns in project drools by kiegroup.
the class KiePackagesBuilder method addInnerBindings.
private void addInnerBindings(Collection<Binding> bindings, AccumulateFunction[] accumulateFunctions, Condition condition) {
List<org.drools.model.Declaration> functionArgList = Arrays.stream(accumulateFunctions).map(function -> function.getSource()).filter(org.drools.model.Declaration.class::isInstance).map(org.drools.model.Declaration.class::cast).collect(Collectors.toList());
if (condition instanceof CompositePatterns) {
CompositePatterns compositePatterns = (CompositePatterns) condition;
for (Condition c : compositePatterns.getSubConditions()) {
Variable<?>[] boundVariables = c.getBoundVariables();
Arrays.stream(boundVariables).filter(org.drools.model.Declaration.class::isInstance).map(org.drools.model.Declaration.class::cast).filter(decl -> functionArgList.contains(decl)).forEach(decl -> bindings.add(new SelfPatternBiding<>((org.drools.model.Declaration) decl)));
}
}
}
use of org.drools.model.patterns.CompositePatterns in project drools by kiegroup.
the class KiePackagesBuilder method buildAccumulate.
private RuleConditionElement buildAccumulate(RuleContext ctx, GroupElement group, AccumulatePattern accumulatePattern) {
Pattern pattern = null;
boolean isGroupBy = accumulatePattern instanceof GroupByPattern;
if (accumulatePattern.getAccumulateFunctions() != null) {
if (!isGroupBy && accumulatePattern.getAccumulateFunctions().length == 1) {
// non groupby with single accumulates can be optimized to directly return the result, rather than place in an array of 1
pattern = ctx.getPattern(accumulatePattern.getAccumulateFunctions()[0].getResult());
} else if (accumulatePattern.getAccumulateFunctions().length > 0 && ctx.getPattern(accumulatePattern.getAccumulateFunctions()[0].getResult()) != null) {
// Illegal executable model. Cannot have groupby or multi accumulate mapped to a single result object.
throw new RuntimeException("Only single accumulate functions, with no group by can optimize the result pattern to be the function return value");
}
}
boolean existingPattern = pattern != null;
if (!existingPattern) {
ObjectType type = !isGroupBy && accumulatePattern.getAccumulateFunctions().length == 1 ? new ClassObjectType(accumulatePattern.getAccumulateFunctions()[0].getResult().getType()) : // groupby or multi function accumulate
JAVA_CLASS_ARRAY_TYPE;
pattern = new Pattern(ctx.getNextPatternIndex(), type);
}
PatternImpl<?> sourcePattern = (PatternImpl<?>) accumulatePattern.getPattern();
Set<String> usedVariableName = new LinkedHashSet<>();
if (sourcePattern != null) {
for (Variable v : sourcePattern.getInputVariables()) {
usedVariableName.add(v.getName());
}
}
RuleConditionElement source;
if (accumulatePattern.isQuerySource()) {
source = buildQueryPattern(ctx, ((QueryCallPattern) accumulatePattern.getCondition()));
} else if (accumulatePattern.isCompositePatterns()) {
CompositePatterns compositePatterns = (CompositePatterns) accumulatePattern.getCondition();
GroupElement allSubConditions = new GroupElement(conditionToGroupElementType(compositePatterns.getType()));
for (Condition c : compositePatterns.getSubConditions()) {
recursivelyAddConditions(ctx, group, allSubConditions, c);
}
source = allSubConditions.getChildren().size() == 1 ? allSubConditions.getChildren().get(0) : allSubConditions;
} else {
source = buildPattern(ctx, group, accumulatePattern);
}
Collection<Binding> bindings = new ArrayList<>();
if (sourcePattern != null) {
bindings.addAll(sourcePattern.getBindings());
bindings.add(new SelfPatternBiding<>(sourcePattern.getPatternVariable()));
} else {
// No pattern is associated. It likely uses inner bindings
addInnerBindings(bindings, accumulatePattern.getAccumulateFunctions(), accumulatePattern.getCondition());
}
pattern.setSource(buildAccumulate(ctx, accumulatePattern, source, pattern, usedVariableName, bindings));
return existingPattern ? null : pattern;
}
use of org.drools.model.patterns.CompositePatterns in project drools by kiegroup.
the class KiePackagesBuilder method recursivelyAddConditions.
private void recursivelyAddConditions(RuleContext ctx, GroupElement group, GroupElement allSubConditions, Condition c) {
if (c instanceof CompositePatterns) {
c.getSubConditions().forEach(sc -> recursivelyAddConditions(ctx, group, allSubConditions, sc));
} else if (c instanceof ExistentialPatternImpl) {
if (c.getType() == Condition.Type.FORALL) {
allSubConditions.addChild(buildForAll(ctx, allSubConditions, c));
} else {
GroupElement existGroupElement = new GroupElement(conditionToGroupElementType(c.getType()));
allSubConditions.addChild(existGroupElement);
recursivelyAddConditions(ctx, existGroupElement, existGroupElement, c.getSubConditions().iterator().next());
}
} else if (c instanceof PatternImpl) {
org.drools.model.Pattern pattern = (org.drools.model.Pattern<?>) c;
RuleConditionElement rce = buildPattern(ctx, allSubConditions, pattern);
if (ctx.getAccumulateSource(pattern.getPatternVariable()) == null) {
allSubConditions.addChild(rce);
}
} else if (c instanceof AccumulatePattern) {
RuleConditionElement rce = buildAccumulate(ctx, group, (AccumulatePattern) c);
if (rce != null) {
allSubConditions.addChild(rce);
}
} else if (c instanceof EvalImpl) {
allSubConditions.addChild(buildEval(ctx, (EvalImpl) c));
}
}
Aggregations