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: FuncLast.java 468655 2006-10-28 07:12:06Z minchau $
20 */
21package org.apache.xpath.functions;
22
23import org.apache.xml.dtm.DTMIterator;
24import org.apache.xpath.XPathContext;
25import org.apache.xpath.axes.SubContextList;
26import org.apache.xpath.compiler.Compiler;
27import org.apache.xpath.objects.XNumber;
28import org.apache.xpath.objects.XObject;
29
30
31/**
32 * Execute the Last() function.
33 * @xsl.usage advanced
34 */
35public class FuncLast extends Function
36{
37    static final long serialVersionUID = 9205812403085432943L;
38
39  private boolean m_isTopLevel;
40
41  /**
42   * Figure out if we're executing a toplevel expression.
43   * If so, we can't be inside of a predicate.
44   */
45  public void postCompileStep(Compiler compiler)
46  {
47    m_isTopLevel = compiler.getLocationPathDepth() == -1;
48  }
49
50  /**
51   * Get the position in the current context node list.
52   *
53   * @param xctxt non-null reference to XPath runtime context.
54   *
55   * @return The number of nodes in the list.
56   *
57   * @throws javax.xml.transform.TransformerException
58   */
59  public int getCountOfContextNodeList(XPathContext xctxt)
60          throws javax.xml.transform.TransformerException
61  {
62
63    // assert(null != m_contextNodeList, "m_contextNodeList must be non-null");
64    // If we're in a predicate, then this will return non-null.
65    SubContextList iter = m_isTopLevel ? null : xctxt.getSubContextList();
66
67    // System.out.println("iter: "+iter);
68    if (null != iter)
69      return iter.getLastPos(xctxt);
70
71    DTMIterator cnl = xctxt.getContextNodeList();
72    int count;
73    if(null != cnl)
74    {
75      count = cnl.getLength();
76      // System.out.println("count: "+count);
77    }
78    else
79      count = 0;
80    return count;
81  }
82
83  /**
84   * Execute the function.  The function must return
85   * a valid object.
86   * @param xctxt The current execution context.
87   * @return A valid XObject.
88   *
89   * @throws javax.xml.transform.TransformerException
90   */
91  public XObject execute(XPathContext xctxt) throws javax.xml.transform.TransformerException
92  {
93    XNumber xnum = new XNumber((double) getCountOfContextNodeList(xctxt));
94    // System.out.println("last: "+xnum.num());
95    return xnum;
96  }
97
98  /**
99   * No arguments to process, so this does nothing.
100   */
101  public void fixupVariables(java.util.Vector vars, int globalsSize)
102  {
103    // no-op
104  }
105
106}
107