package client.net.sf.saxon.ce.functions;
import client.net.sf.saxon.ce.om.StandardNames;
import client.net.sf.saxon.ce.value.EmptySequence;
import client.net.sf.saxon.ce.value.SequenceType;
import client.net.sf.saxon.ce.value.Value;
import java.util.HashMap;
import com.google.gwt.logging.client.LogConfiguration;
/**
* This class contains static data tables defining the properties of standard functions. "Standard functions"
* here means the XPath 2.0 functions, the XSLT 2.0 functions, and a few selected extension functions
* which need special recognition.
*/
public abstract class StandardFunction {
public static Value EMPTY = EmptySequence.getInstance();
/**
* Categories of functions, bit significant
*/
public static final int CORE = 1;
public static final int XSLT = 2;
public static final int USE_WHEN = 4;
/**
* This class is never instantiated
*/
private StandardFunction() {
}
/**
* Register a system function in the table of function details.
*
* @param name the function name
* @param skeleton instance of the class used to implement the function
* @param type the sequence type of the result of the function
* @return the entry describing the function. The entry is incomplete, it does not yet contain information
* about the function arguments.
*/
public static Entry register(String name,
SystemFunction skeleton,
SequenceType type
) {
Entry e = makeEntry(name, skeleton, type, CORE);
functionTable.put(name, e);
return e;
}
/**
* Make a table entry describing the signature of a function, with a reference to the implementation class.
*
* @param name the function name
* @param skeleton instance of the class used to implement the function
* @param type the sequence type of the result of the function
* @return the entry describing the function. The entry is incomplete, it does not yet contain information
* about the function arguments.
*/
public static Entry makeEntry(String name, SystemFunction skeleton,
SequenceType type, int applicability) {
Entry e = new Entry();
int hash = name.indexOf('#');
if (hash < 0) {
e.name = name;
} else {
e.name = name.substring(0, hash);
}
e.skeleton = skeleton;
e.minArguments = 0;
e.maxArguments = 0;
e.resultType = type;
e.applicability = applicability;
e.argumentTypes = new SequenceType[0];
e.sameItemTypeAsFirstArgument = false;
return e;
}
private static HashMap<String, Entry> functionTable = new HashMap<String, Entry>(200);
static {
Entry e;
e = register("abs", new Rounding(Rounding.ABS), SequenceType.OPTIONAL_NUMERIC);
e.sameItemTypeAsFirstArgument = true;
e.mandatoryArg(SequenceType.OPTIONAL_NUMERIC);
e = register("adjust-date-to-timezone", new Adjust(), SequenceType.OPTIONAL_DATE);
e.mandatoryArg(SequenceType.OPTIONAL_DATE);
e.optionalArg(SequenceType.OPTIONAL_DAY_TIME_DURATION);
e = register("adjust-dateTime-to-timezone", new Adjust(), SequenceType.OPTIONAL_DATE_TIME);
e.mandatoryArg(SequenceType.OPTIONAL_DATE_TIME);
e.optionalArg(SequenceType.OPTIONAL_DAY_TIME_DURATION);
e = register("adjust-time-to-timezone", new Adjust(), SequenceType.OPTIONAL_TIME);
e.mandatoryArg(SequenceType.OPTIONAL_TIME);
e.optionalArg(SequenceType.OPTIONAL_DAY_TIME_DURATION);
e = register("avg", new Average(), SequenceType.OPTIONAL_ATOMIC);
// can't say "same as first argument" because the avg of a set of integers is decimal
e.optionalArg(SequenceType.ATOMIC_SEQUENCE);
e = register("base-uri", new BaseURI(), SequenceType.OPTIONAL_ANY_URI);
e.mandatoryArg(SequenceType.OPTIONAL_NODE);
e = register("boolean", new BooleanFn(BooleanFn.BOOLEAN), SequenceType.SINGLE_BOOLEAN);
e.mandatoryArg(SequenceType.ANY_SEQUENCE);
e = register("ceiling", new Rounding(Rounding.CEILING), SequenceType.OPTIONAL_NUMERIC);
e.sameItemTypeAsFirstArgument = true;
e.mandatoryArg(SequenceType.OPTIONAL_NUMERIC);
e = register("codepoint-equal", new CodepointEqual(), SequenceType.OPTIONAL_BOOLEAN);
e.mandatoryArg(SequenceType.OPTIONAL_STRING);
e.mandatoryArg(SequenceType.OPTIONAL_STRING);
e = register("codepoints-to-string", new CodepointsToString(), SequenceType.SINGLE_STRING);
e.mandatoryArg(SequenceType.INTEGER_SEQUENCE);
e = register("compare", new Compare(), SequenceType.OPTIONAL_INTEGER);
e.mandatoryArg(SequenceType.OPTIONAL_STRING);
e.mandatoryArg(SequenceType.OPTIONAL_STRING);
e.optionalArg(SequenceType.SINGLE_STRING);
e = register("concat", new Concat(), SequenceType.SINGLE_STRING);
e.mandatoryArg(SequenceType.OPTIONAL_ATOMIC);
e.maxArguments = Integer.MAX_VALUE;
// Note, this has a variable number of arguments so it is treated specially
e = register("contains", new Contains(), SequenceType.SINGLE_BOOLEAN);
e.mandatoryArg(SequenceType.OPTIONAL_STRING);
e.mandatoryArg(SequenceType.OPTIONAL_STRING);
e.optionalArg(SequenceType.SINGLE_STRING);
e = register("count", new Count(), SequenceType.SINGLE_INTEGER);
e.mandatoryArg(SequenceType.ANY_SEQUENCE);
e = register("current", new Current(), SequenceType.SINGLE_ITEM);
e.applicability = XSLT;
register("current-date", new CurrentDateTime(), SequenceType.SINGLE_DATE);
register("current-dateTime", new CurrentDateTime(), SequenceType.SINGLE_DATE_TIME);
register("current-time", new CurrentDateTime(), SequenceType.SINGLE_TIME);
register("current-group", new CurrentGroup(), SequenceType.ANY_SEQUENCE);
e.applicability = XSLT;
register("current-grouping-key", new CurrentGroupingKey(),
SequenceType.OPTIONAL_ATOMIC);
e.applicability = XSLT;
e = register("dateTime", new DateTimeConstructor(), SequenceType.OPTIONAL_DATE_TIME);
e.mandatoryArg(SequenceType.OPTIONAL_DATE);
e.mandatoryArg(SequenceType.OPTIONAL_TIME);
e = register("day-from-date", new Component((Component.DAY << 16) + StandardNames.XS_DATE),
SequenceType.OPTIONAL_INTEGER);
e.mandatoryArg(SequenceType.OPTIONAL_DATE);
e = register("day-from-dateTime", new Component((Component.DAY << 16) + StandardNames.XS_DATE_TIME),
SequenceType.OPTIONAL_INTEGER);
e.mandatoryArg(SequenceType.OPTIONAL_DATE_TIME);
e = register("days-from-duration", new Component((Component.DAY << 16) + StandardNames.XS_DURATION),
SequenceType.OPTIONAL_INTEGER);
e.mandatoryArg(SequenceType.OPTIONAL_DURATION);
e = register("deep-equal", new DeepEqual(), SequenceType.SINGLE_BOOLEAN);
e.mandatoryArg(SequenceType.ANY_SEQUENCE);
e.mandatoryArg(SequenceType.ANY_SEQUENCE);
e.optionalArg(SequenceType.SINGLE_STRING);
e = register("distinct-values", new DistinctValues(), SequenceType.ATOMIC_SEQUENCE);
e.mandatoryArg(SequenceType.ATOMIC_SEQUENCE);
e.optionalArg(SequenceType.SINGLE_STRING);
e = register("doc", new Doc(), SequenceType.OPTIONAL_DOCUMENT);
e.mandatoryArg(SequenceType.OPTIONAL_STRING);
e = register("doc-available", new DocAvailable(), SequenceType.SINGLE_BOOLEAN);
e.mandatoryArg(SequenceType.OPTIONAL_STRING);
e = register("document", new DocumentFn(), SequenceType.NODE_SEQUENCE);
e.applicability = XSLT;
e.mandatoryArg(SequenceType.ANY_SEQUENCE);
e.optionalArg(SequenceType.SINGLE_NODE);
e = register("document-uri", new NamePart(NamePart.DOCUMENT_URI), SequenceType.OPTIONAL_ANY_URI);
e.mandatoryArg(SequenceType.NODE_SEQUENCE);
e = register("empty", new Empty(), SequenceType.SINGLE_BOOLEAN);
e.mandatoryArg(SequenceType.ANY_SEQUENCE);
e = register("ends-with", new EndsWith(), SequenceType.SINGLE_BOOLEAN);
e.mandatoryArg(SequenceType.OPTIONAL_STRING);
e.mandatoryArg(SequenceType.OPTIONAL_STRING);
e.optionalArg(SequenceType.SINGLE_STRING);
e = register("element-available", new Available(Available.ELEMENT_AVAILABLE),
SequenceType.SINGLE_BOOLEAN);
e.applicability = XSLT | USE_WHEN;
e.mandatoryArg(SequenceType.SINGLE_STRING);
e = register("element-with-id", new Id(), SequenceType.ELEMENT_SEQUENCE);
e.mandatoryArg(SequenceType.STRING_SEQUENCE);
e.optionalArg(SequenceType.SINGLE_NODE);
e = register("encode-for-uri", new EscapeURI(EscapeURI.ENCODE_FOR_URI), SequenceType.SINGLE_STRING);
e.mandatoryArg(SequenceType.OPTIONAL_STRING);
e = register("escape-html-uri", new EscapeURI(EscapeURI.HTML_URI), SequenceType.SINGLE_STRING);
e.mandatoryArg(SequenceType.OPTIONAL_STRING);
e = register("error", new Error(), SequenceType.OPTIONAL_ITEM);
// The return type is chosen so that use of the error() function will never give a static type error,
// on the basis that item()? overlaps every other type, and it's almost impossible to make any
// unwarranted inferences from it, except perhaps count(error()) lt 2.
e.optionalArg(SequenceType.OPTIONAL_QNAME);
e.optionalArg(SequenceType.SINGLE_STRING);
e.optionalArg(SequenceType.ANY_SEQUENCE);
e = register("exists", new Exists(), SequenceType.SINGLE_BOOLEAN);
e.mandatoryArg(SequenceType.ANY_SEQUENCE);
e = register("floor", new Rounding(Rounding.FLOOR), SequenceType.OPTIONAL_NUMERIC);
e.sameItemTypeAsFirstArgument = true;
e.mandatoryArg(SequenceType.OPTIONAL_NUMERIC);
e = register("format-date", new FormatDate(StandardNames.XS_DATE), SequenceType.SINGLE_STRING);
e.applicability = XSLT;
e.mandatoryArg(SequenceType.OPTIONAL_DATE);
e.mandatoryArg(SequenceType.SINGLE_STRING);
e.optionalArg(SequenceType.OPTIONAL_STRING);
e.optionalArg(SequenceType.OPTIONAL_STRING);
e.optionalArg(SequenceType.OPTIONAL_STRING);
e = register("format-dateTime", new FormatDate(StandardNames.XS_DATE_TIME), SequenceType.SINGLE_STRING);
e.applicability = XSLT;
e.mandatoryArg(SequenceType.OPTIONAL_DATE_TIME);
e.mandatoryArg(SequenceType.SINGLE_STRING);
e.optionalArg(SequenceType.OPTIONAL_STRING);
e.optionalArg(SequenceType.OPTIONAL_STRING);
e.optionalArg(SequenceType.OPTIONAL_STRING);
e = register("format-number", new FormatNumber(), SequenceType.SINGLE_STRING);
e.applicability = XSLT;
e.mandatoryArg(SequenceType.OPTIONAL_NUMERIC);
e.mandatoryArg(SequenceType.SINGLE_STRING);
e.optionalArg(SequenceType.SINGLE_STRING);
e = register("format-time", new FormatDate(StandardNames.XS_TIME), SequenceType.SINGLE_STRING);
e.applicability = XSLT;
e.mandatoryArg(SequenceType.OPTIONAL_TIME);
e.mandatoryArg(SequenceType.SINGLE_STRING);
e.optionalArg(SequenceType.OPTIONAL_STRING);
e.optionalArg(SequenceType.OPTIONAL_STRING);
e.optionalArg(SequenceType.OPTIONAL_STRING);
e = register("function-available", new Available(Available.FUNCTION_AVAILABLE), SequenceType.SINGLE_BOOLEAN);
e.applicability = XSLT | USE_WHEN;
e.mandatoryArg(SequenceType.SINGLE_STRING);
e.optionalArg(SequenceType.SINGLE_INTEGER);
e = register("generate-id", new NamePart(NamePart.GENERATE_ID), SequenceType.SINGLE_STRING);
e.applicability = XSLT;
e.mandatoryArg(SequenceType.OPTIONAL_NODE);
e = register("hours-from-dateTime", new Component((Component.HOURS << 16) + StandardNames.XS_DATE_TIME),
SequenceType.OPTIONAL_INTEGER);
e.mandatoryArg(SequenceType.OPTIONAL_DATE_TIME);
e = register("hours-from-duration", new Component((Component.HOURS << 16) + StandardNames.XS_DURATION),
SequenceType.OPTIONAL_INTEGER);
e.mandatoryArg(SequenceType.OPTIONAL_DURATION);
e = register("hours-from-time", new Component((Component.HOURS << 16) + StandardNames.XS_TIME),
SequenceType.OPTIONAL_INTEGER);
e.mandatoryArg(SequenceType.OPTIONAL_TIME);
e = register("id", new Id(), SequenceType.ELEMENT_SEQUENCE);
e.mandatoryArg(SequenceType.STRING_SEQUENCE);
e.optionalArg(SequenceType.SINGLE_NODE);
register("implicit-timezone", new CurrentDateTime(), SequenceType.SINGLE_DAY_TIME_DURATION);
e = register("in-scope-prefixes", new InScopePrefixes(), SequenceType.STRING_SEQUENCE);
e.mandatoryArg(SequenceType.SINGLE_ELEMENT);
e = register("index-of", new IndexOf(), SequenceType.INTEGER_SEQUENCE);
e.mandatoryArg(SequenceType.ATOMIC_SEQUENCE);
e.mandatoryArg(SequenceType.SINGLE_ATOMIC);
e.optionalArg(SequenceType.SINGLE_STRING);
e = register("insert-before", new Insert(), SequenceType.ANY_SEQUENCE);
e.mandatoryArg(SequenceType.ANY_SEQUENCE);
e.mandatoryArg(SequenceType.SINGLE_INTEGER);
e.mandatoryArg(SequenceType.ANY_SEQUENCE);
e = register("iri-to-uri", new EscapeURI(EscapeURI.IRI_TO_URI), SequenceType.SINGLE_STRING);
e.mandatoryArg(SequenceType.OPTIONAL_STRING);
e = register("key", new KeyFn(), SequenceType.NODE_SEQUENCE);
e.applicability = XSLT;
e.mandatoryArg(SequenceType.SINGLE_STRING);
e.mandatoryArg(SequenceType.ATOMIC_SEQUENCE);
e.optionalArg(SequenceType.SINGLE_NODE);
e = register("lang", new Lang(), SequenceType.SINGLE_BOOLEAN);
e.mandatoryArg(SequenceType.OPTIONAL_STRING);
e.optionalArg(SequenceType.SINGLE_NODE);
register("last", new Last(), SequenceType.SINGLE_INTEGER);
e = register("local-name", new NamePart(NamePart.LOCAL_NAME), SequenceType.SINGLE_STRING);
e.mandatoryArg(SequenceType.OPTIONAL_NODE);
e = register("local-name-from-QName", new Component((Component.LOCALNAME << 16) + StandardNames.XS_QNAME),
SequenceType.OPTIONAL_STRING);
e.mandatoryArg(SequenceType.OPTIONAL_QNAME);
e = register("lower-case", new ForceCase(ForceCase.LOWERCASE), SequenceType.SINGLE_STRING);
e.mandatoryArg(SequenceType.OPTIONAL_STRING);
e = register("matches", new Matches(), SequenceType.SINGLE_BOOLEAN);
e.mandatoryArg(SequenceType.OPTIONAL_STRING);
e.mandatoryArg(SequenceType.SINGLE_STRING);
e.optionalArg(SequenceType.SINGLE_STRING);
e = register("max", new Minimax(Minimax.MAX), SequenceType.OPTIONAL_ATOMIC);
e.mandatoryArg(SequenceType.ATOMIC_SEQUENCE);
e.optionalArg(SequenceType.SINGLE_STRING);
e = register("min", new Minimax(Minimax.MIN), SequenceType.OPTIONAL_ATOMIC);
e.mandatoryArg(SequenceType.ATOMIC_SEQUENCE);
e.optionalArg(SequenceType.SINGLE_STRING);
e = register("minutes-from-dateTime", new Component((Component.MINUTES << 16) + StandardNames.XS_DATE_TIME),
SequenceType.OPTIONAL_INTEGER);
e.mandatoryArg(SequenceType.OPTIONAL_DATE_TIME);
e = register("minutes-from-duration", new Component((Component.MINUTES << 16) + StandardNames.XS_DURATION),
SequenceType.OPTIONAL_INTEGER);
e.mandatoryArg(SequenceType.OPTIONAL_DURATION);
e = register("minutes-from-time", new Component((Component.MINUTES << 16) + StandardNames.XS_TIME),
SequenceType.OPTIONAL_INTEGER);
e.mandatoryArg(SequenceType.OPTIONAL_TIME);
e = register("month-from-date", new Component((Component.MONTH << 16) + StandardNames.XS_DATE),
SequenceType.OPTIONAL_INTEGER);
e.mandatoryArg(SequenceType.OPTIONAL_DATE);
e = register("month-from-dateTime", new Component((Component.MONTH << 16) + StandardNames.XS_DATE_TIME),
SequenceType.OPTIONAL_INTEGER);
e.mandatoryArg(SequenceType.OPTIONAL_DATE_TIME);
e = register("months-from-duration", new Component((Component.MONTH << 16) + StandardNames.XS_DURATION),
SequenceType.OPTIONAL_INTEGER);
e.mandatoryArg(SequenceType.OPTIONAL_DURATION);
e = register("name", new NamePart(NamePart.NAME), SequenceType.SINGLE_STRING);
e.mandatoryArg(SequenceType.OPTIONAL_NODE);
e = register("namespace-uri", new NamePart(NamePart.NAMESPACE_URI), SequenceType.SINGLE_ANY_URI);
e.mandatoryArg(SequenceType.OPTIONAL_NODE);
e = register("namespace-uri-for-prefix", new NamespaceForPrefix(), SequenceType.OPTIONAL_ANY_URI);
e.mandatoryArg(SequenceType.OPTIONAL_STRING);
e.mandatoryArg(SequenceType.SINGLE_ELEMENT);
e = register("namespace-uri-from-QName", new Component((Component.NAMESPACE << 16) + StandardNames.XS_QNAME),
SequenceType.OPTIONAL_ANY_URI);
e.mandatoryArg(SequenceType.OPTIONAL_QNAME);
e = register("node-name", new NamePart(NamePart.NODE_NAME), SequenceType.OPTIONAL_QNAME);
e.mandatoryArg(SequenceType.OPTIONAL_NODE);
e = register("not", new BooleanFn(BooleanFn.NOT), SequenceType.SINGLE_BOOLEAN);
e.mandatoryArg(SequenceType.ANY_SEQUENCE);
register("normalize-space", new NormalizeSpace(), SequenceType.SINGLE_STRING);
register("normalize-space#0", new NormalizeSpace(), SequenceType.SINGLE_STRING);
e = register("normalize-space#1", new NormalizeSpace(), SequenceType.SINGLE_STRING);
e.mandatoryArg(SequenceType.OPTIONAL_STRING);
e = register("normalize-unicode", new NormalizeUnicode(), SequenceType.SINGLE_STRING);
e.mandatoryArg(SequenceType.OPTIONAL_STRING);
e.optionalArg(SequenceType.SINGLE_STRING);
e = register("number", new NumberFn(), SequenceType.SINGLE_DOUBLE);
e.mandatoryArg(SequenceType.OPTIONAL_ATOMIC);
register("position", new Position(), SequenceType.SINGLE_INTEGER);
e = register("prefix-from-QName", new Component((Component.PREFIX << 16) + StandardNames.XS_QNAME),
SequenceType.OPTIONAL_STRING);
e.mandatoryArg(SequenceType.OPTIONAL_QNAME);
e = register("QName", new QNameFn(), SequenceType.SINGLE_QNAME);
e.mandatoryArg(SequenceType.OPTIONAL_STRING);
e.mandatoryArg(SequenceType.SINGLE_STRING);
e = register("regex-group", new RegexGroup(), SequenceType.SINGLE_STRING);
e.applicability = XSLT;
e.mandatoryArg(SequenceType.SINGLE_INTEGER);
e = register("remove", new Remove(), SequenceType.ANY_SEQUENCE);
e.sameItemTypeAsFirstArgument = true;
e.mandatoryArg(SequenceType.ANY_SEQUENCE);
e.mandatoryArg(SequenceType.SINGLE_INTEGER);
e = register("replace", new Replace(), SequenceType.SINGLE_STRING);
e.mandatoryArg(SequenceType.OPTIONAL_STRING);
e.mandatoryArg(SequenceType.SINGLE_STRING);
e.mandatoryArg(SequenceType.SINGLE_STRING);
e.optionalArg(SequenceType.SINGLE_STRING);
e = register("resolve-QName", new ResolveQName(), SequenceType.OPTIONAL_QNAME);
e.mandatoryArg(SequenceType.OPTIONAL_STRING);
e.mandatoryArg(SequenceType.SINGLE_ELEMENT);
e = register("resolve-uri", new ResolveURI(), SequenceType.OPTIONAL_ANY_URI);
e.mandatoryArg(SequenceType.OPTIONAL_STRING);
e.optionalArg(SequenceType.SINGLE_STRING);
e = register("reverse", new Reverse(), SequenceType.ANY_SEQUENCE);
e.mandatoryArg(SequenceType.ANY_SEQUENCE);
e = register("root", new Root(), SequenceType.OPTIONAL_NODE);
e.optionalArg(SequenceType.OPTIONAL_NODE);
e = register("round", new Rounding(Rounding.ROUND), SequenceType.OPTIONAL_NUMERIC);
e.sameItemTypeAsFirstArgument = true;
e.mandatoryArg(SequenceType.OPTIONAL_NUMERIC);
e = register("round-half-to-even", new Rounding(Rounding.HALF_EVEN), SequenceType.OPTIONAL_NUMERIC);
e.sameItemTypeAsFirstArgument = true;
e.mandatoryArg(SequenceType.OPTIONAL_NUMERIC);
e.mandatoryArg(SequenceType.SINGLE_INTEGER);
e = register("seconds-from-dateTime", new Component((Component.SECONDS << 16) + StandardNames.XS_DATE_TIME),
SequenceType.OPTIONAL_DECIMAL);
e.mandatoryArg(SequenceType.OPTIONAL_DATE_TIME);
e = register("seconds-from-duration", new Component((Component.SECONDS << 16) + StandardNames.XS_DURATION),
SequenceType.OPTIONAL_DECIMAL);
e.mandatoryArg(SequenceType.OPTIONAL_DURATION);
e = register("seconds-from-time", new Component((Component.SECONDS << 16) + StandardNames.XS_TIME),
SequenceType.OPTIONAL_DECIMAL);
e.mandatoryArg(SequenceType.OPTIONAL_TIME);
e = register("starts-with", new StartsWith(), SequenceType.SINGLE_BOOLEAN);
e.mandatoryArg(SequenceType.OPTIONAL_STRING);
e.mandatoryArg(SequenceType.OPTIONAL_STRING);
e.optionalArg(SequenceType.SINGLE_STRING);
e = register("string", new StringFn(), SequenceType.SINGLE_STRING);
e.mandatoryArg(SequenceType.OPTIONAL_ITEM);
register("string-length", new StringLength(), SequenceType.SINGLE_INTEGER);
register("string-length#0", new StringLength(), SequenceType.SINGLE_INTEGER);
e = register("string-length#1", new StringLength(), SequenceType.SINGLE_INTEGER);
e.mandatoryArg(SequenceType.OPTIONAL_STRING);
e = register("string-join", new StringJoin(), SequenceType.SINGLE_STRING);
e.mandatoryArg(SequenceType.STRING_SEQUENCE);
e.mandatoryArg(SequenceType.SINGLE_STRING);
e = register("string-to-codepoints", new StringToCodepoints(), SequenceType.INTEGER_SEQUENCE);
e.mandatoryArg(SequenceType.OPTIONAL_STRING);
e = register("subsequence", new Subsequence(), SequenceType.ANY_SEQUENCE);
e.sameItemTypeAsFirstArgument = true;
e.mandatoryArg(SequenceType.ANY_SEQUENCE);
e.mandatoryArg(SequenceType.SINGLE_DOUBLE);
e.optionalArg(SequenceType.SINGLE_DOUBLE);
e = register("substring", new Substring(), SequenceType.SINGLE_STRING);
e.mandatoryArg(SequenceType.OPTIONAL_STRING);
e.mandatoryArg(SequenceType.SINGLE_DOUBLE);
e.optionalArg(SequenceType.SINGLE_DOUBLE);
e = register("substring-after", new SubstringAfter(), SequenceType.SINGLE_STRING);
e.mandatoryArg(SequenceType.OPTIONAL_STRING);
e.mandatoryArg(SequenceType.OPTIONAL_STRING);
e.optionalArg(SequenceType.SINGLE_STRING);
e = register("substring-before", new SubstringBefore(), SequenceType.SINGLE_STRING);
e.mandatoryArg(SequenceType.OPTIONAL_STRING);
e.mandatoryArg(SequenceType.OPTIONAL_STRING);
e.optionalArg(SequenceType.SINGLE_STRING);
e = register("sum", new Sum(), SequenceType.OPTIONAL_ATOMIC);
e.mandatoryArg(SequenceType.ATOMIC_SEQUENCE);
e.optionalArg(SequenceType.OPTIONAL_ATOMIC);
e = register("system-property", new SystemProperty(), SequenceType.SINGLE_STRING);
e.applicability = XSLT | USE_WHEN;
e.mandatoryArg(SequenceType.SINGLE_STRING);
e = register("timezone-from-date", new Component((Component.TIMEZONE << 16) + StandardNames.XS_DATE),
SequenceType.OPTIONAL_DAY_TIME_DURATION);
e.mandatoryArg(SequenceType.OPTIONAL_DATE);
e = register("timezone-from-dateTime", new Component((Component.TIMEZONE << 16) + StandardNames.XS_DATE_TIME),
SequenceType.OPTIONAL_DAY_TIME_DURATION);
e.mandatoryArg(SequenceType.OPTIONAL_DATE_TIME);
e = register("timezone-from-time", new Component((Component.TIMEZONE << 16) + StandardNames.XS_TIME),
SequenceType.OPTIONAL_DAY_TIME_DURATION);
e.mandatoryArg(SequenceType.OPTIONAL_TIME);
e = register("translate", new Translate(), SequenceType.SINGLE_STRING);
e.mandatoryArg(SequenceType.OPTIONAL_STRING);
e.mandatoryArg(SequenceType.SINGLE_STRING);
e.mandatoryArg(SequenceType.SINGLE_STRING);
e = register("tokenize", new Tokenize(), SequenceType.STRING_SEQUENCE);
e.mandatoryArg(SequenceType.OPTIONAL_STRING);
e.mandatoryArg(SequenceType.SINGLE_STRING);
e.optionalArg(SequenceType.SINGLE_STRING);
e = register("trace", new Trace(), SequenceType.ANY_SEQUENCE);
e.mandatoryArg(SequenceType.ANY_SEQUENCE);
e.mandatoryArg(SequenceType.SINGLE_STRING);
e = register("type-available", new Available(Available.TYPE_AVAILABLE), SequenceType.SINGLE_BOOLEAN);
e.applicability = XSLT | USE_WHEN;
e.mandatoryArg(SequenceType.SINGLE_STRING);
e = register("upper-case", new ForceCase(ForceCase.UPPERCASE), SequenceType.SINGLE_STRING);
e.mandatoryArg(SequenceType.OPTIONAL_STRING);
e = register("unparsed-text", new UnparsedText(UnparsedText.UNPARSED_TEXT),
SequenceType.OPTIONAL_STRING);
e.applicability = XSLT;
e.mandatoryArg(SequenceType.OPTIONAL_STRING);
e.optionalArg(SequenceType.SINGLE_STRING);
e = register("unparsed-text-available", new UnparsedText(UnparsedText.UNPARSED_TEXT_AVAILABLE),
SequenceType.SINGLE_BOOLEAN);
e.applicability = XSLT;
e.mandatoryArg(SequenceType.SINGLE_STRING);
e.mandatoryArg(SequenceType.SINGLE_STRING);
e = register("year-from-date", new Component((Component.YEAR << 16) + StandardNames.XS_DATE),
SequenceType.OPTIONAL_INTEGER);
e.mandatoryArg(SequenceType.OPTIONAL_DATE);
e = register("year-from-dateTime", new Component((Component.YEAR << 16) + StandardNames.XS_DATE_TIME),
SequenceType.OPTIONAL_INTEGER);
e.mandatoryArg(SequenceType.OPTIONAL_DATE_TIME);
e = register("years-from-duration", new Component((Component.YEAR << 16) + StandardNames.XS_DURATION),
SequenceType.OPTIONAL_INTEGER);
e.mandatoryArg(SequenceType.OPTIONAL_DURATION);
}
/**
* Get the table entry for the function with a given name
*
* @param name the name of the function. This is an unprefixed local-name for functions in the
* system namespace
* @return if the function name is known, an Entry containing information about the function. Otherwise,
* null
*/
public static Entry getFunction(String name, int arity) {
// try first for an entry of the form name#arity
Entry e = functionTable.get(name + '#' + arity);
if (e != null) {
return e;
}
// try for a generic entry
return functionTable.get(name);
}
/**
* An entry in the table describing the properties of a function
*/
public static class Entry {
/**
* The name of the function: a local name in the case of functions in the standard library
*/
public String name;
/**
* The class containing the implementation of this function (always a subclass of SystemFunction)
*/
public SystemFunction skeleton;
/**
* The minimum number of arguments required
*/
public int minArguments;
/**
* The maximum number of arguments permitted
*/
public int maxArguments;
/**
* The type of the result of the function
*/
public SequenceType resultType;
/**
* Flags indicating which host languages the function is applicable to
*/
public int applicability;
/**
* Flag indicating the function result is the same item type as the first argument
*/
public boolean sameItemTypeAsFirstArgument;
/**
* An array holding the types of the arguments to the function
*/
public SequenceType[] argumentTypes;
/**
* Add information to a function entry about the argument types of the function
*
* @param type the sequence type of the argument
*/
public void mandatoryArg(SequenceType type) {
Entry e = this;
e.minArguments++;
e.maxArguments++;
int argNr = e.argumentTypes.length;
SequenceType[] st2 = new SequenceType[e.argumentTypes.length + 1];
System.arraycopy(e.argumentTypes, 0, st2, 0, e.argumentTypes.length);
e.argumentTypes = st2;
e.argumentTypes[argNr] = type;
}
public void optionalArg(SequenceType type) {
Entry e = this;
e.maxArguments++;
int argNr = e.argumentTypes.length;
SequenceType[] st2 = new SequenceType[e.argumentTypes.length + 1];
System.arraycopy(e.argumentTypes, 0, st2, 0, e.argumentTypes.length);
e.argumentTypes = st2;
e.argumentTypes[argNr] = type;
}
}
}
// This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0.
// If a copy of the MPL was not distributed with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
// This Source Code Form is “Incompatible With Secondary Licenses”, as defined by the Mozilla Public License, v. 2.0.