001: package net.sf.saxon.query;
002:
003: import net.sf.saxon.functions.FunctionLibrary;
004: import net.sf.saxon.expr.Expression;
005: import net.sf.saxon.trans.XPathException;
006:
007: import java.util.HashSet;
008: import java.util.Iterator;
009:
010: /**
011: * This implementation of FunctionLibrary contains all the functions imported into a Query Module.
012: * It is implemented as a view of the "global" XQueryFunctionLibrary for the whole query, selecting
013: * only those functions that are in an imported namespace.
014: */
015:
016: public class ImportedFunctionLibrary implements FunctionLibrary,
017: XQueryFunctionBinder {
018:
019: XQueryFunctionLibrary baseLibrary;
020: HashSet namespaces = new HashSet(5);
021:
022: public ImportedFunctionLibrary(XQueryFunctionLibrary baseLibrary) {
023: this .baseLibrary = baseLibrary;
024: }
025:
026: public void addImportedNamespace(String namespace) {
027: namespaces.add(namespace);
028: }
029:
030: /**
031: * Bind an extension function, given the URI and local parts of the function name,
032: * and the list of expressions supplied as arguments. This method is called at compile
033: * time.
034: *
035: * @param nameCode The namepool nameCode of the function name. The uri and local name are also
036: * supplied (redundantly) to avoid fetching them from the name pool.
037: * @param uri The URI of the function name
038: * @param local The local part of the function name
039: * @param staticArgs The expressions supplied statically in arguments to the function call.
040: * The length of this array represents the arity of the function. The intention is
041: * that the static type of the arguments (obtainable via getItemType() and getCardinality()) may
042: * be used as part of the binding algorithm. In some cases it may be possible for the function
043: * to be pre-evaluated at compile time, for example if these expressions are all constant values.
044: * <p/>
045: * The conventions of the XPath language demand that the results of a function depend only on the
046: * values of the expressions supplied as arguments, and not on the form of those expressions. For
047: * example, the result of f(4) is expected to be the same as f(2+2). The actual expression is supplied
048: * here to enable the binding mechanism to select the most efficient possible implementation (including
049: * compile-time pre-evaluation where appropriate).
050: * @return An object representing the function to be called, if one is found;
051: * null if no function was found matching the required name and arity.
052: * @throws net.sf.saxon.trans.XPathException
053: * if a function is found with the required name and arity, but
054: * the implementation of the function cannot be loaded or used; or if an error occurs
055: * while searching for the function.
056: */
057:
058: public Expression bind(int nameCode, String uri, String local,
059: Expression[] staticArgs) throws XPathException {
060: if (namespaces.contains(uri)) {
061: return baseLibrary.bind(nameCode, uri, local, staticArgs);
062: } else {
063: return null;
064: }
065: }
066:
067: /**
068: * Get the function declaration corresponding to a given function name and arity
069: * @return the XQueryFunction if there is one, or null if not.
070: */
071:
072: public XQueryFunction getDeclaration(int nameCode, String uri,
073: String local, Expression[] staticArgs) {
074: if (namespaces.contains(uri)) {
075: return baseLibrary.getDeclaration(nameCode, uri, local,
076: staticArgs);
077: } else {
078: return null;
079: }
080: }
081:
082: /**
083: * This method creates a copy of a FunctionLibrary: if the original FunctionLibrary allows
084: * new functions to be added, then additions to this copy will not affect the original, or
085: * vice versa.
086: *
087: * @return a copy of this function library. This must be an instance of the original class.
088: */
089:
090: public FunctionLibrary copy() {
091: ImportedFunctionLibrary lib = new ImportedFunctionLibrary(
092: baseLibrary);
093: Iterator iter = namespaces.iterator();
094: while (iter.hasNext()) {
095: String ns = (String) iter.next();
096: lib.addImportedNamespace(ns);
097: }
098: return lib;
099: }
100:
101: /**
102: * Test whether an extension function with a given name and arity is available. This supports
103: * the function-available() function in XSLT. This method may be called either at compile time
104: * or at run time. If the function library is to be used only in an XQuery or free-standing XPath
105: * environment, this method may throw an UnsupportedOperationException.
106: *
107: * @param fingerprint The namepool fingerprint of the function name. This must match the
108: * uri and localName; the information is provided redundantly to avoid repeated lookups in the name pool.
109: * @param uri The URI of the function name
110: * @param local The local part of the function name
111: * @param arity The number of arguments. This is set to -1 in the case of the single-argument
112: * function-available() function; in this case the method should return true if there is some
113: * matching extension function, regardless of its arity.
114: */
115:
116: public boolean isAvailable(int fingerprint, String uri,
117: String local, int arity) {
118: if (namespaces.contains(uri)) {
119: return baseLibrary.isAvailable(fingerprint, uri, local,
120: arity);
121: } else {
122: return false;
123: }
124: }
125: }
126:
127: //
128: // The contents of this file are subject to the Mozilla Public License Version 1.0 (the "License");
129: // you may not use this file except in compliance with the License. You may obtain a copy of the
130: // License at http://www.mozilla.org/MPL/
131: //
132: // Software distributed under the License is distributed on an "AS IS" basis,
133: // WITHOUT WARRANTY OF ANY KIND, either express or implied.
134: // See the License for the specific language governing rights and limitations under the License.
135: //
136: // The Original Code is: all this file.
137: //
138: // The Initial Developer of the Original Code is Michael H. Kay.
139: //
140: // Portions created by (your name) are Copyright (C) (your legal entity). All Rights Reserved.
141: //
142: // Contributor(s): none.
143: //
|