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