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: WalkingIteratorSorted.java,v 1.11 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.Axis;
  21. import com.sun.org.apache.xml.internal.utils.PrefixResolver;
  22. import com.sun.org.apache.xpath.internal.compiler.Compiler;
  23. /**
  24. * This class iterates over set of nodes that needs to be sorted.
  25. * @xsl.usage internal
  26. */
  27. public class WalkingIteratorSorted extends WalkingIterator
  28. {
  29. // /** True if the nodes will be found in document order */
  30. // protected boolean m_inNaturalOrder = false;
  31. /** True if the nodes will be found in document order, and this can
  32. * be determined statically. */
  33. protected boolean m_inNaturalOrderStatic = false;
  34. /**
  35. * Create a WalkingIteratorSorted object.
  36. *
  37. * @param nscontext The namespace context for this iterator,
  38. * should be OK if null.
  39. */
  40. public WalkingIteratorSorted(PrefixResolver nscontext)
  41. {
  42. super(nscontext);
  43. }
  44. /**
  45. * Create a WalkingIterator iterator, including creation
  46. * of step walkers from the opcode list, and call back
  47. * into the Compiler to create predicate expressions.
  48. *
  49. * @param compiler The Compiler which is creating
  50. * this expression.
  51. * @param opPos The position of this iterator in the
  52. * opcode list from the compiler.
  53. * @param shouldLoadWalkers True if walkers should be
  54. * loaded, or false if this is a derived iterator and
  55. * it doesn't wish to load child walkers.
  56. *
  57. * @throws javax.xml.transform.TransformerException
  58. */
  59. WalkingIteratorSorted(
  60. Compiler compiler, int opPos, int analysis, boolean shouldLoadWalkers)
  61. throws javax.xml.transform.TransformerException
  62. {
  63. super(compiler, opPos, analysis, shouldLoadWalkers);
  64. }
  65. /**
  66. * Returns true if all the nodes in the iteration well be returned in document
  67. * order.
  68. *
  69. * @return true as a default.
  70. */
  71. public boolean isDocOrdered()
  72. {
  73. return m_inNaturalOrderStatic;
  74. }
  75. /**
  76. * Tell if the nodeset can be walked in doc order, via static analysis.
  77. *
  78. *
  79. * @return true if the nodeset can be walked in doc order, without sorting.
  80. */
  81. boolean canBeWalkedInNaturalDocOrderStatic()
  82. {
  83. if (null != m_firstWalker)
  84. {
  85. AxesWalker walker = m_firstWalker;
  86. int prevAxis = -1;
  87. boolean prevIsSimpleDownAxis = true;
  88. for(int i = 0; null != walker; i++)
  89. {
  90. int axis = walker.getAxis();
  91. if(walker.isDocOrdered())
  92. {
  93. boolean isSimpleDownAxis = ((axis == Axis.CHILD)
  94. || (axis == Axis.SELF)
  95. || (axis == Axis.ROOT));
  96. // Catching the filtered list here is only OK because
  97. // FilterExprWalker#isDocOrdered() did the right thing.
  98. if(isSimpleDownAxis || (axis == -1))
  99. walker = walker.getNextWalker();
  100. else
  101. {
  102. boolean isLastWalker = (null == walker.getNextWalker());
  103. if(isLastWalker)
  104. {
  105. if(walker.isDocOrdered() && (axis == Axis.DESCENDANT ||
  106. axis == Axis.DESCENDANTORSELF || axis == Axis.DESCENDANTSFROMROOT
  107. || axis == Axis.DESCENDANTSORSELFFROMROOT) || (axis == Axis.ATTRIBUTE))
  108. return true;
  109. }
  110. return false;
  111. }
  112. }
  113. else
  114. return false;
  115. }
  116. return true;
  117. }
  118. return false;
  119. }
  120. // /**
  121. // * NEEDSDOC Method canBeWalkedInNaturalDocOrder
  122. // *
  123. // *
  124. // * NEEDSDOC (canBeWalkedInNaturalDocOrder) @return
  125. // */
  126. // boolean canBeWalkedInNaturalDocOrder()
  127. // {
  128. //
  129. // if (null != m_firstWalker)
  130. // {
  131. // AxesWalker walker = m_firstWalker;
  132. // int prevAxis = -1;
  133. // boolean prevIsSimpleDownAxis = true;
  134. //
  135. // for(int i = 0; null != walker; i++)
  136. // {
  137. // int axis = walker.getAxis();
  138. //
  139. // if(walker.isDocOrdered())
  140. // {
  141. // boolean isSimpleDownAxis = ((axis == Axis.CHILD)
  142. // || (axis == Axis.SELF)
  143. // || (axis == Axis.ROOT));
  144. // // Catching the filtered list here is only OK because
  145. // // FilterExprWalker#isDocOrdered() did the right thing.
  146. // if(isSimpleDownAxis || (axis == -1))
  147. // walker = walker.getNextWalker();
  148. // else
  149. // {
  150. // boolean isLastWalker = (null == walker.getNextWalker());
  151. // if(isLastWalker)
  152. // {
  153. // if(walker.isDocOrdered() && (axis == Axis.DESCENDANT ||
  154. // axis == Axis.DESCENDANTORSELF || axis == Axis.DESCENDANTSFROMROOT
  155. // || axis == Axis.DESCENDANTSORSELFFROMROOT) || (axis == Axis.ATTRIBUTE))
  156. // return true;
  157. // }
  158. // return false;
  159. // }
  160. // }
  161. // else
  162. // return false;
  163. // }
  164. // return true;
  165. // }
  166. // return false;
  167. // }
  168. /**
  169. * This function is used to perform some extra analysis of the iterator.
  170. *
  171. * @param vars List of QNames that correspond to variables. This list
  172. * should be searched backwards for the first qualified name that
  173. * corresponds to the variable reference qname. The position of the
  174. * QName in the vector from the start of the vector will be its position
  175. * in the stack frame (but variables above the globalsTop value will need
  176. * to be offset to the current stack frame).
  177. */
  178. public void fixupVariables(java.util.Vector vars, int globalsSize)
  179. {
  180. super.fixupVariables(vars, globalsSize);
  181. int analysis = getAnalysisBits();
  182. if(WalkerFactory.isNaturalDocOrder(analysis))
  183. {
  184. m_inNaturalOrderStatic = true;
  185. }
  186. else
  187. {
  188. m_inNaturalOrderStatic = false;
  189. // System.out.println("Setting natural doc order to false: "+
  190. // WalkerFactory.getAnalysisString(analysis));
  191. }
  192. }
  193. }