1. /*
  2. * The Apache Software License, Version 1.1
  3. *
  4. *
  5. * Copyright (c) 1999 The Apache Software Foundation. All rights
  6. * reserved.
  7. *
  8. * Redistribution and use in source and binary forms, with or without
  9. * modification, are permitted provided that the following conditions
  10. * are met:
  11. *
  12. * 1. Redistributions of source code must retain the above copyright
  13. * notice, this list of conditions and the following disclaimer.
  14. *
  15. * 2. Redistributions in binary form must reproduce the above copyright
  16. * notice, this list of conditions and the following disclaimer in
  17. * the documentation and/or other materials provided with the
  18. * distribution.
  19. *
  20. * 3. The end-user documentation included with the redistribution,
  21. * if any, must include the following acknowledgment:
  22. * "This product includes software developed by the
  23. * Apache Software Foundation (http://www.apache.org/)."
  24. * Alternately, this acknowledgment may appear in the software itself,
  25. * if and wherever such third-party acknowledgments normally appear.
  26. *
  27. * 4. The names "Xalan" and "Apache Software Foundation" must
  28. * not be used to endorse or promote products derived from this
  29. * software without prior written permission. For written
  30. * permission, please contact apache@apache.org.
  31. *
  32. * 5. Products derived from this software may not be called "Apache",
  33. * nor may "Apache" appear in their name, without prior written
  34. * permission of the Apache Software Foundation.
  35. *
  36. * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
  37. * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
  38. * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  39. * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
  40. * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  41. * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
  42. * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
  43. * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
  44. * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
  45. * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
  46. * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  47. * SUCH DAMAGE.
  48. * ====================================================================
  49. *
  50. * This software consists of voluntary contributions made by many
  51. * individuals on behalf of the Apache Software Foundation and was
  52. * originally based on software copyright (c) 1999, Lotus
  53. * Development Corporation., http://www.lotus.com. For more
  54. * information on the Apache Software Foundation, please see
  55. * <http://www.apache.org/>.
  56. */
  57. package org.apache.xalan.transformer;
  58. //import org.w3c.dom.Node;
  59. import org.apache.xml.dtm.DTM;
  60. import org.apache.xml.utils.NodeVector;
  61. import org.apache.xpath.NodeSetDTM; // for isNodeAfter support
  62. import org.apache.xpath.XPathContext;
  63. import javax.xml.transform.TransformerException;
  64. import org.apache.xpath.NodeSetDTM;
  65. import org.apache.xpath.XPath;
  66. import org.apache.xalan.templates.ElemNumber;
  67. /**
  68. * <meta name="usage" content="internal"/>
  69. * A class that does incremental counting for support of xsl:number.
  70. * This class stores a cache of counted nodes (m_countNodes).
  71. * It tries to cache the counted nodes in document order...
  72. * the node count is based on its position in the cache list
  73. */
  74. public class Counter
  75. {
  76. /**
  77. * Set the maximum ammount the m_countNodes list can
  78. * grow to.
  79. */
  80. static final int MAXCOUNTNODES = 500;
  81. /**
  82. * The start count from where m_countNodes counts
  83. * from. In other words, the count of a given node
  84. * in the m_countNodes vector is node position +
  85. * m_countNodesStartCount.
  86. */
  87. int m_countNodesStartCount = 0;
  88. /**
  89. * A vector of all nodes counted so far.
  90. */
  91. NodeSetDTM m_countNodes;
  92. /**
  93. * The node from where the counting starts. This is needed to
  94. * find a counter if the node being counted is not immediatly
  95. * found in the m_countNodes vector.
  96. */
  97. int m_fromNode = DTM.NULL;
  98. /**
  99. * The owning xsl:number element.
  100. */
  101. ElemNumber m_numberElem;
  102. /**
  103. * Value to store result of last getCount call, for benifit
  104. * of returning val from CountersTable.getCounterByCounted,
  105. * who calls getCount.
  106. */
  107. int m_countResult;
  108. /**
  109. * Construct a counter object.
  110. *
  111. * @param numberElem The owning xsl:number element.
  112. * @param countNodes A vector of all nodes counted so far.
  113. *
  114. * @throws TransformerException
  115. */
  116. Counter(ElemNumber numberElem, NodeSetDTM countNodes) throws TransformerException
  117. {
  118. m_countNodes = countNodes;
  119. m_numberElem = numberElem;
  120. }
  121. /**
  122. * Construct a counter object.
  123. *
  124. * @param numberElem The owning xsl:number element.
  125. *
  126. * @throws TransformerException
  127. *
  128. Counter(ElemNumber numberElem) throws TransformerException
  129. {
  130. m_numberElem = numberElem;
  131. }*/
  132. /**
  133. * Try and find a node that was previously counted. If found,
  134. * return a positive integer that corresponds to the count.
  135. *
  136. * @param support The XPath context to use
  137. * @param node The node to be counted.
  138. *
  139. * @return The count of the node, or -1 if not found.
  140. */
  141. int getPreviouslyCounted(XPathContext support, int node)
  142. {
  143. int n = m_countNodes.size();
  144. m_countResult = 0;
  145. for (int i = n - 1; i >= 0; i--)
  146. {
  147. int countedNode = m_countNodes.elementAt(i);
  148. if (node == countedNode)
  149. {
  150. // Since the list is in backwards order, the count is
  151. // how many are in the rest of the list.
  152. m_countResult = i + 1 + m_countNodesStartCount;
  153. break;
  154. }
  155. DTM dtm = support.getDTM(countedNode);
  156. // Try to see if the given node falls after the counted node...
  157. // if it does, don't keep searching backwards.
  158. if (dtm.isNodeAfter(countedNode, node))
  159. break;
  160. }
  161. return m_countResult;
  162. }
  163. /**
  164. * Get the last node in the list.
  165. *
  166. * @return the last node in the list.
  167. */
  168. int getLast()
  169. {
  170. int size = m_countNodes.size();
  171. return (size > 0) ? m_countNodes.elementAt(size - 1) : DTM.NULL;
  172. }
  173. }