KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > xpath > functions > FuncExtFunction


1 /*
2  * Copyright 1999-2004 The Apache Software Foundation.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */

16 /*
17  * $Id: FuncExtFunction.java,v 1.24 2004/02/17 04:34:01 minchau Exp $
18  */

19 package org.apache.xpath.functions;
20
21 import java.util.Vector JavaDoc;
22
23 import org.apache.xalan.res.XSLMessages;
24 import org.apache.xpath.Expression;
25 import org.apache.xpath.ExpressionNode;
26 import org.apache.xpath.ExpressionOwner;
27 import org.apache.xpath.ExtensionsProvider;
28 import org.apache.xpath.XPathContext;
29 import org.apache.xpath.XPathVisitor;
30 import org.apache.xpath.objects.XNull;
31 import org.apache.xpath.objects.XObject;
32 import org.apache.xpath.res.XPATHErrorResources;
33
34 /**
35  * An object of this class represents an extension call expression. When
36  * the expression executes, it calls ExtensionsTable#extFunction, and then
37  * converts the result to the appropriate XObject.
38  * @xsl.usage advanced
39  */

40 public class FuncExtFunction extends Function
41 {
42
43   /**
44    * The namespace for the extension function, which should not normally
45    * be null or empty.
46    * @serial
47    */

48   String JavaDoc m_namespace;
49
50   /**
51    * The local name of the extension.
52    * @serial
53    */

54   String JavaDoc m_extensionName;
55
56   /**
57    * Unique method key, which is passed to ExtensionsTable#extFunction in
58    * order to allow caching of the method.
59    * @serial
60    */

61   Object JavaDoc m_methodKey;
62
63   /**
64    * Array of static expressions which represent the parameters to the
65    * function.
66    * @serial
67    */

68   Vector JavaDoc m_argVec = new Vector JavaDoc();
69
70   /**
71    * This function is used to fixup variables from QNames to stack frame
72    * indexes at stylesheet build time.
73    * @param vars List of QNames that correspond to variables. This list
74    * should be searched backwards for the first qualified name that
75    * corresponds to the variable reference qname. The position of the
76    * QName in the vector from the start of the vector will be its position
77    * in the stack frame (but variables above the globalsTop value will need
78    * to be offset to the current stack frame).
79    * NEEDSDOC @param globalsSize
80    */

81   public void fixupVariables(java.util.Vector JavaDoc vars, int globalsSize)
82   {
83
84     if (null != m_argVec)
85     {
86       int nArgs = m_argVec.size();
87
88       for (int i = 0; i < nArgs; i++)
89       {
90         Expression arg = (Expression) m_argVec.elementAt(i);
91
92         arg.fixupVariables(vars, globalsSize);
93       }
94     }
95   }
96   
97   /**
98    * Return the namespace of the extension function.
99    *
100    * @return The namespace of the extension function.
101    */

102   public String JavaDoc getNamespace()
103   {
104     return m_namespace;
105   }
106   
107   /**
108    * Return the name of the extension function.
109    *
110    * @return The name of the extension function.
111    */

112   public String JavaDoc getFunctionName()
113   {
114     return m_extensionName;
115   }
116   
117   /**
118    * Return the method key of the extension function.
119    *
120    * @return The method key of the extension function.
121    */

122   public Object JavaDoc getMethodKey()
123   {
124     return m_methodKey;
125   }
126
127   /**
128    * Return the nth argument passed to the extension function.
129    *
130    * @param n The argument number index.
131    * @return The Expression object at the given index.
132    */

133   public Expression getArg(int n) {
134     if (n >= 0 && n < m_argVec.size())
135       return (Expression) m_argVec.elementAt(n);
136     else
137       return null;
138   }
139
140   /**
141    * Return the number of arguments that were passed
142    * into this extension function.
143    *
144    * @return The number of arguments.
145    */

146   public int getArgCount() {
147     return m_argVec.size();
148   }
149
150   /**
151    * Create a new FuncExtFunction based on the qualified name of the extension,
152    * and a unique method key.
153    *
154    * @param namespace The namespace for the extension function, which should
155    * not normally be null or empty.
156    * @param extensionName The local name of the extension.
157    * @param methodKey Unique method key, which is passed to
158    * ExtensionsTable#extFunction in order to allow caching
159    * of the method.
160    */

161   public FuncExtFunction(java.lang.String JavaDoc namespace,
162                          java.lang.String JavaDoc extensionName, Object JavaDoc methodKey)
163   {
164     //try{throw new Exception("FuncExtFunction() " + namespace + " " + extensionName);} catch (Exception e){e.printStackTrace();}
165
m_namespace = namespace;
166     m_extensionName = extensionName;
167     m_methodKey = methodKey;
168   }
169
170   /**
171    * Execute the function. The function must return
172    * a valid object.
173    * @param xctxt The current execution context.
174    * @return A valid XObject.
175    *
176    * @throws javax.xml.transform.TransformerException
177    */

178   public XObject execute(XPathContext xctxt)
179           throws javax.xml.transform.TransformerException JavaDoc
180   {
181
182     XObject result;
183     Vector JavaDoc argVec = new Vector JavaDoc();
184     int nArgs = m_argVec.size();
185
186     for (int i = 0; i < nArgs; i++)
187     {
188       Expression arg = (Expression) m_argVec.elementAt(i);
189       
190       XObject xobj = arg.execute(xctxt);
191       /*
192        * Should cache the arguments for func:function
193        */

194       xobj.allowDetachToRelease(false);
195       argVec.addElement(xobj);
196     }
197     //dml
198
ExtensionsProvider extProvider = (ExtensionsProvider)xctxt.getOwnerObject();
199     Object JavaDoc val = extProvider.extFunction(this, argVec);
200
201     if (null != val)
202     {
203       result = XObject.create(val, xctxt);
204     }
205     else
206     {
207       result = new XNull();
208     }
209
210     return result;
211   }
212
213   /**
214    * Set an argument expression for a function. This method is called by the
215    * XPath compiler.
216    *
217    * @param arg non-null expression that represents the argument.
218    * @param argNum The argument number index.
219    *
220    * @throws WrongNumberArgsException If the argNum parameter is beyond what
221    * is specified for this function.
222    */

223   public void setArg(Expression arg, int argNum)
224           throws WrongNumberArgsException
225   {
226     m_argVec.addElement(arg);
227   }
228
229   /**
230    * Check that the number of arguments passed to this function is correct.
231    *
232    *
233    * @param argNum The number of arguments that is being passed to the function.
234    *
235    * @throws WrongNumberArgsException
236    */

237   public void checkNumberArgs(int argNum) throws WrongNumberArgsException{}
238
239
240   class ArgExtOwner implements ExpressionOwner
241   {
242   
243     Expression m_exp;
244     
245     ArgExtOwner(Expression exp)
246     {
247         m_exp = exp;
248     }
249     
250     /**
251      * @see ExpressionOwner#getExpression()
252      */

253     public Expression getExpression()
254     {
255       return m_exp;
256     }
257
258
259     /**
260      * @see ExpressionOwner#setExpression(Expression)
261      */

262     public void setExpression(Expression exp)
263     {
264         exp.exprSetParent(FuncExtFunction.this);
265         m_exp = exp;
266     }
267   }
268   
269   
270   /**
271    * Call the visitors for the function arguments.
272    */

273   public void callArgVisitors(XPathVisitor visitor)
274   {
275       for (int i = 0; i < m_argVec.size(); i++)
276       {
277          Expression exp = (Expression)m_argVec.elementAt(i);
278          exp.callVisitors(new ArgExtOwner(exp), visitor);
279       }
280     
281   }
282
283   /**
284    * Set the parent node.
285    * For an extension function, we also need to set the parent
286    * node for all argument expressions.
287    *
288    * @param n The parent node
289    */

290   public void exprSetParent(ExpressionNode n)
291   {
292     
293     super.exprSetParent(n);
294       
295     int nArgs = m_argVec.size();
296
297     for (int i = 0; i < nArgs; i++)
298     {
299       Expression arg = (Expression) m_argVec.elementAt(i);
300
301       arg.exprSetParent(n);
302     }
303   }
304
305   /**
306    * Constructs and throws a WrongNumberArgException with the appropriate
307    * message for this function object. This class supports an arbitrary
308    * number of arguments, so this method must never be called.
309    *
310    * @throws WrongNumberArgsException
311    */

312   protected void reportWrongNumberArgs() throws WrongNumberArgsException {
313     String JavaDoc fMsg = XSLMessages.createXPATHMessage(
314         XPATHErrorResources.ER_INCORRECT_PROGRAMMER_ASSERTION,
315         new Object JavaDoc[]{ "Programmer's assertion: the method FunctionMultiArgs.reportWrongNumberArgs() should never be called." });
316
317     throw new RuntimeException JavaDoc(fMsg);
318   }
319 }
320
Popular Tags