1. /*
  2. * Copyright 1999-2004 The Apache Software Foundation.
  3. *
  4. * Licensed under the Apache License, Version 2.0 (the "License");
  5. * you may not use this file except in compliance with the License.
  6. * You may obtain a copy of the License at
  7. *
  8. * http://www.apache.org/licenses/LICENSE-2.0
  9. *
  10. * Unless required by applicable law or agreed to in writing, software
  11. * distributed under the License is distributed on an "AS IS" BASIS,
  12. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. * See the License for the specific language governing permissions and
  14. * limitations under the License.
  15. */
  16. /*
  17. * $Id: UnionChildIterator.java,v 1.5 2004/02/17 04:32:08 minchau Exp $
  18. */
  19. package com.sun.org.apache.xpath.internal.axes;
  20. import com.sun.org.apache.xml.internal.dtm.DTMIterator;
  21. import com.sun.org.apache.xpath.internal.XPathContext;
  22. import com.sun.org.apache.xpath.internal.objects.XObject;
  23. import com.sun.org.apache.xpath.internal.patterns.NodeTest;
  24. /**
  25. * This class defines a simplified type of union iterator that only
  26. * tests along the child axes. If the conditions are right, it is
  27. * much faster than using a UnionPathIterator.
  28. */
  29. public class UnionChildIterator extends ChildTestIterator
  30. {
  31. /**
  32. * Even though these may hold full LocPathIterators, this array does
  33. * not have to be cloned, since only the node test and predicate
  34. * portion are used, and these only need static information. However,
  35. * also note that index predicates can not be used!
  36. */
  37. private PredicatedNodeTest[] m_nodeTests = null;
  38. /**
  39. * Constructor for UnionChildIterator
  40. */
  41. public UnionChildIterator()
  42. {
  43. super(null);
  44. }
  45. /**
  46. * Add a node test to the union list.
  47. *
  48. * @param test reference to a NodeTest, which will be added
  49. * directly to the list of node tests (in other words, it will
  50. * not be cloned). The parent of this test will be set to
  51. * this object.
  52. */
  53. public void addNodeTest(PredicatedNodeTest test)
  54. {
  55. // Increase array size by only 1 at a time. Fix this
  56. // if it looks to be a problem.
  57. if (null == m_nodeTests)
  58. {
  59. m_nodeTests = new PredicatedNodeTest[1];
  60. m_nodeTests[0] = test;
  61. }
  62. else
  63. {
  64. PredicatedNodeTest[] tests = m_nodeTests;
  65. int len = m_nodeTests.length;
  66. m_nodeTests = new PredicatedNodeTest[len + 1];
  67. System.arraycopy(tests, 0, m_nodeTests, 0, len);
  68. m_nodeTests[len] = test;
  69. }
  70. test.exprSetParent(this);
  71. }
  72. /**
  73. * This function is used to fixup variables from QNames to stack frame
  74. * indexes at stylesheet build time.
  75. * @param vars List of QNames that correspond to variables. This list
  76. * should be searched backwards for the first qualified name that
  77. * corresponds to the variable reference qname. The position of the
  78. * QName in the vector from the start of the vector will be its position
  79. * in the stack frame (but variables above the globalsTop value will need
  80. * to be offset to the current stack frame).
  81. */
  82. public void fixupVariables(java.util.Vector vars, int globalsSize)
  83. {
  84. super.fixupVariables(vars, globalsSize);
  85. if (m_nodeTests != null) {
  86. for (int i = 0; i < m_nodeTests.length; i++) {
  87. m_nodeTests[i].fixupVariables(vars, globalsSize);
  88. }
  89. }
  90. }
  91. /**
  92. * Test whether a specified node is visible in the logical view of a
  93. * TreeWalker or NodeIterator. This function will be called by the
  94. * implementation of TreeWalker and NodeIterator; it is not intended to
  95. * be called directly from user code.
  96. * @param n The node to check to see if it passes the filter or not.
  97. * @return a constant to determine whether the node is accepted,
  98. * rejected, or skipped, as defined above .
  99. */
  100. public short acceptNode(int n)
  101. {
  102. XPathContext xctxt = getXPathContext();
  103. try
  104. {
  105. xctxt.pushCurrentNode(n);
  106. for (int i = 0; i < m_nodeTests.length; i++)
  107. {
  108. PredicatedNodeTest pnt = m_nodeTests[i];
  109. XObject score = pnt.execute(xctxt, n);
  110. if (score != NodeTest.SCORE_NONE)
  111. {
  112. // Note that we are assuming there are no positional predicates!
  113. if (pnt.getPredicateCount() > 0)
  114. {
  115. if (pnt.executePredicates(n, xctxt))
  116. return DTMIterator.FILTER_ACCEPT;
  117. }
  118. else
  119. return DTMIterator.FILTER_ACCEPT;
  120. }
  121. }
  122. }
  123. catch (javax.xml.transform.TransformerException se)
  124. {
  125. // TODO: Fix this.
  126. throw new RuntimeException(se.getMessage());
  127. }
  128. finally
  129. {
  130. xctxt.popCurrentNode();
  131. }
  132. return DTMIterator.FILTER_SKIP;
  133. }
  134. }