Example #1
0
  /**
   * @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
  }