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