13d2eed823d534ee370cfd7742c1e96ab3ee9a80bTed Kremenek/*
23d2eed823d534ee370cfd7742c1e96ab3ee9a80bTed Kremenek * Licensed to the Apache Software Foundation (ASF) under one
33d2eed823d534ee370cfd7742c1e96ab3ee9a80bTed Kremenek * or more contributor license agreements. See the NOTICE file
43d2eed823d534ee370cfd7742c1e96ab3ee9a80bTed Kremenek * distributed with this work for additional information
53d2eed823d534ee370cfd7742c1e96ab3ee9a80bTed Kremenek * regarding copyright ownership. The ASF licenses this file
63d2eed823d534ee370cfd7742c1e96ab3ee9a80bTed Kremenek * to you under the Apache License, Version 2.0 (the  "License");
73d2eed823d534ee370cfd7742c1e96ab3ee9a80bTed Kremenek * you may not use this file except in compliance with the License.
83d2eed823d534ee370cfd7742c1e96ab3ee9a80bTed Kremenek * You may obtain a copy of the License at
93d2eed823d534ee370cfd7742c1e96ab3ee9a80bTed Kremenek *
103d2eed823d534ee370cfd7742c1e96ab3ee9a80bTed Kremenek *     http://www.apache.org/licenses/LICENSE-2.0
113d2eed823d534ee370cfd7742c1e96ab3ee9a80bTed Kremenek *
123d2eed823d534ee370cfd7742c1e96ab3ee9a80bTed Kremenek * Unless required by applicable law or agreed to in writing, software
133d2eed823d534ee370cfd7742c1e96ab3ee9a80bTed Kremenek * distributed under the License is distributed on an "AS IS" BASIS,
143d2eed823d534ee370cfd7742c1e96ab3ee9a80bTed Kremenek * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1555fc873017f10f6f566b182b70f6fc22aefa3464Chandler Carruth * See the License for the specific language governing permissions and
16651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines * limitations under the License.
1772919a334752bc87001a7e3a0b6e5892768fac20Ted Kremenek */
1872919a334752bc87001a7e3a0b6e5892768fac20Ted Kremenek/*
19f85e193739c953358c865005855253af4f68a497John McCall * $Id: FuncExtFunction.java 468655 2006-10-28 07:12:06Z minchau $
2072919a334752bc87001a7e3a0b6e5892768fac20Ted Kremenek */
21651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinespackage org.apache.xpath.functions;
2272919a334752bc87001a7e3a0b6e5892768fac20Ted Kremenek
2355fc873017f10f6f566b182b70f6fc22aefa3464Chandler Carruthimport java.util.Vector;
2472919a334752bc87001a7e3a0b6e5892768fac20Ted Kremenek
2555fc873017f10f6f566b182b70f6fc22aefa3464Chandler Carruthimport org.apache.xalan.res.XSLMessages;
2655fc873017f10f6f566b182b70f6fc22aefa3464Chandler Carruthimport org.apache.xpath.Expression;
273d2eed823d534ee370cfd7742c1e96ab3ee9a80bTed Kremenekimport org.apache.xpath.ExpressionNode;
283d2eed823d534ee370cfd7742c1e96ab3ee9a80bTed Kremenekimport org.apache.xpath.ExpressionOwner;
293d2eed823d534ee370cfd7742c1e96ab3ee9a80bTed Kremenekimport org.apache.xpath.ExtensionsProvider;
30651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesimport org.apache.xpath.XPathContext;
31651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesimport org.apache.xpath.XPathVisitor;
32651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesimport org.apache.xpath.objects.XNull;
33651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesimport org.apache.xpath.objects.XObject;
34651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesimport org.apache.xpath.res.XPATHErrorResources;
35651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesimport org.apache.xpath.res.XPATHMessages;
36651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
37651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines/**
38651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines * An object of this class represents an extension call expression.  When
39651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines * the expression executes, it calls ExtensionsTable#extFunction, and then
40651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines * converts the result to the appropriate XObject.
41651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines * @xsl.usage advanced
42651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines */
43651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinespublic class FuncExtFunction extends Function
44651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines{
45651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    static final long serialVersionUID = 5196115554693708718L;
46651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
47651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  /**
48651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines   * The namespace for the extension function, which should not normally
49651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines   *  be null or empty.
50651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines   *  @serial
51651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines   */
52651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  String m_namespace;
53651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
54651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  /**
55651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines   * The local name of the extension.
56651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines   *  @serial
57651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines   */
58651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  String m_extensionName;
59651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
60651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  /**
61651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines   * Unique method key, which is passed to ExtensionsTable#extFunction in
626bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines   *  order to allow caching of the method.
636bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines   *  @serial
646bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines   */
656bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  Object m_methodKey;
666bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines
676bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  /**
686bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines   * Array of static expressions which represent the parameters to the
696bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines   *  function.
706bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines   *  @serial
716bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines   */
726bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  Vector m_argVec = new Vector();
73651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
746bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  /**
756bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines   * This function is used to fixup variables from QNames to stack frame
766bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines   * indexes at stylesheet build time.
776bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines   * @param vars List of QNames that correspond to variables.  This list
786bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines   * should be searched backwards for the first qualified name that
796bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines   * corresponds to the variable reference qname.  The position of the
806bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines   * QName in the vector from the start of the vector will be its position
816bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines   * in the stack frame (but variables above the globalsTop value will need
826bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines   * to be offset to the current stack frame).
83651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines   * NEEDSDOC @param globalsSize
846bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines   */
85651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  public void fixupVariables(java.util.Vector vars, int globalsSize)
866bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  {
876bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines
886bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines    if (null != m_argVec)
896bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines    {
906bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines      int nArgs = m_argVec.size();
916bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines
926bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines      for (int i = 0; i < nArgs; i++)
936bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines      {
946bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines        Expression arg = (Expression) m_argVec.elementAt(i);
956bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines
966bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines        arg.fixupVariables(vars, globalsSize);
976bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines      }
986bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines    }
996bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  }
1006bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines
1016bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  /**
1026bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines   * Return the namespace of the extension function.
1036bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines   *
1046bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines   * @return The namespace of the extension function.
1056bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines   */
1066bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  public String getNamespace()
1076bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  {
1086bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines    return m_namespace;
1096bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  }
110651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
111651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  /**
1126bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines   * Return the name of the extension function.
113651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines   *
114651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines   * @return The name of the extension function.
115651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines   */
116651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  public String getFunctionName()
117651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  {
118651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    return m_extensionName;
119651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  }
120651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
121651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  /**
122651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines   * Return the method key of the extension function.
123651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines   *
124651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines   * @return The method key of the extension function.
125651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines   */
126651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  public Object getMethodKey()
127651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  {
128651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    return m_methodKey;
129651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  }
130651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
131651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  /**
132651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines   * Return the nth argument passed to the extension function.
133651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines   *
134651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines   * @param n The argument number index.
135651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines   * @return The Expression object at the given index.
136651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines   */
137651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  public Expression getArg(int n) {
138651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    if (n >= 0 && n < m_argVec.size())
139651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      return (Expression) m_argVec.elementAt(n);
140651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    else
141651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      return null;
142651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  }
143651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
144651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  /**
145651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines   * Return the number of arguments that were passed
146651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines   * into this extension function.
147651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines   *
148651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines   * @return The number of arguments.
149651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines   */
150651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  public int getArgCount() {
151651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    return m_argVec.size();
152651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  }
153651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
154651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  /**
155651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines   * Create a new FuncExtFunction based on the qualified name of the extension,
156651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines   * and a unique method key.
157651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines   *
158651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines   * @param namespace The namespace for the extension function, which should
159651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines   *                  not normally be null or empty.
160651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines   * @param extensionName The local name of the extension.
161651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines   * @param methodKey Unique method key, which is passed to
162651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines   *                  ExtensionsTable#extFunction in order to allow caching
163651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines   *                  of the method.
164651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines   */
165651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  public FuncExtFunction(java.lang.String namespace,
166651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines                         java.lang.String extensionName, Object methodKey)
1676bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  {
1686bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines    //try{throw new Exception("FuncExtFunction() " + namespace + " " + extensionName);} catch (Exception e){e.printStackTrace();}
1696bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines    m_namespace = namespace;
170651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    m_extensionName = extensionName;
171651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    m_methodKey = methodKey;
172651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  }
173651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
174651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  /**
175651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines   * Execute the function.  The function must return
176651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines   * a valid object.
1776bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines   * @param xctxt The current execution context.
178651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines   * @return A valid XObject.
179651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines   *
180651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines   * @throws javax.xml.transform.TransformerException
181651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines   */
182651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  public XObject execute(XPathContext xctxt)
183651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines          throws javax.xml.transform.TransformerException
184651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  {
185651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    if (xctxt.isSecureProcessing())
186651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      throw new javax.xml.transform.TransformerException(
187651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines        XPATHMessages.createXPATHMessage(
188651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines          XPATHErrorResources.ER_EXTENSION_FUNCTION_CANNOT_BE_INVOKED,
189651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines          new Object[] {toString()}));
190651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
191651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    XObject result;
192651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    Vector argVec = new Vector();
193651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    int nArgs = m_argVec.size();
194651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
195651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    for (int i = 0; i < nArgs; i++)
196651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    {
197651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      Expression arg = (Expression) m_argVec.elementAt(i);
198651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
199651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      XObject xobj = arg.execute(xctxt);
200651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      /*
201651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines       * Should cache the arguments for func:function
202651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines       */
203651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      xobj.allowDetachToRelease(false);
204651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      argVec.addElement(xobj);
205651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    }
206651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    //dml
207651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    ExtensionsProvider extProvider = (ExtensionsProvider)xctxt.getOwnerObject();
208651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    Object val = extProvider.extFunction(this, argVec);
209651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
210651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    if (null != val)
211651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    {
212651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      result = XObject.create(val, xctxt);
213651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    }
214651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    else
215651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    {
216651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      result = new XNull();
217651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    }
218651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
219651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    return result;
220651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  }
221651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
222651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  /**
223651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines   * Set an argument expression for a function.  This method is called by the
224651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines   * XPath compiler.
225651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines   *
226651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines   * @param arg non-null expression that represents the argument.
227651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines   * @param argNum The argument number index.
228651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines   *
229651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines   * @throws WrongNumberArgsException If the argNum parameter is beyond what
230651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines   * is specified for this function.
231651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines   */
232651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  public void setArg(Expression arg, int argNum)
233651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines          throws WrongNumberArgsException
234651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  {
235651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    m_argVec.addElement(arg);
236651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    arg.exprSetParent(this);
237651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  }
238651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
239651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  /**
240651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines   * Check that the number of arguments passed to this function is correct.
241651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines   *
242651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines   *
243651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines   * @param argNum The number of arguments that is being passed to the function.
244651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines   *
245651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines   * @throws WrongNumberArgsException
246651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines   */
247651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  public void checkNumberArgs(int argNum) throws WrongNumberArgsException{}
248651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
249651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
250651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  class ArgExtOwner implements ExpressionOwner
251651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  {
252651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
253651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    Expression m_exp;
254651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
255651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  	ArgExtOwner(Expression exp)
256651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  	{
257651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  		m_exp = exp;
258651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  	}
259651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
260651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    /**
261651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines     * @see ExpressionOwner#getExpression()
262651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines     */
263651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    public Expression getExpression()
264651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    {
265651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      return m_exp;
266651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    }
267651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
268651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
269651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    /**
270651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines     * @see ExpressionOwner#setExpression(Expression)
271651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines     */
2720f3b4ca1764cd6d457f511d340fba504f41763c3Ted Kremenek    public void setExpression(Expression exp)
273651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    {
274651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    	exp.exprSetParent(FuncExtFunction.this);
2750f3b4ca1764cd6d457f511d340fba504f41763c3Ted Kremenek    	m_exp = exp;
276651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    }
277651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  }
278651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
279651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
280651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  /**
281651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines   * Call the visitors for the function arguments.
2820f3b4ca1764cd6d457f511d340fba504f41763c3Ted Kremenek   */
283651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  public void callArgVisitors(XPathVisitor visitor)
2840f3b4ca1764cd6d457f511d340fba504f41763c3Ted Kremenek  {
285651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      for (int i = 0; i < m_argVec.size(); i++)
286651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      {
287651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines         Expression exp = (Expression)m_argVec.elementAt(i);
288651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines         exp.callVisitors(new ArgExtOwner(exp), visitor);
289651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      }
290651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
291651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  }
292651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
293651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  /**
294651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines   * Set the parent node.
295651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines   * For an extension function, we also need to set the parent
296651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines   * node for all argument expressions.
297651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines   *
298651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines   * @param n The parent node
299651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines   */
300651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  public void exprSetParent(ExpressionNode n)
301651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  {
302651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
303651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    super.exprSetParent(n);
304651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
305651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    int nArgs = m_argVec.size();
306651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
307651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    for (int i = 0; i < nArgs; i++)
308651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    {
309651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      Expression arg = (Expression) m_argVec.elementAt(i);
310651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
311651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      arg.exprSetParent(n);
312651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    }
313651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  }
314651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
315651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  /**
316651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines   * Constructs and throws a WrongNumberArgException with the appropriate
317651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines   * message for this function object.  This class supports an arbitrary
318651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines   * number of arguments, so this method must never be called.
319651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines   *
320651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines   * @throws WrongNumberArgsException
321651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines   */
322651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  protected void reportWrongNumberArgs() throws WrongNumberArgsException {
323651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    String fMsg = XSLMessages.createXPATHMessage(
324651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines        XPATHErrorResources.ER_INCORRECT_PROGRAMMER_ASSERTION,
325651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines        new Object[]{ "Programmer's assertion:  the method FunctionMultiArgs.reportWrongNumberArgs() should never be called." });
326651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
327651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    throw new RuntimeException(fMsg);
328651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  }
329651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
330651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  /**
331651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines   * Return the name of the extesion function in string format
332651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines   */
333651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  public String toString()
334651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  {
335651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    if (m_namespace != null && m_namespace.length() > 0)
336651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      return "{" + m_namespace + "}" + m_extensionName;
337651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    else
338651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      return m_extensionName;
339651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  }
340651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines}
341651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines