1 /*
   2  * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
   3  * @LastModified: Oct 2017
   4  */
   5 /*
   6  * Licensed to the Apache Software Foundation (ASF) under one or more
   7  * contributor license agreements.  See the NOTICE file distributed with
   8  * this work for additional information regarding copyright ownership.
   9  * The ASF licenses this file to You under the Apache License, Version 2.0
  10  * (the "License"); you may not use this file except in compliance with
  11  * the License.  You may obtain a copy of the License at
  12  *
  13  *      http://www.apache.org/licenses/LICENSE-2.0
  14  *
  15  * Unless required by applicable law or agreed to in writing, software
  16  * distributed under the License is distributed on an "AS IS" BASIS,
  17  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  18  * See the License for the specific language governing permissions and
  19  * limitations under the License.
  20  */
  21 
  22 package com.sun.org.apache.xpath.internal.functions;
  23 
  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 /**
  35  * Execute the Last() function.
  36  * @xsl.usage advanced
  37  */
  38 public class FuncLast extends Function
  39 {
  40     static final long serialVersionUID = 9205812403085432943L;
  41 
  42   private boolean m_isTopLevel;
  43 
  44   /**
  45    * Figure out if we're executing a toplevel expression.
  46    * If so, we can't be inside of a predicate.
  47    */
  48   public void postCompileStep(Compiler compiler)
  49   {
  50     m_isTopLevel = compiler.getLocationPathDepth() == -1;
  51   }
  52 
  53   /**
  54    * Get the position in the current context node list.
  55    *
  56    * @param xctxt non-null reference to XPath runtime context.
  57    *
  58    * @return The number of nodes in the list.
  59    *
  60    * @throws javax.xml.transform.TransformerException
  61    */
  62   public int getCountOfContextNodeList(XPathContext xctxt)
  63           throws javax.xml.transform.TransformerException
  64   {
  65 
  66     // assert(null != m_contextNodeList, "m_contextNodeList must be non-null");
  67     // If we're in a predicate, then this will return non-null.
  68     SubContextList iter = m_isTopLevel ? null : xctxt.getSubContextList();
  69 
  70     // System.out.println("iter: "+iter);
  71     if (null != iter)
  72       return iter.getLastPos(xctxt);
  73 
  74     DTMIterator cnl = xctxt.getContextNodeList();
  75     int count;
  76     if(null != cnl)
  77     {
  78       count = cnl.getLength();
  79       // System.out.println("count: "+count);
  80     }
  81     else
  82       count = 0;
  83     return count;
  84   }
  85 
  86   /**
  87    * Execute the function.  The function must return
  88    * a valid object.
  89    * @param xctxt The current execution context.
  90    * @return A valid XObject.
  91    *
  92    * @throws javax.xml.transform.TransformerException
  93    */
  94   public XObject execute(XPathContext xctxt) throws javax.xml.transform.TransformerException
  95   {
  96     XNumber xnum = new XNumber((double) getCountOfContextNodeList(xctxt));
  97     // System.out.println("last: "+xnum.num());
  98     return xnum;
  99   }
 100 
 101   /**
 102    * No arguments to process, so this does nothing.
 103    */
 104   public void fixupVariables(List<QName> vars, int globalsSize)
 105   {
 106     // no-op
 107   }
 108 
 109 }