001: /*
002: * Copyright 1999-2004 The Apache Software Foundation.
003: *
004: * Licensed under the Apache License, Version 2.0 (the "License");
005: * you may not use this file except in compliance with the License.
006: * You may obtain a copy of the License at
007: *
008: * http://www.apache.org/licenses/LICENSE-2.0
009: *
010: * Unless required by applicable law or agreed to in writing, software
011: * distributed under the License is distributed on an "AS IS" BASIS,
012: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013: * See the License for the specific language governing permissions and
014: * limitations under the License.
015: */
016: /*
017: * $Id: FuncPosition.java,v 1.13 2004/08/17 19:25:36 jycli Exp $
018: */
019: package org.apache.xpath.functions;
020:
021: import org.apache.xml.dtm.DTM;
022: import org.apache.xml.dtm.DTMIterator;
023: import org.apache.xpath.XPathContext;
024: import org.apache.xpath.axes.SubContextList;
025: import org.apache.xpath.compiler.Compiler;
026: import org.apache.xpath.objects.XNumber;
027: import org.apache.xpath.objects.XObject;
028:
029: /**
030: * Execute the Position() function.
031: * @xsl.usage advanced
032: */
033: public class FuncPosition extends Function {
034: static final long serialVersionUID = -9092846348197271582L;
035: private boolean m_isTopLevel;
036:
037: /**
038: * Figure out if we're executing a toplevel expression.
039: * If so, we can't be inside of a predicate.
040: */
041: public void postCompileStep(Compiler compiler) {
042: m_isTopLevel = compiler.getLocationPathDepth() == -1;
043: }
044:
045: /**
046: * Get the position in the current context node list.
047: *
048: * @param xctxt Runtime XPath context.
049: *
050: * @return The current position of the itteration in the context node list,
051: * or -1 if there is no active context node list.
052: */
053: public int getPositionInContextNodeList(XPathContext xctxt) {
054:
055: // System.out.println("FuncPosition- entry");
056: // If we're in a predicate, then this will return non-null.
057: SubContextList iter = m_isTopLevel ? null : xctxt
058: .getSubContextList();
059:
060: if (null != iter) {
061: int prox = iter.getProximityPosition(xctxt);
062:
063: // System.out.println("FuncPosition- prox: "+prox);
064: return prox;
065: }
066:
067: DTMIterator cnl = xctxt.getContextNodeList();
068:
069: if (null != cnl) {
070: int n = cnl.getCurrentNode();
071: if (n == DTM.NULL) {
072: if (cnl.getCurrentPos() == 0)
073: return 0;
074:
075: // Then I think we're in a sort. See sort21.xsl. So the iterator has
076: // already been spent, and is not on the node we're processing.
077: // It's highly possible that this is an issue for other context-list
078: // functions. Shouldn't be a problem for last(), and it shouldn't be
079: // a problem for current().
080: try {
081: cnl = cnl.cloneWithReset();
082: } catch (CloneNotSupportedException cnse) {
083: throw new org.apache.xml.utils.WrappedRuntimeException(
084: cnse);
085: }
086: int currentNode = xctxt.getContextNode();
087: // System.out.println("currentNode: "+currentNode);
088: while (DTM.NULL != (n = cnl.nextNode())) {
089: if (n == currentNode)
090: break;
091: }
092: }
093: // System.out.println("n: "+n);
094: // System.out.println("FuncPosition- cnl.getCurrentPos(): "+cnl.getCurrentPos());
095: return cnl.getCurrentPos();
096: }
097:
098: // System.out.println("FuncPosition - out of guesses: -1");
099: return -1;
100: }
101:
102: /**
103: * Execute the function. The function must return
104: * a valid object.
105: * @param xctxt The current execution context.
106: * @return A valid XObject.
107: *
108: * @throws javax.xml.transform.TransformerException
109: */
110: public XObject execute(XPathContext xctxt)
111: throws javax.xml.transform.TransformerException {
112: double pos = (double) getPositionInContextNodeList(xctxt);
113:
114: return new XNumber(pos);
115: }
116:
117: /**
118: * No arguments to process, so this does nothing.
119: */
120: public void fixupVariables(java.util.Vector vars, int globalsSize) {
121: // no-op
122: }
123: }
|