예제 #1
0
    public void rowUpdated(
        final Rule rule,
        final LeftTuple resultLeftTuple,
        final PropagationContext context,
        final InternalWorkingMemory workingMemory) {
      RightTuple rightTuple = (RightTuple) resultLeftTuple.getObject();
      if (rightTuple.getMemory() != null) {
        // Already sheduled as an insert
        return;
      }

      rightTuple.setLeftTuple(null);
      resultLeftTuple.setObject(null);

      // We need to recopy everything back again, as we don't know what has or hasn't changed
      QueryTerminalNode node = (QueryTerminalNode) resultLeftTuple.getLeftTupleSink();
      Declaration[] decls = node.getDeclarations();
      InternalFactHandle rootHandle = resultLeftTuple.get(0);
      DroolsQuery query = (DroolsQuery) rootHandle.getObject();

      Object[] objects = new Object[query.getElements().length];

      Declaration decl;
      for (int i = 0, length = this.variables.length; i < length; i++) {
        decl = decls[this.variables[i]];
        objects[this.variables[i]] =
            decl.getValue(workingMemory, resultLeftTuple.get(decl).getObject());
      }

      QueryElementFactHandle handle = (QueryElementFactHandle) rightTuple.getFactHandle();

      handle.setRecency(workingMemory.getFactHandleFactory().getAtomicRecency().incrementAndGet());
      handle.setObject(objects);

      if (query.isOpen()) {
        rightTuple.setLeftTuple(resultLeftTuple);
        resultLeftTuple.setObject(rightTuple);
      }

      // Don't need to recreate child links, as they will already be there form the first "add"

      RightTupleList rightTuples = query.getResultUpdateRightTupleList();
      if (rightTuples == null) {
        rightTuples = new RightTupleList();
        query.setResultUpdateRightTupleList(rightTuples);
        QueryResultUpdateAction updateAction =
            new QueryResultUpdateAction(context, this.factHandle, leftTuple, this.node);
        context.getQueue2().addFirst(updateAction);
      }
      rightTuples.add(rightTuple);
    }
예제 #2
0
  /**
   * Takes the asserted <code>ReteTuple</code> received from the <code>TupleSource</code> and
   * adapts it into a FactHandleImpl
   *
   * @param tuple
   *            The asserted <code>ReteTuple</code>.
   * @param context
   *             The <code>PropagationContext</code> of the <code>WorkingMemory<code> action.
   * @param workingMemory
   *            the <code>WorkingMemory</code> session.
   */
  public void assertLeftTuple(
      final LeftTuple leftTuple,
      final PropagationContext context,
      final InternalWorkingMemory workingMemory) {
    // creating a dummy fact handle to wrap the tuple
    final InternalFactHandle handle =
        workingMemory
            .getFactHandleFactory()
            .newFactHandle(
                leftTuple,
                workingMemory
                    .getObjectTypeConfigurationRegistry()
                    .getObjectTypeConf(context.getEntryPoint(), leftTuple),
                workingMemory,
                null);
    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) {
      final ObjectHashMap memory = (ObjectHashMap) workingMemory.getNodeMemory(this);
      // add it to a memory mapping
      memory.put(leftTuple, handle);
    }

    // propagate it
    this.sink.propagateAssertObject(handle, context, workingMemory);
  }
예제 #3
0
 public static Map<String, Object> valuesAsMap(
     Object object,
     InternalWorkingMemory workingMemory,
     LeftTuple leftTuple,
     Declaration[] declarations) {
   if (declarations.length == 0) {
     return null;
   }
   Map<String, Object> map = new HashMap<String, Object>();
   for (Declaration declaration : declarations) {
     if (leftTuple == null) {
       map.put(
           declaration.getBindingName(),
           declaration.getExtractor().getValue(workingMemory, object));
     } else {
       InternalFactHandle fact = leftTuple.get(declaration);
       map.put(
           declaration.getBindingName(),
           declaration
               .getExtractor()
               .getValue(workingMemory, fact != null ? fact.getObject() : object));
     }
   }
   return map;
 }
 public void updateFromTuple(InternalWorkingMemory workingMemory, LeftTuple tuple) {
   Object object = this.declaration.getValue(workingMemory, tuple.get(0).getObject());
   if (!(object instanceof Variable)) {
     this.variable = null;
     this.contextEntry.updateFromTuple(workingMemory, tuple);
   } else {
     this.variable = (Variable) object;
   }
 }
