use of org.drools.core.rule.Pattern in project drools by kiegroup.
the class CollectBuilder method build.
/**
* @inheritDoc
*/
public void build(final BuildContext context, final BuildUtils utils, final RuleConditionElement rce) {
boolean existSubNetwort = false;
final Collect collect = (Collect) rce;
context.pushRuleComponent(collect);
final List<BetaNodeFieldConstraint> resultBetaConstraints = context.getBetaconstraints();
final List<AlphaNodeFieldConstraint> resultAlphaConstraints = context.getAlphaConstraints();
final Pattern sourcePattern = collect.getSourcePattern();
// get builder for the pattern
final ReteooComponentBuilder builder = utils.getBuilderFor(sourcePattern);
// save tuple source and pattern offset for later if needed
final LeftTupleSource tupleSource = context.getTupleSource();
// builds the source pattern
builder.build(context, utils, sourcePattern);
// if object source is null, then we need to adapt tuple source into a subnetwork
if (context.getObjectSource() == null) {
RightInputAdapterNode riaNode = CoreComponentFactory.get().getNodeFactoryService().buildRightInputNode(context.getNextNodeId(), context.getTupleSource(), tupleSource, context);
// attach right input adapter node to convert tuple source into an object source
context.setObjectSource(utils.attachNode(context, riaNode));
// restore tuple source from before the start of the sub network
context.setTupleSource(tupleSource);
// create a tuple start equals constraint and set it in the context
final TupleStartEqualsConstraint constraint = TupleStartEqualsConstraint.getInstance();
final List<BetaNodeFieldConstraint> betaConstraints = new ArrayList<BetaNodeFieldConstraint>();
betaConstraints.add(constraint);
context.setBetaconstraints(betaConstraints);
existSubNetwort = true;
}
BetaConstraints binder = utils.createBetaNodeConstraint(context, context.getBetaconstraints(), false);
// indexing for the results should be always disabled
BetaConstraints resultBinder = utils.createBetaNodeConstraint(context, resultBetaConstraints, true);
// The node needs to declare the vars it returns
Pattern resultPattern = collect.getResultPattern();
Accumulate accumulate = new SingleAccumulate(sourcePattern, sourcePattern.getRequiredDeclarations(), new CollectAccumulator(collect, existSubNetwort));
AccumulateNode accNode = CoreComponentFactory.get().getNodeFactoryService().buildAccumulateNode(context.getNextNodeId(), context.getTupleSource(), context.getObjectSource(), resultAlphaConstraints.toArray(new AlphaNodeFieldConstraint[resultAlphaConstraints.size()]), // source binder
binder, resultBinder, accumulate, context);
context.setTupleSource(utils.attachNode(context, accNode));
// source pattern was bound, so nulling context
context.setObjectSource(null);
context.popRuleComponent();
}
use of org.drools.core.rule.Pattern in project drools by kiegroup.
the class KiePackagesBuilder method buildConditionalConsequence.
private ConditionalBranch buildConditionalConsequence(RuleContext ctx, ConditionalNamedConsequenceImpl consequence) {
// This makes the assumption the variable is for a pattern (not field) binding, and this binding must already exist.
// It's used for the implicit bindings
// The main issue with all of this, is it doesn't allow access to other previous variables. And it should work with
// with pattern bindings and field bindings. What if getVariables() returns an array.length > 1?
EvalCondition evalCondition;
if (consequence.getExpr() != null) {
Pattern pattern = ctx.getPattern(consequence.getExpr().getVariables()[0]);
if (pattern.getDeclaration() != null) {
// pattern has a root binding, so use that.
EvalExpression eval = new LambdaEvalExpression(pattern, consequence.getExpr());
evalCondition = new EvalCondition(eval, new Declaration[] { pattern.getDeclaration() });
} else {
// Pattern does not have root binding, so use field bindings.
Declaration[] declarations = pattern.getDeclarations().values().toArray(new Declaration[pattern.getDeclarations().size()]);
EvalExpression eval = new LambdaEvalExpression(declarations, consequence.getExpr());
evalCondition = new EvalCondition(eval, declarations);
}
} else {
evalCondition = new EvalCondition(LambdaEvalExpression.EMPTY, null);
}
return new ConditionalBranch(evalCondition, new NamedConsequence(consequence.getThenConsequence().getName(), consequence.getThenConsequence().isBreaking()), consequence.getElseBranch() != null ? buildConditionalConsequence(ctx, consequence.getElseBranch()) : null);
}
use of org.drools.core.rule.Pattern in project drools by kiegroup.
the class KiePackagesBuilder method getRequiredDeclarationsForAccumulate.
private Declaration[] getRequiredDeclarationsForAccumulate(RuleContext ctx, Binding binding, AccumulateFunction accFunction) {
if (binding != null || accFunction.getSource() == null) {
if (accFunction.getExternalVars() != null) {
Variable[] extVars = accFunction.getExternalVars();
Declaration[] bindingDeclaration = new Declaration[extVars.length];
for (int i = 0; i < extVars.length; i++) {
bindingDeclaration[i] = ctx.getDeclaration(extVars[i]);
}
return bindingDeclaration;
} else {
return new Declaration[0];
}
}
if (accFunction.getSource() instanceof Variable) {
Pattern pattern = ctx.getPattern((Variable) accFunction.getSource());
return pattern == null || pattern.getDeclaration() == null ? new Declaration[0] : new Declaration[] { pattern.getDeclaration() };
} else {
return new Declaration[0];
}
}
use of org.drools.core.rule.Pattern in project drools by kiegroup.
the class KiePackagesBuilder method addQueryPattern.
private void addQueryPattern(Query query, QueryImpl queryImpl, RuleContext ctx) {
Pattern pattern = new Pattern(ctx.getNextPatternIndex(), // tupleIndex is 0 by default
0, // patternIndex is 0 by default
0, ClassObjectType.DroolsQuery_ObjectType, null);
InternalReadAccessor extractor = new LambdaReadAccessor(DroolsQuery.class, q -> ((DroolsQuery) q).getName());
QueryNameConstraint constraint = new QueryNameConstraint(extractor, query.getName());
pattern.addConstraint(constraint);
queryImpl.getLhs().addChild(pattern);
Variable<?>[] args = query.getArguments();
Declaration[] declarations = new Declaration[args.length];
for (int i = 0; i < args.length; i++) {
int index = i;
LambdaReadAccessor accessor = new LambdaReadAccessor(index, args[index].getType(), obj -> ((DroolsQuery) obj).getElements()[index]);
declarations[i] = new Declaration(args[i].getName(), accessor, pattern, false);
pattern.addDeclaration(declarations[i]);
ctx.addQueryDeclaration(args[i], declarations[i]);
}
queryImpl.setParameters(declarations);
}
use of org.drools.core.rule.Pattern in project drools by kiegroup.
the class KiePackagesBuilder method buildAccumulate.
private Accumulate buildAccumulate(RuleContext ctx, AccumulatePattern accPattern, RuleConditionElement source, Pattern pattern, Set<String> usedVariableName, Collection<Binding> bindings) {
boolean isGroupBy = accPattern instanceof GroupByPattern;
AccumulateFunction[] accFunctions = accPattern.getAccumulateFunctions();
Declaration groupByDeclaration = null;
Class selfType = (isGroupBy || accFunctions.length > 1) ? Object[].class : accFunctions[0].getResult().getType();
InternalReadAccessor selfReader = new SelfReferenceClassFieldReader(selfType);
int arrayIndexOffset = 0;
if (isGroupBy) {
if (accFunctions.length == 0) {
// In this situation the result is anonymous, but it still uses element position 0.
// For this reason the i used to populate hte array index must be offset by 1.
accFunctions = new AccumulateFunction[] { new AccumulateFunction(null, CountAccumulateFunction::new) };
arrayIndexOffset = 1;
}
// GroupBy key is always the last element in the result array
Variable groupVar = ((GroupByPattern<?, ?>) accPattern).getVarKey();
groupByDeclaration = new Declaration(groupVar.getName(), new ArrayElementReader(selfReader, accFunctions.length, groupVar.getType()), pattern, true);
pattern.addDeclaration(groupByDeclaration);
}
Accumulate accumulate;
Accumulator[] accumulators = new Accumulator[accFunctions.length];
List<Declaration> requiredDeclarationList = new ArrayList<>();
for (int i = 0; i < accFunctions.length; i++) {
Variable boundVar = processFunctions(ctx, accPattern, source, pattern, usedVariableName, bindings, isGroupBy, accFunctions[i], selfReader, accumulators, requiredDeclarationList, arrayIndexOffset, i);
if (isGroupBy) {
ctx.addGroupByDeclaration(((GroupByPattern) accPattern).getVarKey(), groupByDeclaration);
}
}
if (accFunctions.length == 1) {
accumulate = new SingleAccumulate(source, requiredDeclarationList.toArray(new Declaration[requiredDeclarationList.size()]), accumulators[0]);
} else {
if (source instanceof Pattern) {
requiredDeclarationList.forEach(((Pattern) source)::addDeclaration);
}
accumulate = new MultiAccumulate(source, new Declaration[0], accumulators, // if this is a groupby +1 for the key
accumulators.length + ((isGroupBy) ? 1 : 0));
}
if (isGroupBy) {
GroupByPatternImpl groupBy = (GroupByPatternImpl) accPattern;
Declaration[] groupingDeclarations = new Declaration[groupBy.getVars().length];
for (int i = 0; i < groupBy.getVars().length; i++) {
groupingDeclarations[i] = ctx.getDeclaration(groupBy.getVars()[i]);
}
accumulate = new LambdaGroupByAccumulate(accumulate, groupingDeclarations, groupBy.getGroupingFunction());
}
for (Variable boundVar : accPattern.getBoundVariables()) {
ctx.addAccumulateSource(boundVar, accumulate);
}
return accumulate;
}
Aggregations