/** * Get the item type of the function item * * @return the function item's type */ public FunctionItemType getFunctionItemType() { return new SpecificFunctionType( new SequenceType[]{SequenceType.ANY_SEQUENCE}, SequenceType.SINGLE_BOOLEAN); }
/** * Ask whether values of this type are atomizable * * @return true if some or all instances of this type can be successfully atomized; false * * if no instances of this type can be atomized * @param th The type hierarchy cache */ @Override public boolean isAtomizable(TypeHierarchy th) { // An instance of a specific function type can be atomized only if it is an array, which // means there must be a single argument and it must be of type xs:integer or a supertype. if (getArity() != 1) { return false; } ItemType argType = getArgumentTypes()[0].getPrimaryType(); return th.isSubType(BuiltInAtomicType.INTEGER, argType); }
@Override public Expression makeFunctionSequenceCoercer(Expression exp, RoleDiagnostic role) throws XPathException { return new SpecificFunctionType(getArgumentTypes(), getResultType()).makeFunctionSequenceCoercer(exp, role); }
public void setFallbackFunction(Map<String, Sequence<?>> options, XPathContext context) throws XPathException { Sequence<?> val = options.get("fallback"); if (val != null) { Item fn = val.head(); if (fn instanceof Function) { fallbackFunction = (Function) fn; if (fallbackFunction.getArity() != 1) { throw new XPathException("Fallback function must have arity=1", "FOJS0005"); } SpecificFunctionType required = new SpecificFunctionType( new SequenceType[]{SequenceType.SINGLE_STRING}, SequenceType.ANY_SEQUENCE); if (!required.matches(fallbackFunction, context.getConfiguration().getTypeHierarchy())) { throw new XPathException("Fallback function does not match the required type", "FOJS0005"); } } else { throw new XPathException("Value of option 'fallback' is not a function", "FOJS0005"); } } } }
rel = new SpecificFunctionType(getArgumentTypes(), getResultType()).relationship(other, th); return rel;
if (getArity() == 1) { if (argTypes[0].getCardinality() == StaticProperty.EXACTLY_ONE && argTypes[0].getPrimaryType().isPlainType()) { String s = "The function arity is " + getArity() + "; a map can only be supplied for a function type with arity 1"; return Optional.of(s); if (getArity() == 1) { if (argTypes[0].getCardinality() == StaticProperty.EXACTLY_ONE && argTypes[0].getPrimaryType().isPlainType()) { String s = "The function arity is " + getArity() + "; an array can only be supplied for a function type with arity 1"; return Optional.of(s); if (getArity() != ((Function) item).getArity()) { String s = "The required function arity is " + getArity() + "; the supplied function has arity " + ((Function) item).getArity(); return Optional.of(s); return Optional.of(s); for (int j=0; j<getArity(); j++) { rel = th.sequenceTypeRelationship(argTypes[j], other.getArgumentTypes()[j]); if (rel != TypeHierarchy.SAME_TYPE && rel != TypeHierarchy.SUBSUMED_BY) {
/** * Test whether this function type equals another function type */ public boolean equals(Object other) { if (other instanceof SpecificFunctionType) { SpecificFunctionType f2 = (SpecificFunctionType) other; if (!resultType.equals(f2.resultType)) { return false; } if (argTypes.length != f2.argTypes.length) { return false; } for (int i = 0; i < argTypes.length; i++) { if (!argTypes[i].equals(f2.argTypes[i])) { return false; } } // Compare the annotations if (!getAnnotationAssertions().equals(f2.getAnnotationAssertions())) { return false; } return true; } return false; }
if (other == AnyFunctionType.getInstance() || other instanceof AnyFunctionTypeWithAssertions) { return TypeHierarchy.SUBSUMED_BY; } else if (equals(other)) { return TypeHierarchy.SAME_TYPE; } else if (other instanceof ArrayItemType || other instanceof MapType) {
public void setFallbackFunction(Map<String, Sequence<?>> options, XPathContext context) throws XPathException { Sequence<?> val = options.get("fallback"); if (val != null) { Item fn = val.head(); if (fn instanceof Function) { fallbackFunction = (Function) fn; if (fallbackFunction.getArity() != 1) { throw new XPathException("Fallback function must have arity=1", "FOJS0005"); } SpecificFunctionType required = new SpecificFunctionType( new SequenceType[]{SequenceType.SINGLE_STRING}, SequenceType.ANY_SEQUENCE); if (!required.matches(fallbackFunction, context.getConfiguration().getTypeHierarchy())) { throw new XPathException("Fallback function does not match the required type", "FOJS0005"); } } else { throw new XPathException("Value of option 'fallback' is not a function", "FOJS0005"); } } } }
rel = new SpecificFunctionType(getArgumentTypes(), getResultType()).relationship(other, th); return rel;
if (getArity() == 1) { if (argTypes[0].getCardinality() == StaticProperty.EXACTLY_ONE && argTypes[0].getPrimaryType().isPlainType()) { String s = "The function arity is " + getArity() + "; a map can only be supplied for a function type with arity 1"; return Optional.of(s); if (getArity() == 1) { if (argTypes[0].getCardinality() == StaticProperty.EXACTLY_ONE && argTypes[0].getPrimaryType().isPlainType()) { String s = "The function arity is " + getArity() + "; an array can only be supplied for a function type with arity 1"; return Optional.of(s); if (getArity() != ((Function) item).getArity()) { String s = "The required function arity is " + getArity() + "; the supplied function has arity " + ((Function) item).getArity(); return Optional.of(s); return Optional.of(s); for (int j=0; j<getArity(); j++) { rel = th.sequenceTypeRelationship(argTypes[j], other.getArgumentTypes()[j]); if (rel != TypeHierarchy.SAME_TYPE && rel != TypeHierarchy.SUBSUMED_BY) {
/** * Test whether this function type equals another function type */ public boolean equals(Object other) { if (other instanceof SpecificFunctionType) { SpecificFunctionType f2 = (SpecificFunctionType) other; if (!resultType.equals(f2.resultType)) { return false; } if (argTypes.length != f2.argTypes.length) { return false; } for (int i = 0; i < argTypes.length; i++) { if (!argTypes[i].equals(f2.argTypes[i])) { return false; } } // Compare the annotations if (!getAnnotationAssertions().equals(f2.getAnnotationAssertions())) { return false; } return true; } return false; }
if (other == AnyFunctionType.getInstance() || other instanceof AnyFunctionTypeWithAssertions) { return TypeHierarchy.SUBSUMED_BY; } else if (equals(other)) { return TypeHierarchy.SAME_TYPE; } else if (other instanceof ArrayItemType || other instanceof MapType) {
/** * Get the item type of the function item * * @return the function item's type */ public FunctionItemType getFunctionItemType() { // The function accepts any sequence as input, so it can do its own atomization return new SpecificFunctionType( new SequenceType[]{SequenceType.ANY_SEQUENCE}, SequenceType.SINGLE_BOOLEAN); }
@Override public Expression makeFunctionSequenceCoercer(Expression exp, RoleDiagnostic role) throws XPathException { return new SpecificFunctionType(getArgumentTypes(), getResultType()).makeFunctionSequenceCoercer(exp, role); }
/** * Ask whether values of this type are atomizable * * @return true if some or all instances of this type can be successfully atomized; false * * if no instances of this type can be atomized * @param th The type hierarchy cache */ @Override public boolean isAtomizable(TypeHierarchy th) { // An instance of a specific function type can be atomized only if it is an array, which // means there must be a single argument and it must be of type xs:integer or a supertype. if (getArity() != 1) { return false; } ItemType argType = getArgumentTypes()[0].getPrimaryType(); return th.isSubType(BuiltInAtomicType.INTEGER, argType); }
/** * Get the item type of the function item * * @return the function item's type */ public FunctionItemType getFunctionItemType() { // The function accepts any sequence as input, so it can do its own atomization return new SpecificFunctionType( new SequenceType[]{SequenceType.ANY_SEQUENCE}, SequenceType.SINGLE_BOOLEAN); }
/** * Get the item type of the function item * * @return the function item's type */ public FunctionItemType getFunctionItemType() { return new SpecificFunctionType( new SequenceType[]{SequenceType.ANY_SEQUENCE}, SequenceType.SINGLE_BOOLEAN); }