public int countNode ( XPathContext support , ElemNumber numberElem , int node ) throws TransformerException { int count = 0 ; Vector counters = getCounters ( numberElem ) ; int nCounters = counters . size ( ) ; // XPath countMatchPattern = numberElem.getCountMatchPattern(support, node); // XPath fromMatchPattern = numberElem.m_fromMatchPattern; int target = numberElem . getTargetNode ( support , node ) ; if ( DTM . NULL != target ) { for ( int i = 0 ; i < nCounters ; i ++ ) { Counter counter = ( Counter ) counters . elementAt ( i ) ; count = counter . getPreviouslyCounted ( support , target ) ; if ( count > 0 ) return count ; } // In the loop below, we collect the nodes in backwards doc order, so // we don't have to do inserts, but then we store the nodes in forwards // document order, so we don't have to insert nodes into that list, // so that's what the appendBtoFList stuff is all about. In cases // of forward counting by one, this will mean a single node copy from // the backwards list (m_newFound) to the forwards list (counter.m_countNodes). count = 0 ; if ( m_newFound == null ) m_newFound = new NodeSetDTM ( support . getDTMManager ( ) ) ; for ( ; DTM . NULL != target ; target = numberElem . getPreviousNode ( support , target ) ) { // First time in, we should not have to check for previous counts, // since the original target node was already checked in the // block above. if ( 0 != count ) { for ( int i = 0 ; i < nCounters ; i ++ ) { Counter counter = ( Counter ) counters . elementAt ( i ) ; int cacheLen = counter . m_countNodes . size ( ) ; if ( ( cacheLen > 0 ) && ( counter . m_countNodes . elementAt ( cacheLen - 1 ) == target ) ) { count += ( cacheLen + counter . m_countNodesStartCount ) ; if ( cacheLen > 0 ) appendBtoFList ( counter . m_countNodes , m_newFound ) ; m_newFound . removeAllElements ( ) ; return count ; } } } m_newFound . addElement ( target ) ; count ++ ; } // If we got to this point, then we didn't find a counter, so make // one and add it to the list. Counter counter = new Counter ( numberElem , new NodeSetDTM ( support . getDTMManager ( ) ) ) ; m_countersMade ++ ; // for diagnostics appendBtoFList ( counter . m_countNodes , m_newFound ) ; m_newFound . removeAllElements ( ) ; counters . addElement ( counter ) ; } return count ; }
Count forward until the given node is found or until we have looked to the given amount .