/* * Copyright 1999-2004 The Apache Software Foundation. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /* * $Id: ContextMatchStepPattern.java,v 1.6 2004/02/17 04:35:37 minchau Exp $ */ package com.sun.org.apache.xpath.internal.patterns; import com.sun.org.apache.xml.internal.dtm.Axis; import com.sun.org.apache.xml.internal.dtm.DTM; import com.sun.org.apache.xml.internal.dtm.DTMAxisTraverser; import com.sun.org.apache.xml.internal.dtm.DTMFilter; import com.sun.org.apache.xpath.internal.XPathContext; import com.sun.org.apache.xpath.internal.axes.WalkerFactory; import com.sun.org.apache.xpath.internal.objects.XObject; /** * Special context node pattern matcher. */ public class ContextMatchStepPattern extends StepPattern { /** * Construct a ContextMatchStepPattern. * * @param whatToShow Bit set defined mainly by {@link org.w3c.dom.traversal.NodeFilter}. */ public ContextMatchStepPattern(int axis, int paxis) { super(DTMFilter.SHOW_ALL, axis, paxis); } /** * Execute this pattern step, including predicates. * * * @param xctxt XPath runtime context. * * @return {@link com.sun.org.apache.xpath.internal.patterns.NodeTest#SCORE_NODETEST}, * {@link com.sun.org.apache.xpath.internal.patterns.NodeTest#SCORE_NONE}, * {@link com.sun.org.apache.xpath.internal.patterns.NodeTest#SCORE_NSWILD}, * {@link com.sun.org.apache.xpath.internal.patterns.NodeTest#SCORE_QNAME}, or * {@link com.sun.org.apache.xpath.internal.patterns.NodeTest#SCORE_OTHER}. * * @throws javax.xml.transform.TransformerException */ public XObject execute(XPathContext xctxt) throws javax.xml.transform.TransformerException { if (xctxt.getIteratorRoot() == xctxt.getCurrentNode()) return getStaticScore(); else return this.SCORE_NONE; } /** * Execute the match pattern step relative to another step. * * * @param xctxt The XPath runtime context. * NEEDSDOC @param prevStep * * @return {@link com.sun.org.apache.xpath.internal.patterns.NodeTest#SCORE_NODETEST}, * {@link com.sun.org.apache.xpath.internal.patterns.NodeTest#SCORE_NONE}, * {@link com.sun.org.apache.xpath.internal.patterns.NodeTest#SCORE_NSWILD}, * {@link com.sun.org.apache.xpath.internal.patterns.NodeTest#SCORE_QNAME}, or * {@link com.sun.org.apache.xpath.internal.patterns.NodeTest#SCORE_OTHER}. * * @throws javax.xml.transform.TransformerException */ public XObject executeRelativePathPattern( XPathContext xctxt, StepPattern prevStep) throws javax.xml.transform.TransformerException { XObject score = NodeTest.SCORE_NONE; int context = xctxt.getCurrentNode(); DTM dtm = xctxt.getDTM(context); if (null != dtm) { int predContext = xctxt.getCurrentNode(); DTMAxisTraverser traverser; int axis = m_axis; boolean needToTraverseAttrs = WalkerFactory.isDownwardAxisOfMany(axis); boolean iterRootIsAttr = (dtm.getNodeType(xctxt.getIteratorRoot()) == DTM.ATTRIBUTE_NODE); if((Axis.PRECEDING == axis) && iterRootIsAttr) { axis = Axis.PRECEDINGANDANCESTOR; } traverser = dtm.getAxisTraverser(axis); for (int relative = traverser.first(context); DTM.NULL != relative; relative = traverser.next(context, relative)) { try { xctxt.pushCurrentNode(relative); score = execute(xctxt); if (score != NodeTest.SCORE_NONE) { //score = executePredicates( xctxt, prevStep, SCORE_OTHER, // predContext, relative); if (executePredicates(xctxt, dtm, context)) return score; score = NodeTest.SCORE_NONE; } if(needToTraverseAttrs && iterRootIsAttr && (DTM.ELEMENT_NODE == dtm.getNodeType(relative))) { int xaxis = Axis.ATTRIBUTE; for (int i = 0; i < 2; i++) { DTMAxisTraverser atraverser = dtm.getAxisTraverser(xaxis); for (int arelative = atraverser.first(relative); DTM.NULL != arelative; arelative = atraverser.next(relative, arelative)) { try { xctxt.pushCurrentNode(arelative); score = execute(xctxt); if (score != NodeTest.SCORE_NONE) { //score = executePredicates( xctxt, prevStep, SCORE_OTHER, // predContext, arelative); if (score != NodeTest.SCORE_NONE) return score; } } finally { xctxt.popCurrentNode(); } } xaxis = Axis.NAMESPACE; } } } finally { xctxt.popCurrentNode(); } } } return score; } }