KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > net > sf > saxon > functions > ExecutableFunctionLibrary


1 package net.sf.saxon.functions;
2
3 import net.sf.saxon.Configuration;
4 import net.sf.saxon.expr.Expression;
5 import net.sf.saxon.expr.UserFunctionCall;
6 import net.sf.saxon.instruct.UserFunction;
7 import net.sf.saxon.trans.IndependentContext;
8 import net.sf.saxon.trans.XPathException;
9
10 import java.util.HashMap JavaDoc;
11
12 /**
13  * An ExecutableFunctionLibrary is a function library that contains definitions of functions for use at
14  * run-time. Normally functions are bound at compile-time; however there are various situations in which
15  * the information is needed dynamically, for example (a) to support the XSLT function-available() call
16  * (in the pathological case where the argument is not known statically), (b) to allow functions to be
17  * called from saxon:evaluate(), (c) to allow functions to be called from a debugging breakpoint.
18  *
19  * The objects actually held in the ExecutableFunctionLibrary are UserFunctionCall objects that have been
20  * prepared at compile time. These are function calls that do full dynamic type checking: that is, they
21  * are prepared on the basis that the static types of the arguments are all "item()*", meaning that full
22  * type checking is needed at run-time.
23  */

24
25 public class ExecutableFunctionLibrary implements FunctionLibrary {
26
27     private Configuration config;
28     private HashMap JavaDoc functions = new HashMap JavaDoc(20);
29     // The key of the hash table is a Long containing the arity in the top half, and the
30
// fingerprint of the function name in the bottom half. The value is a UserFunction object.
31

32     public ExecutableFunctionLibrary(Configuration config) {
33         this.config = config;
34     }
35
36     /**
37      * Register a function with the function library
38      */

39
40     public void addFunction(UserFunction fn) {
41         long key = ((long)fn.getNumberOfArguments())<<32 | (fn.getFunctionNameCode() & 0xfffff);
42         functions.put(new Long JavaDoc(key), fn);
43     }
44
45     /**
46      * Test whether a function with a given name and arity is available. This supports
47      * the function-available() function in XSLT.
48      * @param uri The URI of the function name
49      * @param local The local part of the function name
50      * @param arity The number of arguments. This is set to -1 in the case of the single-argument
51      * function-available() function; in this case the method should return true if there is some
52      * matching extension function, regardless of its arity.
53      */

54
55     public boolean isAvailable(int fingerprint, String JavaDoc uri, String JavaDoc local, int arity) {
56         if (arity == -1) {
57             for (int i=0; i<=20; i++) {
58                 if (isAvailable(fingerprint, uri, local, i)) {
59                     return true;
60                 }
61             }
62             return false;
63         }
64         long key = ((long)arity)<<32 | fingerprint;
65         return functions.get(new Long JavaDoc(key)) != null;
66     }
67
68     /**
69      * Bind a function, given the URI and local parts of the function name,
70      * and the list of expressions supplied as arguments. This method is called at compile
71      * time.
72      * @param nameCode The namepool nameCode of the function name. The uri and local name are also
73      * supplied (redundantly) to avoid fetching them from the name pool.
74      * @param uri The URI of the function name
75      * @param local The local part of the function name
76      * @param staticArgs The expressions supplied statically in the function call. The intention is
77      * that the static type of the arguments (obtainable via getItemType() and getCardinality() may
78      * be used as part of the binding algorithm.
79      * @return An object representing the extension function to be called, if one is found;
80      * null if no extension function was found matching the required name and arity.
81      * @throws net.sf.saxon.trans.XPathException if a function is found with the required name and arity, but
82      * the implementation of the function cannot be loaded or used; or if an error occurs
83      * while searching for the function; or if this function library "owns" the namespace containing
84      * the function call, but no function was found.
85      */

86
87     public Expression bind(int nameCode, String JavaDoc uri, String JavaDoc local, Expression[] staticArgs)
88             throws XPathException {
89         long key = ((long)staticArgs.length)<<32 | (nameCode & 0xfffff);
90         UserFunction fn = (UserFunction)functions.get(new Long JavaDoc(key));
91         if (fn == null) {
92             return null;
93         }
94         IndependentContext env = new IndependentContext(config); // this is needed only for the name pool
95
UserFunctionCall fc = new UserFunctionCall();
96         fc.setFunctionNameCode(nameCode);
97         fc.setArguments(staticArgs);
98         fc.setFunction(fn, env);
99         fc.checkFunctionCall(fn, env);
100         fc.setStaticType(fn.getResultType());
101         return fc;
102     }
103
104     /**
105      * This method creates a copy of a FunctionLibrary: if the original FunctionLibrary allows
106      * new functions to be added, then additions to this copy will not affect the original, or
107      * vice versa.
108      *
109      * @return a copy of this function library. This must be an instance of the original class.
110      */

111
112     public FunctionLibrary copy() {
113         ExecutableFunctionLibrary efl = new ExecutableFunctionLibrary(config);
114         efl.functions = new HashMap JavaDoc(functions);
115         return efl;
116     }
117
118 }
119
120 //
121
// The contents of this file are subject to the Mozilla Public License Version 1.0 (the "License");
122
// you may not use this file except in compliance with the License. You may obtain a copy of the
123
// License at http://www.mozilla.org/MPL/
124
//
125
// Software distributed under the License is distributed on an "AS IS" basis,
126
// WITHOUT WARRANTY OF ANY KIND, either express or implied.
127
// See the License for the specific language governing rights and limitations under the License.
128
//
129
// The Original Code is: all this file.
130
//
131
// The Initial Developer of the Original Code is Michael H. Kay.
132
//
133
// Portions created by (your name) are Copyright (C) (your legal entity). All Rights Reserved.
134
//
135
// Contributor(s): none.
136
//
Popular Tags