⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 joinnode.java

📁 jboss规则引擎
💻 JAVA
📖 第 1 页 / 共 2 页
字号:
     *            The <code>PropagationContext</code>
     * @param workingMemory
     *            The working memory seesion.
     */
    public void retractTuple(final ReteTuple leftTuple,
                             final PropagationContext context,
                             final ReteooWorkingMemory workingMemory) {

        final BetaMemory memory = (BetaMemory) workingMemory.getNodeMemory( this );
        memory.remove( workingMemory,
                       leftTuple );

        final Map matches = leftTuple.getTupleMatches();

        if ( !matches.isEmpty() ) {
            for ( final Iterator it = matches.values().iterator(); it.hasNext(); ) {
                final TupleMatch tupleMatch = (TupleMatch) it.next();
                tupleMatch.getObjectMatches().remove( tupleMatch );
                propagateRetractTuple( tupleMatch,
                                       context,
                                       workingMemory );
            }
        }
    }

    public void modifyTuple(final ReteTuple leftTuple,
                            final PropagationContext context,
                            final ReteooWorkingMemory workingMemory) {
        final BetaMemory memory = (BetaMemory) workingMemory.getNodeMemory( this );

        // We remove the tuple as now its modified it needs to go to the top of
        // the stack, which is added back in else where
        memory.remove( workingMemory,
                       leftTuple );

        final Map matches = leftTuple.getTupleMatches();

        if ( matches.isEmpty() ) {
            // No child propagations, so try as a new assert, will ensure the
            // tuple is added to the top of the memory
            assertTuple( leftTuple,
                         context,
                         workingMemory );
        } else {
            // TIRELLI's NOTE: the following is necessary because in case memory  
            // indexing is enabled, the loop over right objects may skip some of the
            // previously matched objects
            final Map oldMatches = new HashMap(matches);
            leftTuple.getTupleMatches().clear();
            
            // ensure the tuple is at the top of the memory
            memory.add( workingMemory,
                        leftTuple );
            final BetaNodeBinder binder = getJoinNodeBinder();

            for ( final Iterator rightIterator = memory.rightObjectIterator( workingMemory,
                                                                             leftTuple ); rightIterator.hasNext(); ) {
                final ObjectMatches objectMatches = (ObjectMatches) rightIterator.next();
                final DefaultFactHandle handle = objectMatches.getFactHandle();

                if ( binder.isAllowed( handle,
                                       leftTuple,
                                       workingMemory ) ) {
                    TupleMatch tupleMatch = (TupleMatch) oldMatches.remove( handle );
                    if ( tupleMatch != null ) {
                        // ensures tupleMatch will be in the appropriate order
                        objectMatches.remove( tupleMatch );
                        objectMatches.add( tupleMatch );
                        leftTuple.addTupleMatch( handle, tupleMatch );
                        
                        propagateModifyTuple( tupleMatch,
                                              context,
                                              workingMemory );
                    } else {
                        tupleMatch = objectMatches.add( leftTuple );
                        leftTuple.addTupleMatch( handle,
                                                 tupleMatch );
                        propagateAssertTuple( new ReteTuple( leftTuple,
                                                             handle ),
                                              tupleMatch,
                                              context,
                                              workingMemory );
                    }

                } else {
                    final TupleMatch tupleMatch = leftTuple.removeMatch( handle );
                    if ( tupleMatch != null ) {
                        oldMatches.remove( handle );
                        objectMatches.remove( tupleMatch );
                        propagateRetractTuple( tupleMatch,
                                               context,
                                               workingMemory );
                    }
                }
            }
            
            // TIRELLI's NOTE: the following is necessary because in case memory  
            // indexing is enabled, the loop over right objects may skip some of the
            // previously matched objects
            if(!oldMatches.isEmpty()) {
                for(Iterator it = oldMatches.values().iterator(); it.hasNext(); ) {
                    final TupleMatch tupleMatch = (TupleMatch) it.next();
                    tupleMatch.getObjectMatches().remove( tupleMatch );
                    propagateRetractTuple( tupleMatch,
                                           context,
                                           workingMemory );
                }
            }
        }
    }

    public void modifyObject(final DefaultFactHandle handle,
                             final PropagationContext context,
                             final ReteooWorkingMemory workingMemory) {
        final BetaMemory memory = (BetaMemory) workingMemory.getNodeMemory( this );
        
        // Remove and re-add the FactHandle from memory, ensures that its the latest on the list
        final ObjectMatches objectMatches = memory.remove( workingMemory,
                                                           handle );
        memory.add( workingMemory,
                    objectMatches );

        TupleMatch tupleMatch = objectMatches.getFirstTupleMatch();
        final BetaNodeBinder binder = getJoinNodeBinder();

        for ( final Iterator it = memory.leftTupleIterator( workingMemory,
                                                            handle ); it.hasNext(); ) {
            final ReteTuple leftTuple = (ReteTuple) it.next();
            if ( tupleMatch != null && tupleMatch.getTuple() == leftTuple ) {
                // has previous match so need to decide whether to continue
                // modify or retract    

                // Need to get the "next" tuple match before messing with references 
                // using objectMatches.remove( tupleMatch ); for instance.
                TupleMatch nextTupleMatch = (TupleMatch) tupleMatch.getNext();
                if ( binder.isAllowed( handle,
                                       leftTuple,
                                       workingMemory ) ) {
                    propagateModifyTuple( tupleMatch,
                                          context,
                                          workingMemory );
                } else {
                    leftTuple.removeMatch( handle );
                    objectMatches.remove( tupleMatch );
                    propagateRetractTuple( tupleMatch,
                                           context,
                                           workingMemory );
                }
                tupleMatch = nextTupleMatch;
            } else {
                // no previous join, so attempt join now
                final TupleMatch newTupleMatch = attemptJoin( leftTuple,
                                                              handle,
                                                              objectMatches,
                                                              binder,
                                                              workingMemory );
                if ( newTupleMatch != null ) {
                    propagateAssertTuple( new ReteTuple( leftTuple,
                                                         handle ),
                                          newTupleMatch,
                                          context,
                                          workingMemory );
                }
            }
        }
    }

    /* (non-Javadoc)
     * @see org.drools.reteoo.BaseNode#updateNewNode(org.drools.reteoo.WorkingMemoryImpl, org.drools.spi.PropagationContext)
     */
    public void updateNewNode(final ReteooWorkingMemory workingMemory,
                              final PropagationContext context) {
        this.attachingNewNode = true;

        final BetaMemory memory = (BetaMemory) workingMemory.getNodeMemory( this );

        for ( final Iterator it = memory.getRightObjectMemory().iterator(); it.hasNext(); ) {
            final ObjectMatches objectMatches = (ObjectMatches) it.next();
            final DefaultFactHandle handle = objectMatches.getFactHandle();
            for ( TupleMatch tupleMatch = objectMatches.getFirstTupleMatch(); tupleMatch != null; tupleMatch = (TupleMatch) tupleMatch.getNext() ) {
                final ReteTuple tuple = new ReteTuple( tupleMatch.getTuple(),
                                                       handle );
                final TupleSink sink = (TupleSink) this.tupleSinks.get( this.tupleSinks.size() - 1 );
                if ( sink != null ) {
                    tupleMatch.addJoinedTuple( tuple );
                    sink.assertTuple( tuple,
                                      context,
                                      workingMemory );
                } else {
                    throw new RuntimeException( "Possible BUG: trying to propagate an assert to a node that was the last added node" );
                }
            }
        }

        this.attachingNewNode = false;
    }

    /**
     * @inheritDoc
     */
    public List getPropagatedTuples(final ReteooWorkingMemory workingMemory,
                                    final TupleSink sink) {
        final BetaMemory memory = (BetaMemory) workingMemory.getNodeMemory( this );
        final int index = this.getTupleSinks().indexOf( sink );
        final List propagatedTuples = new ArrayList();

        for ( final Iterator it = memory.getRightObjectMemory().iterator(); it.hasNext(); ) {
            final ObjectMatches objectMatches = (ObjectMatches) it.next();
            for ( TupleMatch tupleMatch = objectMatches.getFirstTupleMatch(); tupleMatch != null; tupleMatch = (TupleMatch) tupleMatch.getNext() ) {
                propagatedTuples.add( tupleMatch.getJoinedTuples().get( index ) );
            }
        }
        return propagatedTuples;
    }

}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -