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: ContextMatchStepPattern.java,v 1.6 2004/02/17 04:35:37 minchau Exp $
  18. */
  19. package com.sun.org.apache.xpath.internal.patterns;
  20. import com.sun.org.apache.xml.internal.dtm.Axis;
  21. import com.sun.org.apache.xml.internal.dtm.DTM;
  22. import com.sun.org.apache.xml.internal.dtm.DTMAxisTraverser;
  23. import com.sun.org.apache.xml.internal.dtm.DTMFilter;
  24. import com.sun.org.apache.xpath.internal.XPathContext;
  25. import com.sun.org.apache.xpath.internal.axes.WalkerFactory;
  26. import com.sun.org.apache.xpath.internal.objects.XObject;
  27. /**
  28. * Special context node pattern matcher.
  29. */
  30. public class ContextMatchStepPattern extends StepPattern
  31. {
  32. /**
  33. * Construct a ContextMatchStepPattern.
  34. *
  35. * @param whatToShow Bit set defined mainly by {@link org.w3c.dom.traversal.NodeFilter}.
  36. */
  37. public ContextMatchStepPattern(int axis, int paxis)
  38. {
  39. super(DTMFilter.SHOW_ALL, axis, paxis);
  40. }
  41. /**
  42. * Execute this pattern step, including predicates.
  43. *
  44. *
  45. * @param xctxt XPath runtime context.
  46. *
  47. * @return {@link com.sun.org.apache.xpath.internal.patterns.NodeTest#SCORE_NODETEST},
  48. * {@link com.sun.org.apache.xpath.internal.patterns.NodeTest#SCORE_NONE},
  49. * {@link com.sun.org.apache.xpath.internal.patterns.NodeTest#SCORE_NSWILD},
  50. * {@link com.sun.org.apache.xpath.internal.patterns.NodeTest#SCORE_QNAME}, or
  51. * {@link com.sun.org.apache.xpath.internal.patterns.NodeTest#SCORE_OTHER}.
  52. *
  53. * @throws javax.xml.transform.TransformerException
  54. */
  55. public XObject execute(XPathContext xctxt)
  56. throws javax.xml.transform.TransformerException
  57. {
  58. if (xctxt.getIteratorRoot() == xctxt.getCurrentNode())
  59. return getStaticScore();
  60. else
  61. return this.SCORE_NONE;
  62. }
  63. /**
  64. * Execute the match pattern step relative to another step.
  65. *
  66. *
  67. * @param xctxt The XPath runtime context.
  68. * NEEDSDOC @param prevStep
  69. *
  70. * @return {@link com.sun.org.apache.xpath.internal.patterns.NodeTest#SCORE_NODETEST},
  71. * {@link com.sun.org.apache.xpath.internal.patterns.NodeTest#SCORE_NONE},
  72. * {@link com.sun.org.apache.xpath.internal.patterns.NodeTest#SCORE_NSWILD},
  73. * {@link com.sun.org.apache.xpath.internal.patterns.NodeTest#SCORE_QNAME}, or
  74. * {@link com.sun.org.apache.xpath.internal.patterns.NodeTest#SCORE_OTHER}.
  75. *
  76. * @throws javax.xml.transform.TransformerException
  77. */
  78. public XObject executeRelativePathPattern(
  79. XPathContext xctxt, StepPattern prevStep)
  80. throws javax.xml.transform.TransformerException
  81. {
  82. XObject score = NodeTest.SCORE_NONE;
  83. int context = xctxt.getCurrentNode();
  84. DTM dtm = xctxt.getDTM(context);
  85. if (null != dtm)
  86. {
  87. int predContext = xctxt.getCurrentNode();
  88. DTMAxisTraverser traverser;
  89. int axis = m_axis;
  90. boolean needToTraverseAttrs = WalkerFactory.isDownwardAxisOfMany(axis);
  91. boolean iterRootIsAttr = (dtm.getNodeType(xctxt.getIteratorRoot())
  92. == DTM.ATTRIBUTE_NODE);
  93. if((Axis.PRECEDING == axis) && iterRootIsAttr)
  94. {
  95. axis = Axis.PRECEDINGANDANCESTOR;
  96. }
  97. traverser = dtm.getAxisTraverser(axis);
  98. for (int relative = traverser.first(context); DTM.NULL != relative;
  99. relative = traverser.next(context, relative))
  100. {
  101. try
  102. {
  103. xctxt.pushCurrentNode(relative);
  104. score = execute(xctxt);
  105. if (score != NodeTest.SCORE_NONE)
  106. {
  107. //score = executePredicates( xctxt, prevStep, SCORE_OTHER,
  108. // predContext, relative);
  109. if (executePredicates(xctxt, dtm, context))
  110. return score;
  111. score = NodeTest.SCORE_NONE;
  112. }
  113. if(needToTraverseAttrs && iterRootIsAttr
  114. && (DTM.ELEMENT_NODE == dtm.getNodeType(relative)))
  115. {
  116. int xaxis = Axis.ATTRIBUTE;
  117. for (int i = 0; i < 2; i++)
  118. {
  119. DTMAxisTraverser atraverser = dtm.getAxisTraverser(xaxis);
  120. for (int arelative = atraverser.first(relative);
  121. DTM.NULL != arelative;
  122. arelative = atraverser.next(relative, arelative))
  123. {
  124. try
  125. {
  126. xctxt.pushCurrentNode(arelative);
  127. score = execute(xctxt);
  128. if (score != NodeTest.SCORE_NONE)
  129. {
  130. //score = executePredicates( xctxt, prevStep, SCORE_OTHER,
  131. // predContext, arelative);
  132. if (score != NodeTest.SCORE_NONE)
  133. return score;
  134. }
  135. }
  136. finally
  137. {
  138. xctxt.popCurrentNode();
  139. }
  140. }
  141. xaxis = Axis.NAMESPACE;
  142. }
  143. }
  144. }
  145. finally
  146. {
  147. xctxt.popCurrentNode();
  148. }
  149. }
  150. }
  151. return score;
  152. }
  153. }