1 /* 2 * Licensed to the Apache Software Foundation (ASF) under one 3 * or more contributor license agreements. See the NOTICE file 4 * distributed with this work for additional information 5 * regarding copyright ownership. The ASF licenses this file 6 * to you under the Apache License, Version 2.0 (the "License"); 7 * you may not use this file except in compliance with the License. 8 * You may obtain a copy of the License at 9 * 10 * http://www.apache.org/licenses/LICENSE-2.0 11 * 12 * Unless required by applicable law or agreed to in writing, software 13 * distributed under the License is distributed on an "AS IS" BASIS, 14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 * See the License for the specific language governing permissions and 16 * limitations under the License. 17 */ 18 /* 19 * $Id: ContextMatchStepPattern.java 468655 2006-10-28 07:12:06Z minchau $ 20 */ 21 package org.apache.xpath.patterns; 22 23 import org.apache.xml.dtm.Axis; 24 import org.apache.xml.dtm.DTM; 25 import org.apache.xml.dtm.DTMAxisTraverser; 26 import org.apache.xml.dtm.DTMFilter; 27 import org.apache.xpath.XPathContext; 28 import org.apache.xpath.axes.WalkerFactory; 29 import org.apache.xpath.objects.XObject; 30 /** 31 * Special context node pattern matcher. 32 */ 33 public class ContextMatchStepPattern extends StepPattern 34 { 35 static final long serialVersionUID = -1888092779313211942L; 36 37 /** 38 * Construct a ContextMatchStepPattern. 39 * 40 */ 41 public ContextMatchStepPattern(int axis, int paxis) 42 { 43 super(DTMFilter.SHOW_ALL, axis, paxis); 44 } 45 46 /** 47 * Execute this pattern step, including predicates. 48 * 49 * 50 * @param xctxt XPath runtime context. 51 * 52 * @return {@link org.apache.xpath.patterns.NodeTest#SCORE_NODETEST}, 53 * {@link org.apache.xpath.patterns.NodeTest#SCORE_NONE}, 54 * {@link org.apache.xpath.patterns.NodeTest#SCORE_NSWILD}, 55 * {@link org.apache.xpath.patterns.NodeTest#SCORE_QNAME}, or 56 * {@link org.apache.xpath.patterns.NodeTest#SCORE_OTHER}. 57 * 58 * @throws javax.xml.transform.TransformerException 59 */ 60 public XObject execute(XPathContext xctxt) 61 throws javax.xml.transform.TransformerException 62 { 63 64 if (xctxt.getIteratorRoot() == xctxt.getCurrentNode()) 65 return getStaticScore(); 66 else 67 return this.SCORE_NONE; 68 } 69 70 /** 71 * Execute the match pattern step relative to another step. 72 * 73 * 74 * @param xctxt The XPath runtime context. 75 * NEEDSDOC @param prevStep 76 * 77 * @return {@link org.apache.xpath.patterns.NodeTest#SCORE_NODETEST}, 78 * {@link org.apache.xpath.patterns.NodeTest#SCORE_NONE}, 79 * {@link org.apache.xpath.patterns.NodeTest#SCORE_NSWILD}, 80 * {@link org.apache.xpath.patterns.NodeTest#SCORE_QNAME}, or 81 * {@link org.apache.xpath.patterns.NodeTest#SCORE_OTHER}. 82 * 83 * @throws javax.xml.transform.TransformerException 84 */ 85 public XObject executeRelativePathPattern( 86 XPathContext xctxt, StepPattern prevStep) 87 throws javax.xml.transform.TransformerException 88 { 89 90 XObject score = NodeTest.SCORE_NONE; 91 int context = xctxt.getCurrentNode(); 92 DTM dtm = xctxt.getDTM(context); 93 94 if (null != dtm) 95 { 96 int predContext = xctxt.getCurrentNode(); 97 DTMAxisTraverser traverser; 98 99 int axis = m_axis; 100 101 boolean needToTraverseAttrs = WalkerFactory.isDownwardAxisOfMany(axis); 102 boolean iterRootIsAttr = (dtm.getNodeType(xctxt.getIteratorRoot()) 103 == DTM.ATTRIBUTE_NODE); 104 105 if((Axis.PRECEDING == axis) && iterRootIsAttr) 106 { 107 axis = Axis.PRECEDINGANDANCESTOR; 108 } 109 110 traverser = dtm.getAxisTraverser(axis); 111 112 for (int relative = traverser.first(context); DTM.NULL != relative; 113 relative = traverser.next(context, relative)) 114 { 115 try 116 { 117 xctxt.pushCurrentNode(relative); 118 119 score = execute(xctxt); 120 121 if (score != NodeTest.SCORE_NONE) 122 { 123 //score = executePredicates( xctxt, prevStep, SCORE_OTHER, 124 // predContext, relative); 125 if (executePredicates(xctxt, dtm, context)) 126 return score; 127 128 score = NodeTest.SCORE_NONE; 129 } 130 131 if(needToTraverseAttrs && iterRootIsAttr 132 && (DTM.ELEMENT_NODE == dtm.getNodeType(relative))) 133 { 134 int xaxis = Axis.ATTRIBUTE; 135 for (int i = 0; i < 2; i++) 136 { 137 DTMAxisTraverser atraverser = dtm.getAxisTraverser(xaxis); 138 139 for (int arelative = atraverser.first(relative); 140 DTM.NULL != arelative; 141 arelative = atraverser.next(relative, arelative)) 142 { 143 try 144 { 145 xctxt.pushCurrentNode(arelative); 146 147 score = execute(xctxt); 148 149 if (score != NodeTest.SCORE_NONE) 150 { 151 //score = executePredicates( xctxt, prevStep, SCORE_OTHER, 152 // predContext, arelative); 153 154 if (score != NodeTest.SCORE_NONE) 155 return score; 156 } 157 } 158 finally 159 { 160 xctxt.popCurrentNode(); 161 } 162 } 163 xaxis = Axis.NAMESPACE; 164 } 165 } 166 167 } 168 finally 169 { 170 xctxt.popCurrentNode(); 171 } 172 } 173 174 } 175 176 return score; 177 } 178 179 } 180