/** * @inheritDoc When a new tuple is asserted into an AccumulateNode, do this: * <p>1. Select all matching objects from right memory 2. Execute the initialization code * using the tuple + matching objects 3. Execute the accumulation code for each combination of * tuple+object 4. Execute the return code 5. Create a new CalculatedObjectHandle for the * resulting object and add it to the tuple 6. Propagate the tuple * <p>The initialization, accumulation and return codes, in JBRules, are assembled into a * generated method code and called once for the whole match, as you can see below: * <p>Object result = this.accumulator.accumulate( ... ); */ public void assertLeftTuple( final LeftTuple leftTuple, final PropagationContext context, final InternalWorkingMemory workingMemory) { final AccumulateMemory memory = (AccumulateMemory) workingMemory.getNodeMemory(this); AccumulateContext accresult = new AccumulateContext(); boolean useLeftMemory = true; if (!this.tupleMemoryEnabled) { // This is a hack, to not add closed DroolsQuery objects Object object = ((InternalFactHandle) leftTuple.get(0)).getObject(); if (!(object instanceof DroolsQuery) || !((DroolsQuery) object).isOpen()) { useLeftMemory = false; } } if (useLeftMemory) { memory.betaMemory.getLeftTupleMemory().add(leftTuple); leftTuple.setObject(accresult); } accresult.context = this.accumulate.createContext(); this.accumulate.init(memory.workingMemoryContext, accresult.context, leftTuple, workingMemory); this.constraints.updateFromTuple(memory.betaMemory.getContext(), workingMemory, leftTuple); RightTupleMemory rightMemory = memory.betaMemory.getRightTupleMemory(); FastIterator rightIt = getRightIterator(rightMemory); for (RightTuple rightTuple = getFirstRightTuple(leftTuple, rightMemory, context, rightIt); rightTuple != null; rightTuple = (RightTuple) rightIt.next(rightTuple)) { InternalFactHandle handle = rightTuple.getFactHandle(); if (this.constraints.isAllowedCachedLeft(memory.betaMemory.getContext(), handle)) { // add a match addMatch( leftTuple, rightTuple, null, null, workingMemory, memory, accresult, useLeftMemory); } } this.constraints.resetTuple(memory.betaMemory.getContext()); if (accresult.getAction() == null) { evaluateResultConstraints( ActivitySource.LEFT, leftTuple, context, workingMemory, memory, accresult, useLeftMemory); } // else evaluation is already scheduled, so do nothing }