예제 #5
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
  }
예제 #6
0
    public void rowAdded(
        final Rule rule,
        LeftTuple resultLeftTuple,
        PropagationContext context,
        InternalWorkingMemory workingMemory) {

      QueryTerminalNode node = (QueryTerminalNode) resultLeftTuple.getLeftTupleSink();
      Declaration[] decls = node.getDeclarations();
      DroolsQuery query = (DroolsQuery) this.factHandle.getObject();
      Object[] objects = new Object[query.getElements().length];

      Declaration decl;
      for (int i = 0, length = this.variables.length; i < length; i++) {
        decl = decls[this.variables[i]];
        objects[this.variables[i]] =
            decl.getValue(workingMemory, resultLeftTuple.get(decl).getObject());
      }

      QueryElementFactHandle resultHandle =
          createQueryResultHandle(context, workingMemory, objects);

      RightTuple rightTuple = new RightTuple(resultHandle);
      if (query.isOpen()) {
        rightTuple.setLeftTuple(resultLeftTuple);
        resultLeftTuple.setObject(rightTuple);
      }

      this.node
          .getSinkPropagator()
          .createChildLeftTuplesforQuery(
              this.leftTuple,
              rightTuple,
              true, // this must always be true, otherwise we can't
              // find the child tuples to iterate for evaluating the query results
              query.isOpen());

      RightTupleList rightTuples = query.getResultInsertRightTupleList();
      if (rightTuples == null) {
        rightTuples = new RightTupleList();
        query.setResultInsertRightTupleList(rightTuples);
        QueryResultInsertAction evalAction =
            new QueryResultInsertAction(context, this.factHandle, leftTuple, this.node);
        context.getQueue2().addFirst(evalAction);
      }

      rightTuples.add(rightTuple);
    }
예제 #7
0
  public void modifyLeftTuple(
      LeftTuple leftTuple, PropagationContext context, InternalWorkingMemory workingMemory) {
    boolean executeAsOpenQuery = openQuery;
    if (executeAsOpenQuery) {
      // There is no point in doing an open query if the caller is a non-open query.
      Object object = ((InternalFactHandle) leftTuple.get(0)).getObject();
      if (object instanceof DroolsQuery && !((DroolsQuery) object).isOpen()) {
        executeAsOpenQuery = false;
      }
    }

    if (!executeAsOpenQuery) {
      // Was never open so execute as a retract + assert
      if (leftTuple.getFirstChild() != null) {
        this.sink.propagateRetractLeftTuple(leftTuple, context, workingMemory);
      }
      assertLeftTuple(leftTuple, context, workingMemory);
      return;
    }

    InternalFactHandle handle = (InternalFactHandle) leftTuple.getObject();
    DroolsQuery queryObject = (DroolsQuery) handle.getObject();
    if (queryObject.getAction() != null) {
      // we already have an insert scheduled for this query, but have re-entered it
      // do nothing
      return;
    }

    Object[] argTemplate =
        this.queryElement.getArgTemplate(); // an array of declr, variable and literals
    Object[] args =
        new Object[argTemplate.length]; // the actual args, to be created from the  template

    // first copy everything, so that we get the literals. We will rewrite the declarations and
    // variables next
    System.arraycopy(argTemplate, 0, args, 0, args.length);

    int[] declIndexes = this.queryElement.getDeclIndexes();

    for (int i = 0, length = declIndexes.length; i < length; i++) {
      Declaration declr = (Declaration) argTemplate[declIndexes[i]];

      Object tupleObject = leftTuple.get(declr).getObject();

      Object o;

      if (tupleObject instanceof DroolsQuery) {
        // If the query passed in a Variable, we need to use it
        ArrayElementReader arrayReader = (ArrayElementReader) declr.getExtractor();
        if (((DroolsQuery) tupleObject).getVariables()[arrayReader.getIndex()] != null) {
          o = Variable.v;
        } else {
          o = declr.getValue(workingMemory, tupleObject);
        }
      } else {
        o = declr.getValue(workingMemory, tupleObject);
      }

      args[declIndexes[i]] = o;
    }

    int[] varIndexes = this.queryElement.getVariableIndexes();
    for (int i = 0, length = varIndexes.length; i < length; i++) {
      if (argTemplate[varIndexes[i]] == Variable.v) {
        // Need to check against the arg template, as the varIndexes also includes re-declared
        // declarations
        args[varIndexes[i]] = Variable.v;
      }
    }

    queryObject.setParameters(args);
    ((UnificationNodeViewChangedEventListener) queryObject.getQueryResultCollector())
        .setVariables(varIndexes);

    QueryUpdateAction action = new QueryUpdateAction(context, handle, leftTuple, this);
    context.getQueue1().addFirst(action);
  }
