Home | History | Annotate | Download | only in transformer
      1 /*
      2  * Licensed to the Apache Software Foundation (ASF) under one
      3  * or more contributor license agreements. See the NOTICE file
      4  * distributed with this work for additional information
      5  * regarding copyright ownership. The ASF licenses this file
      6  * to you under the Apache License, Version 2.0 (the  "License");
      7  * you may not use this file except in compliance with the License.
      8  * You may obtain a copy of the License at
      9  *
     10  *     http://www.apache.org/licenses/LICENSE-2.0
     11  *
     12  * Unless required by applicable law or agreed to in writing, software
     13  * distributed under the License is distributed on an "AS IS" BASIS,
     14  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     15  * See the License for the specific language governing permissions and
     16  * limitations under the License.
     17  */
     18 /*
     19  * $Id: Counter.java 468645 2006-10-28 06:57:24Z minchau $
     20  */
     21 package org.apache.xalan.transformer;
     22 
     23 import javax.xml.transform.TransformerException;
     24 
     25 import org.apache.xalan.templates.ElemNumber;
     26 import org.apache.xml.dtm.DTM;
     27 import org.apache.xpath.NodeSetDTM;
     28 import org.apache.xpath.XPathContext;
     29 
     30 /**
     31  * A class that does incremental counting for support of xsl:number.
     32  * This class stores a cache of counted nodes (m_countNodes).
     33  * It tries to cache the counted nodes in document order...
     34  * the node count is based on its position in the cache list
     35  * @xsl.usage internal
     36  */
     37 public class Counter
     38 {
     39 
     40   /**
     41    * Set the maximum ammount the m_countNodes list can
     42    * grow to.
     43    */
     44   static final int MAXCOUNTNODES = 500;
     45 
     46   /**
     47    * The start count from where m_countNodes counts
     48    * from.  In other words, the count of a given node
     49    * in the m_countNodes vector is node position +
     50    * m_countNodesStartCount.
     51    */
     52   int m_countNodesStartCount = 0;
     53 
     54   /**
     55    * A vector of all nodes counted so far.
     56    */
     57   NodeSetDTM m_countNodes;
     58 
     59   /**
     60    * The node from where the counting starts.  This is needed to
     61    * find a counter if the node being counted is not immediatly
     62    * found in the m_countNodes vector.
     63    */
     64   int m_fromNode = DTM.NULL;
     65 
     66   /**
     67    * The owning xsl:number element.
     68    */
     69   ElemNumber m_numberElem;
     70 
     71   /**
     72    * Value to store result of last getCount call, for benifit
     73    * of returning val from CountersTable.getCounterByCounted,
     74    * who calls getCount.
     75    */
     76   int m_countResult;
     77 
     78   /**
     79    * Construct a counter object.
     80    *
     81    * @param numberElem The owning xsl:number element.
     82    * @param countNodes A vector of all nodes counted so far.
     83    *
     84    * @throws TransformerException
     85    */
     86   Counter(ElemNumber numberElem, NodeSetDTM countNodes) throws TransformerException
     87   {
     88     m_countNodes = countNodes;
     89     m_numberElem = numberElem;
     90   }
     91 
     92   /**
     93    * Construct a counter object.
     94    *
     95    * @param numberElem The owning xsl:number element.
     96    *
     97    * @throws TransformerException
     98    *
     99   Counter(ElemNumber numberElem) throws TransformerException
    100   {
    101     m_numberElem = numberElem;
    102   }*/
    103 
    104   /**
    105    * Try and find a node that was previously counted. If found,
    106    * return a positive integer that corresponds to the count.
    107    *
    108    * @param support The XPath context to use
    109    * @param node The node to be counted.
    110    *
    111    * @return The count of the node, or -1 if not found.
    112    */
    113   int getPreviouslyCounted(XPathContext support, int node)
    114   {
    115 
    116     int n = m_countNodes.size();
    117 
    118     m_countResult = 0;
    119 
    120     for (int i = n - 1; i >= 0; i--)
    121     {
    122       int countedNode = m_countNodes.elementAt(i);
    123 
    124       if (node == countedNode)
    125       {
    126 
    127         // Since the list is in backwards order, the count is
    128         // how many are in the rest of the list.
    129         m_countResult = i + 1 + m_countNodesStartCount;
    130 
    131         break;
    132       }
    133 
    134       DTM dtm = support.getDTM(countedNode);
    135 
    136       // Try to see if the given node falls after the counted node...
    137       // if it does, don't keep searching backwards.
    138       if (dtm.isNodeAfter(countedNode, node))
    139         break;
    140     }
    141 
    142     return m_countResult;
    143   }
    144 
    145   /**
    146    * Get the last node in the list.
    147    *
    148    * @return the last node in the list.
    149    */
    150   int getLast()
    151   {
    152 
    153     int size = m_countNodes.size();
    154 
    155     return (size > 0) ? m_countNodes.elementAt(size - 1) : DTM.NULL;
    156   }
    157 }
    158