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); }
/** * 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); }
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; } }
/** * @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 }
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); }
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); }
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; }