19f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson/*
29f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * Licensed to the Apache Software Foundation (ASF) under one
39f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * or more contributor license agreements. See the NOTICE file
49f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * distributed with this work for additional information
59f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * regarding copyright ownership. The ASF licenses this file
69f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * to you under the Apache License, Version 2.0 (the  "License");
79f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * you may not use this file except in compliance with the License.
89f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * You may obtain a copy of the License at
99f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson *
109f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson *     http://www.apache.org/licenses/LICENSE-2.0
119f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson *
129f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * Unless required by applicable law or agreed to in writing, software
139f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * distributed under the License is distributed on an "AS IS" BASIS,
149f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
159f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * See the License for the specific language governing permissions and
169f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * limitations under the License.
179f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson */
189f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson/*
199f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * $Id: FuncExtFunction.java 468655 2006-10-28 07:12:06Z minchau $
209f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson */
219f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilsonpackage org.apache.xpath.functions;
229f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
239f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilsonimport java.util.Vector;
249f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
259f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilsonimport org.apache.xalan.res.XSLMessages;
269f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilsonimport org.apache.xpath.Expression;
279f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilsonimport org.apache.xpath.ExpressionNode;
289f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilsonimport org.apache.xpath.ExpressionOwner;
299f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilsonimport org.apache.xpath.ExtensionsProvider;
309f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilsonimport org.apache.xpath.XPathContext;
319f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilsonimport org.apache.xpath.XPathVisitor;
329f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilsonimport org.apache.xpath.objects.XNull;
339f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilsonimport org.apache.xpath.objects.XObject;
349f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilsonimport org.apache.xpath.res.XPATHErrorResources;
359f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilsonimport org.apache.xpath.res.XPATHMessages;
369f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
379f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson/**
389f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * An object of this class represents an extension call expression.  When
399f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * the expression executes, it calls ExtensionsTable#extFunction, and then
409f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * converts the result to the appropriate XObject.
419f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * @xsl.usage advanced
429f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson */
439f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilsonpublic class FuncExtFunction extends Function
449f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson{
459f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    static final long serialVersionUID = 5196115554693708718L;
469f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
479f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  /**
489f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * The namespace for the extension function, which should not normally
499f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *  be null or empty.
509f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *  @serial
519f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   */
529f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  String m_namespace;
539f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
549f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  /**
559f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * The local name of the extension.
569f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *  @serial
579f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   */
589f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  String m_extensionName;
599f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
609f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  /**
619f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * Unique method key, which is passed to ExtensionsTable#extFunction in
629f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *  order to allow caching of the method.
639f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *  @serial
649f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   */
659f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  Object m_methodKey;
669f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
679f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  /**
689f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * Array of static expressions which represent the parameters to the
699f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *  function.
709f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *  @serial
719f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   */
729f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  Vector m_argVec = new Vector();
739f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
749f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  /**
759f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * This function is used to fixup variables from QNames to stack frame
769f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * indexes at stylesheet build time.
779f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @param vars List of QNames that correspond to variables.  This list
789f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * should be searched backwards for the first qualified name that
799f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * corresponds to the variable reference qname.  The position of the
809f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * QName in the vector from the start of the vector will be its position
819f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * in the stack frame (but variables above the globalsTop value will need
829f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * to be offset to the current stack frame).
839f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * NEEDSDOC @param globalsSize
849f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   */
859f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  public void fixupVariables(java.util.Vector vars, int globalsSize)
869f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  {
879f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
889f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    if (null != m_argVec)
899f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    {
909f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      int nArgs = m_argVec.size();
919f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
929f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      for (int i = 0; i < nArgs; i++)
939f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      {
949f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        Expression arg = (Expression) m_argVec.elementAt(i);
959f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
969f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        arg.fixupVariables(vars, globalsSize);
979f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      }
989f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
999f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  }
1009f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
1019f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  /**
1029f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * Return the namespace of the extension function.
1039f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *
1049f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @return The namespace of the extension function.
1059f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   */
1069f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  public String getNamespace()
1079f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  {
1089f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    return m_namespace;
1099f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  }
1109f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
1119f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  /**
1129f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * Return the name of the extension function.
1139f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *
1149f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @return The name of the extension function.
1159f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   */
1169f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  public String getFunctionName()
1179f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  {
1189f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    return m_extensionName;
1199f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  }
1209f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
1219f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  /**
1229f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * Return the method key of the extension function.
1239f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *
1249f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @return The method key of the extension function.
1259f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   */
1269f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  public Object getMethodKey()
1279f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  {
1289f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    return m_methodKey;
1299f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  }
1309f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
1319f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  /**
1329f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * Return the nth argument passed to the extension function.
1339f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *
1349f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @param n The argument number index.
1359f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @return The Expression object at the given index.
1369f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   */
1379f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  public Expression getArg(int n) {
1389f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    if (n >= 0 && n < m_argVec.size())
1399f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      return (Expression) m_argVec.elementAt(n);
1409f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    else
1419f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      return null;
1429f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  }
1439f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
1449f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  /**
1459f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * Return the number of arguments that were passed
1469f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * into this extension function.
1479f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *
1489f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @return The number of arguments.
1499f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   */
1509f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  public int getArgCount() {
1519f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    return m_argVec.size();
1529f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  }
1539f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
1549f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  /**
1559f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * Create a new FuncExtFunction based on the qualified name of the extension,
1569f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * and a unique method key.
1579f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *
1589f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @param namespace The namespace for the extension function, which should
1599f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *                  not normally be null or empty.
1609f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @param extensionName The local name of the extension.
1619f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @param methodKey Unique method key, which is passed to
1629f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *                  ExtensionsTable#extFunction in order to allow caching
1639f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *                  of the method.
1649f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   */
1659f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  public FuncExtFunction(java.lang.String namespace,
1669f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                         java.lang.String extensionName, Object methodKey)
1679f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  {
1689f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    //try{throw new Exception("FuncExtFunction() " + namespace + " " + extensionName);} catch (Exception e){e.printStackTrace();}
1699f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    m_namespace = namespace;
1709f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    m_extensionName = extensionName;
1719f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    m_methodKey = methodKey;
1729f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  }
1739f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
1749f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  /**
1759f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * Execute the function.  The function must return
1769f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * a valid object.
1779f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @param xctxt The current execution context.
1789f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @return A valid XObject.
1799f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *
1809f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @throws javax.xml.transform.TransformerException
1819f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   */
1829f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  public XObject execute(XPathContext xctxt)
1839f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          throws javax.xml.transform.TransformerException
1849f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  {
1859f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    if (xctxt.isSecureProcessing())
1869f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      throw new javax.xml.transform.TransformerException(
1879f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        XPATHMessages.createXPATHMessage(
1889f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          XPATHErrorResources.ER_EXTENSION_FUNCTION_CANNOT_BE_INVOKED,
1899f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          new Object[] {toString()}));
1909f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
1919f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    XObject result;
1929f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    Vector argVec = new Vector();
1939f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    int nArgs = m_argVec.size();
1949f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
1959f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    for (int i = 0; i < nArgs; i++)
1969f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    {
1979f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      Expression arg = (Expression) m_argVec.elementAt(i);
1989f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
1999f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      XObject xobj = arg.execute(xctxt);
2009f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      /*
2019f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson       * Should cache the arguments for func:function
2029f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson       */
2039f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      xobj.allowDetachToRelease(false);
2049f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      argVec.addElement(xobj);
2059f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
2069f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    //dml
2079f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    ExtensionsProvider extProvider = (ExtensionsProvider)xctxt.getOwnerObject();
2089f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    Object val = extProvider.extFunction(this, argVec);
2099f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
2109f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    if (null != val)
2119f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    {
2129f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      result = XObject.create(val, xctxt);
2139f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
2149f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    else
2159f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    {
2169f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      result = new XNull();
2179f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
2189f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
2199f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    return result;
2209f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  }
2219f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
2229f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  /**
2239f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * Set an argument expression for a function.  This method is called by the
2249f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * XPath compiler.
2259f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *
2269f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @param arg non-null expression that represents the argument.
2279f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @param argNum The argument number index.
2289f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *
2299f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @throws WrongNumberArgsException If the argNum parameter is beyond what
2309f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * is specified for this function.
2319f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   */
2329f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  public void setArg(Expression arg, int argNum)
2339f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          throws WrongNumberArgsException
2349f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  {
2359f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    m_argVec.addElement(arg);
2369f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    arg.exprSetParent(this);
2379f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  }
2389f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
2399f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  /**
2409f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * Check that the number of arguments passed to this function is correct.
2419f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *
2429f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *
2439f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @param argNum The number of arguments that is being passed to the function.
2449f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *
2459f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @throws WrongNumberArgsException
2469f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   */
2479f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  public void checkNumberArgs(int argNum) throws WrongNumberArgsException{}
2489f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
2499f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
2509f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  class ArgExtOwner implements ExpressionOwner
2519f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  {
2529f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
2539f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    Expression m_exp;
2549f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
2559f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  	ArgExtOwner(Expression exp)
2569f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  	{
2579f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  		m_exp = exp;
2589f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  	}
2599f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
2609f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    /**
2619f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * @see ExpressionOwner#getExpression()
2629f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     */
2639f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    public Expression getExpression()
2649f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    {
2659f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      return m_exp;
2669f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
2679f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
2689f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
2699f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    /**
2709f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * @see ExpressionOwner#setExpression(Expression)
2719f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     */
2729f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    public void setExpression(Expression exp)
2739f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    {
2749f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    	exp.exprSetParent(FuncExtFunction.this);
2759f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    	m_exp = exp;
2769f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
2779f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  }
2789f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
2799f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
2809f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  /**
2819f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * Call the visitors for the function arguments.
2829f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   */
2839f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  public void callArgVisitors(XPathVisitor visitor)
2849f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  {
2859f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      for (int i = 0; i < m_argVec.size(); i++)
2869f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      {
2879f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson         Expression exp = (Expression)m_argVec.elementAt(i);
2889f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson         exp.callVisitors(new ArgExtOwner(exp), visitor);
2899f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      }
2909f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
2919f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  }
2929f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
2939f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  /**
2949f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * Set the parent node.
2959f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * For an extension function, we also need to set the parent
2969f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * node for all argument expressions.
2979f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *
2989f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @param n The parent node
2999f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   */
3009f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  public void exprSetParent(ExpressionNode n)
3019f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  {
3029f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
3039f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    super.exprSetParent(n);
3049f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
3059f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    int nArgs = m_argVec.size();
3069f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
3079f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    for (int i = 0; i < nArgs; i++)
3089f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    {
3099f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      Expression arg = (Expression) m_argVec.elementAt(i);
3109f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
3119f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      arg.exprSetParent(n);
3129f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
3139f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  }
3149f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
3159f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  /**
3169f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * Constructs and throws a WrongNumberArgException with the appropriate
3179f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * message for this function object.  This class supports an arbitrary
3189f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * number of arguments, so this method must never be called.
3199f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *
3209f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @throws WrongNumberArgsException
3219f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   */
3229f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  protected void reportWrongNumberArgs() throws WrongNumberArgsException {
3239f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    String fMsg = XSLMessages.createXPATHMessage(
3249f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        XPATHErrorResources.ER_INCORRECT_PROGRAMMER_ASSERTION,
3259f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        new Object[]{ "Programmer's assertion:  the method FunctionMultiArgs.reportWrongNumberArgs() should never be called." });
3269f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
3279f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    throw new RuntimeException(fMsg);
3289f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  }
3299f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
3309f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  /**
3319f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * Return the name of the extesion function in string format
3329f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   */
3339f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  public String toString()
3349f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  {
3359f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    if (m_namespace != null && m_namespace.length() > 0)
3369f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      return "{" + m_namespace + "}" + m_extensionName;
3379f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    else
3389f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      return m_extensionName;
3399f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  }
3409f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson}
341