001: package net.sf.saxon.functions;
002:
003: import net.sf.saxon.Configuration;
004: import net.sf.saxon.expr.CastExpression;
005: import net.sf.saxon.expr.Expression;
006: import net.sf.saxon.om.NamespaceConstant;
007: import net.sf.saxon.style.StandardNames;
008: import net.sf.saxon.trans.StaticError;
009: import net.sf.saxon.trans.XPathException;
010: import net.sf.saxon.type.AtomicType;
011: import net.sf.saxon.type.SchemaType;
012: import net.sf.saxon.type.Type;
013:
014: /**
015: * The ConstructorFunctionLibrary represents the collection of constructor functions for atomic types. These
016: * are provided for the built-in types such as xs:integer and xs:date, and also for user-defined atomic types.
017: */
018:
019: public class ConstructorFunctionLibrary implements FunctionLibrary {
020:
021: private Configuration config;
022:
023: /**
024: * Create a SystemFunctionLibrary
025: * @param config the Configuration
026: */
027:
028: public ConstructorFunctionLibrary(Configuration config) {
029: this .config = config;
030: }
031:
032: /**
033: * Test whether a system function with a given name and arity is available. This supports
034: * the function-available() function in XSLT. This method may be called either at compile time
035: * or at run time.
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: if (arity != 1 && arity != -1) {
046: return false;
047: }
048: if (uri.equals(NamespaceConstant.SCHEMA)) {
049: AtomicType type = (AtomicType) Type.getBuiltInItemType(uri,
050: local);
051: return type != null
052: && type.getFingerprint() != StandardNames.XS_NOTATION;
053: } else if (NamespaceConstant.isXDTNamespace(uri)) {
054: AtomicType type = (AtomicType) Type.getBuiltInItemType(
055: NamespaceConstant.XDT, local);
056: return type != null
057: && type.getFingerprint() != StandardNames.XDT_ANY_ATOMIC_TYPE;
058: }
059:
060: SchemaType st = config.getSchemaType(fingerprint);
061: return (st != null && st instanceof AtomicType);
062: }
063:
064: /**
065: * Bind an extension function, given the URI and local parts of the function name,
066: * and the list of expressions supplied as arguments. This method is called at compile
067: * time.
068: * @param uri The URI of the function name
069: * @param localName The local part of the function name
070: * @param arguments The expressions supplied statically in the function call. The intention is
071: * that the static type of the arguments (obtainable via getItemType() and getCardinality() may
072: * be used as part of the binding algorithm.
073: * @return An object representing the extension function to be called, if one is found;
074: * null if no extension function was found matching the required name and arity.
075: * @throws net.sf.saxon.trans.XPathException if a function is found with the required name and arity, but
076: * the implementation of the function cannot be loaded or used; or if an error occurs
077: * while searching for the function; or if this function library "owns" the namespace containing
078: * the function call, but no function was found.
079: */
080:
081: public Expression bind(int nameCode, String uri, String localName,
082: Expression[] arguments) throws XPathException {
083: String targetURI = uri;
084: boolean builtInNamespace = uri.equals(NamespaceConstant.SCHEMA);
085: if (!builtInNamespace && NamespaceConstant.isXDTNamespace(uri)) {
086: targetURI = NamespaceConstant.XDT;
087: builtInNamespace = true;
088: }
089: if (builtInNamespace) {
090: // it's a constructor function: treat it as shorthand for a cast expression
091: if (arguments.length != 1) {
092: throw new StaticError(
093: "A constructor function must have exactly one argument");
094: }
095: AtomicType type = (AtomicType) Type.getBuiltInItemType(
096: targetURI, localName);
097: if (type == null
098: || type.getFingerprint() == StandardNames.XDT_ANY_ATOMIC_TYPE
099: || type.getFingerprint() == StandardNames.XS_NOTATION) {
100: StaticError err = new StaticError(
101: "Unknown constructor function: {" + uri + '}'
102: + localName);
103: err.setErrorCode("XPST0017");
104: throw err;
105: }
106:
107: return new CastExpression(arguments[0], type, true);
108: }
109:
110: // Now see if it's a constructor function for a user-defined type
111:
112: if (arguments.length == 1) {
113: SchemaType st = config.getSchemaType(nameCode & 0xfffff);
114: if (st != null && st instanceof AtomicType) {
115: return new CastExpression(arguments[0],
116: (AtomicType) st, true);
117: }
118: }
119:
120: return null;
121: }
122:
123: /**
124: * This method creates a copy of a FunctionLibrary: if the original FunctionLibrary allows
125: * new functions to be added, then additions to this copy will not affect the original, or
126: * vice versa.
127: *
128: * @return a copy of this function library. This must be an instance of the original class.
129: */
130:
131: public FunctionLibrary copy() {
132: return this ;
133: }
134:
135: }
136: //
137: // The contents of this file are subject to the Mozilla Public License Version 1.0 (the "License");
138: // you may not use this file except in compliance with the License. You may obtain a copy of the
139: // License at http://www.mozilla.org/MPL/
140: //
141: // Software distributed under the License is distributed on an "AS IS" basis,
142: // WITHOUT WARRANTY OF ANY KIND, either express or implied.
143: // See the License for the specific language governing rights and limitations under the License.
144: //
145: // The Original Code is: all this file.
146: //
147: // The Initial Developer of the Original Code is Michael H. Kay.
148: //
149: // Portions created by (your name) are Copyright (C) (your legal entity). All Rights Reserved.
150: //
151: // Contributor(s): none.
152: //
|