001: package net.sf.saxon.style;
002:
003: import net.sf.saxon.expr.Expression;
004: import net.sf.saxon.expr.UserFunctionCall;
005: import net.sf.saxon.functions.FunctionLibrary;
006: import net.sf.saxon.trans.XPathException;
007:
008: /**
009: * A StylesheetFunctionLibrary contains functions defined by the user in a stylesheet. This library is used at
010: * compile time only, as it contains references to the actual XSLFunction objects. Binding to a function in this
011: * library registers the function call on a fix-up list to be notified when the actual compiled function becomes
012: * available.
013: */
014:
015: public class StylesheetFunctionLibrary implements FunctionLibrary {
016:
017: private XSLStylesheet stylesheet;
018: private boolean overriding;
019:
020: /**
021: * Create a FunctionLibrary that provides access to stylesheet functions
022: * @param sheet The XSLStylesheet element of the principal stylesheet module
023: * @param overriding set to true if this library is to contain functions specifying override="yes",
024: * or to false if it is to contain functions specifying override="no". (XSLT uses two instances
025: * of this class, one for overriding functions and one for non-overriding functions.)
026: */
027: public StylesheetFunctionLibrary(XSLStylesheet sheet,
028: boolean overriding) {
029: this .stylesheet = sheet;
030: this .overriding = overriding;
031: }
032:
033: /**
034: * Test whether a Saxon function with a given name and arity is available. This supports
035: * the function-available() function in XSLT.
036: * @param uri The URI of the function name
037: * @param local The local part of the function name
038: * @param arity The number of arguments. This is set to -1 in the case of the single-argument
039: * function-available() function; in this case the method should return true if there is some
040: * matching extension function, regardless of its arity.
041: */
042:
043: public boolean isAvailable(int fingerprint, String uri,
044: String local, int arity) {
045: XSLFunction fn = stylesheet.getStylesheetFunction(fingerprint,
046: arity);
047: return (fn != null);
048: }
049:
050: /**
051: * Bind a function, given the URI and local parts of the function name,
052: * and the list of expressions supplied as arguments. This method is called at compile
053: * time.
054: * @param nameCode The namepool nameCode of the function name. The uri and local name are also
055: * supplied (redundantly) to avoid fetching them from the name pool.
056: * @param uri The URI of the function name
057: * @param local The local part of the function name
058: * @param staticArgs The expressions supplied statically in the function call. The intention is
059: * that the static type of the arguments (obtainable via getItemType() and getCardinality() may
060: * be used as part of the binding algorithm.
061: * @return An object representing the extension function to be called, if one is found;
062: * null if no extension function was found matching the required name and arity.
063: * @throws net.sf.saxon.trans.XPathException if a function is found with the required name and arity, but
064: * the implementation of the function cannot be loaded or used; or if an error occurs
065: * while searching for the function; or if this function library "owns" the namespace containing
066: * the function call, but no function was found.
067: */
068:
069: public Expression bind(int nameCode, String uri, String local,
070: Expression[] staticArgs) throws XPathException {
071: int fingerprint = nameCode & 0xfffff;
072: XSLFunction fn = stylesheet.getStylesheetFunction(fingerprint,
073: staticArgs.length);
074: if (fn == null) {
075: return null;
076: }
077: if (fn.isOverriding() != overriding) {
078: return null;
079: }
080: UserFunctionCall fc = new UserFunctionCall();
081: fn.registerReference(fc);
082: fc.setFunctionNameCode(nameCode);
083: fc.setArguments(staticArgs);
084: fc.setConfirmed(true);
085: return fc;
086: }
087:
088: /**
089: * This method creates a copy of a FunctionLibrary: if the original FunctionLibrary allows
090: * new functions to be added, then additions to this copy will not affect the original, or
091: * vice versa.
092: *
093: * @return a copy of this function library. This must be an instance of the original class.
094: */
095:
096: public FunctionLibrary copy() {
097: return this ;
098: }
099:
100: }
101: //
102: // The contents of this file are subject to the Mozilla Public License Version 1.0 (the "License");
103: // you may not use this file except in compliance with the License. You may obtain a copy of the
104: // License at http://www.mozilla.org/MPL/
105: //
106: // Software distributed under the License is distributed on an "AS IS" basis,
107: // WITHOUT WARRANTY OF ANY KIND, either express or implied.
108: // See the License for the specific language governing rights and limitations under the License.
109: //
110: // The Original Code is: all this file.
111: //
112: // The Initial Developer of the Original Code is Michael H. Kay.
113: //
114: // Portions created by (your name) are Copyright (C) (your legal entity). All Rights Reserved.
115: //
116: // Contributor(s): none.
117: //
|