예제 #8
0
  public DroolsQuery createDroolsQuery(
      LeftTuple leftTuple, InternalFactHandle handle, InternalWorkingMemory workingMemory) {
    Object[] argTemplate =
        this.queryElement.getArgTemplate(); // an array of declr, variable and literals
    Object[] args =
        new Object[argTemplate.length]; // the actual args, to be created from the  template

    // first copy everything, so that we get the literals. We will rewrite the declarations and
    // variables next
    System.arraycopy(argTemplate, 0, args, 0, args.length);

    int[] declIndexes = this.queryElement.getDeclIndexes();

    for (int i = 0, length = declIndexes.length; i < length; i++) {
      Declaration declr = (Declaration) argTemplate[declIndexes[i]];

      Object tupleObject = leftTuple.get(declr).getObject();

      Object o;

      if (tupleObject instanceof DroolsQuery) {
        // If the query passed in a Variable, we need to use it
        ArrayElementReader arrayReader = (ArrayElementReader) declr.getExtractor();
        if (((DroolsQuery) tupleObject).getVariables()[arrayReader.getIndex()] != null) {
          o = Variable.v;
        } else {
          o = declr.getValue(workingMemory, tupleObject);
        }
      } else {
        o = declr.getValue(workingMemory, tupleObject);
      }

      args[declIndexes[i]] = o;
    }

    int[] varIndexes = this.queryElement.getVariableIndexes();
    for (int i = 0, length = varIndexes.length; i < length; i++) {
      if (argTemplate[varIndexes[i]] == Variable.v) {
        // Need to check against the arg template, as the varIndexes also includes re-declared
        // declarations
        args[varIndexes[i]] = Variable.v;
      }
    }

    UnificationNodeViewChangedEventListener collector =
        new UnificationNodeViewChangedEventListener(
            leftTuple, varIndexes, this, this.tupleMemoryEnabled);

    boolean executeAsOpenQuery = openQuery;
    if (executeAsOpenQuery) {
      // There is no point in doing an open query if the caller is a non-open query.
      Object object = ((InternalFactHandle) leftTuple.get(0)).getObject();
      if (object instanceof DroolsQuery && !((DroolsQuery) object).isOpen()) {
        executeAsOpenQuery = false;
      }
    }

    DroolsQuery queryObject =
        new DroolsQuery(this.queryElement.getQueryName(), args, collector, executeAsOpenQuery);

    collector.setFactHandle(handle);

    handle.setObject(queryObject);

    leftTuple.setObject(handle); // so it can be retracted later and destroyed

    return queryObject;
  }