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.functions; 22 23 import com.sun.org.apache.xml.internal.dtm.DTM; 24 import com.sun.org.apache.xml.internal.dtm.DTMIterator; 25 import com.sun.org.apache.xml.internal.utils.QName; 26 import com.sun.org.apache.xpath.internal.XPathContext; 27 import com.sun.org.apache.xpath.internal.axes.SubContextList; 28 import com.sun.org.apache.xpath.internal.compiler.Compiler; 29 import com.sun.org.apache.xpath.internal.objects.XNumber; 30 import com.sun.org.apache.xpath.internal.objects.XObject; 31 import java.util.List; 32 33 /** 34 * Execute the Position() function. 35 * @xsl.usage advanced 36 * @LastModified: Oct 2017 37 */ 38 public class FuncPosition extends Function 39 { 40 static final long serialVersionUID = -9092846348197271582L; 41 private boolean m_isTopLevel; 42 43 /** 44 * Figure out if we're executing a toplevel expression. 45 * If so, we can't be inside of a predicate. 46 */ postCompileStep(Compiler compiler)47 public void postCompileStep(Compiler compiler) 48 { 49 m_isTopLevel = compiler.getLocationPathDepth() == -1; 50 } 51 52 /** 53 * Get the position in the current context node list. 54 * 55 * @param xctxt Runtime XPath context. 56 * 57 * @return The current position of the itteration in the context node list, 58 * or -1 if there is no active context node list. 59 */ getPositionInContextNodeList(XPathContext xctxt)60 public int getPositionInContextNodeList(XPathContext xctxt) 61 { 62 63 // System.out.println("FuncPosition- entry"); 64 // If we're in a predicate, then this will return non-null. 65 SubContextList iter = m_isTopLevel ? null : xctxt.getSubContextList(); 66 67 if (null != iter) 68 { 69 int prox = iter.getProximityPosition(xctxt); 70 71 // System.out.println("FuncPosition- prox: "+prox); 72 return prox; 73 } 74 75 DTMIterator cnl = xctxt.getContextNodeList(); 76 77 if (null != cnl) 78 { 79 int n = cnl.getCurrentNode(); 80 if(n == DTM.NULL) 81 { 82 if(cnl.getCurrentPos() == 0) 83 return 0; 84 85 // Then I think we're in a sort. See sort21.xsl. So the iterator has 86 // already been spent, and is not on the node we're processing. 87 // It's highly possible that this is an issue for other context-list 88 // functions. Shouldn't be a problem for last(), and it shouldn't be 89 // a problem for current(). 90 try 91 { 92 cnl = cnl.cloneWithReset(); 93 } 94 catch(CloneNotSupportedException cnse) 95 { 96 throw new com.sun.org.apache.xml.internal.utils.WrappedRuntimeException(cnse); 97 } 98 int currentNode = xctxt.getContextNode(); 99 // System.out.println("currentNode: "+currentNode); 100 while(DTM.NULL != (n = cnl.nextNode())) 101 { 102 if(n == currentNode) 103 break; 104 } 105 } 106 // System.out.println("n: "+n); 107 // System.out.println("FuncPosition- cnl.getCurrentPos(): "+cnl.getCurrentPos()); 108 return cnl.getCurrentPos(); 109 } 110 111 // System.out.println("FuncPosition - out of guesses: -1"); 112 return -1; 113 } 114 115 /** 116 * Execute the function. The function must return 117 * a valid object. 118 * @param xctxt The current execution context. 119 * @return A valid XObject. 120 * 121 * @throws javax.xml.transform.TransformerException 122 */ execute(XPathContext xctxt)123 public XObject execute(XPathContext xctxt) throws javax.xml.transform.TransformerException 124 { 125 double pos = (double) getPositionInContextNodeList(xctxt); 126 127 return new XNumber(pos); 128 } 129 130 /** 131 * No arguments to process, so this does nothing. 132 */ fixupVariables(List<QName> vars, int globalsSize)133 public void fixupVariables(List<QName> vars, int globalsSize) 134 { 135 // no-op 136 } 137 } 138