Search in sources :

Example 6 with QNameValue

use of org.exist.xquery.value.QNameValue in project exist by eXist-db.

the class FunMax method eval.

/* (non-Javadoc)
	 * @see org.exist.xquery.Expression#eval(org.exist.dom.persistent.DocumentSet, org.exist.xquery.value.Sequence, org.exist.xquery.value.Item)
	 */
public Sequence eval(Sequence contextSequence, Item contextItem) throws XPathException {
    if (context.getProfiler().isEnabled()) {
        context.getProfiler().start(this);
        context.getProfiler().message(this, Profiler.DEPENDENCIES, "DEPENDENCIES", Dependency.getDependenciesName(this.getDependencies()));
        if (contextSequence != null) {
            context.getProfiler().message(this, Profiler.START_SEQUENCES, "CONTEXT SEQUENCE", contextSequence);
        }
        if (contextItem != null) {
            context.getProfiler().message(this, Profiler.START_SEQUENCES, "CONTEXT ITEM", contextItem.toSequence());
        }
    }
    Sequence result;
    final Sequence arg = getArgument(0).eval(contextSequence, contextItem);
    if (arg.isEmpty()) {
        result = Sequence.EMPTY_SEQUENCE;
    } else {
        boolean computableProcessing = false;
        // TODO : test if a range index is defined *iff* it is compatible with the collator
        final Collator collator = getCollator(contextSequence, contextItem, 2);
        final SequenceIterator iter = arg.unorderedIterator();
        AtomicValue max = null;
        while (iter.hasNext()) {
            final Item item = iter.nextItem();
            if (item instanceof QNameValue) {
                throw new XPathException(this, ErrorCodes.FORG0006, "Cannot compare " + Type.getTypeName(item.getType()), arg);
            }
            AtomicValue value = item.atomize();
            // Duration values must either all be xs:yearMonthDuration values or must all be xs:dayTimeDuration values.
            if (Type.subTypeOf(value.getType(), Type.DURATION)) {
                value = ((DurationValue) value).wrap();
                if (value.getType() == Type.YEAR_MONTH_DURATION) {
                    if (max != null && max.getType() != Type.YEAR_MONTH_DURATION) {
                        throw new XPathException(this, ErrorCodes.FORG0006, "Cannot compare " + Type.getTypeName(max.getType()) + " and " + Type.getTypeName(value.getType()), value);
                    }
                } else if (value.getType() == Type.DAY_TIME_DURATION) {
                    if (max != null && max.getType() != Type.DAY_TIME_DURATION) {
                        throw new XPathException(this, ErrorCodes.FORG0006, "Cannot compare " + Type.getTypeName(max.getType()) + " and " + Type.getTypeName(value.getType()), value);
                    }
                } else {
                    throw new XPathException(this, ErrorCodes.FORG0006, "Cannot compare " + Type.getTypeName(value.getType()), value);
                }
            // Any value of type xdt:untypedAtomic is cast to xs:double
            } else if (value.getType() == Type.UNTYPED_ATOMIC) {
                value = value.convertTo(Type.DOUBLE);
            }
            if (max == null) {
                max = value;
            } else {
                if (Type.getCommonSuperType(max.getType(), value.getType()) == Type.ATOMIC) {
                    throw new XPathException(this, ErrorCodes.FORG0006, "Cannot compare " + Type.getTypeName(max.getType()) + " and " + Type.getTypeName(value.getType()), max);
                }
                // Any value of type xdt:untypedAtomic is cast to xs:double
                if (value.getType() == Type.UNTYPED_ATOMIC) {
                    value = value.convertTo(Type.DOUBLE);
                }
                // Numeric tests
                if (Type.subTypeOfUnion(value.getType(), Type.NUMBER)) {
                    // Don't mix comparisons
                    if (!Type.subTypeOfUnion(max.getType(), Type.NUMBER)) {
                        throw new XPathException(this, ErrorCodes.FORG0006, "Cannot compare " + Type.getTypeName(max.getType()) + " and " + Type.getTypeName(value.getType()), max);
                    }
                    if (((NumericValue) value).isNaN()) {
                        // Type NaN correctly
                        value = value.promote(max);
                        if (value.getType() == Type.FLOAT) {
                            max = FloatValue.NaN;
                        } else {
                            max = DoubleValue.NaN;
                        }
                        // although result will be NaN, we need to continue on order to type correctly
                        continue;
                    } else {
                        max = max.promote(value);
                    }
                }
                // Ugly test
                if (max instanceof ComputableValue && value instanceof ComputableValue) {
                    // Type value correctly
                    value = value.promote(max);
                    max = (ComputableValue) max.max(collator, value);
                    computableProcessing = true;
                } else {
                    if (computableProcessing) {
                        throw new XPathException(this, ErrorCodes.FORG0006, "Cannot compare " + Type.getTypeName(max.getType()) + " and " + Type.getTypeName(value.getType()), max);
                    }
                    if (Collations.compare(collator, value.getStringValue(), max.getStringValue()) > 0) {
                        max = value;
                    }
                }
            }
        }
        result = max;
    }
    if (context.getProfiler().isEnabled()) {
        context.getProfiler().end(this, "", result);
    }
    return result;
}
Also used : Item(org.exist.xquery.value.Item) ComputableValue(org.exist.xquery.value.ComputableValue) SequenceIterator(org.exist.xquery.value.SequenceIterator) XPathException(org.exist.xquery.XPathException) QNameValue(org.exist.xquery.value.QNameValue) AtomicValue(org.exist.xquery.value.AtomicValue) Sequence(org.exist.xquery.value.Sequence) NumericValue(org.exist.xquery.value.NumericValue) Collator(com.ibm.icu.text.Collator)

Example 7 with QNameValue

use of org.exist.xquery.value.QNameValue in project exist by eXist-db.

the class FunNodeName method eval.

@Override
public Sequence eval(Sequence contextSequence, final Item contextItem) throws XPathException {
    if (context.getProfiler().isEnabled()) {
        context.getProfiler().start(this);
        context.getProfiler().message(this, Profiler.DEPENDENCIES, "DEPENDENCIES", Dependency.getDependenciesName(this.getDependencies()));
        if (contextSequence != null) {
            context.getProfiler().message(this, Profiler.START_SEQUENCES, "CONTEXT SEQUENCE", contextSequence);
        }
        if (contextItem != null) {
            context.getProfiler().message(this, Profiler.START_SEQUENCES, "CONTEXT ITEM", contextItem.toSequence());
        }
    }
    if (contextItem != null) {
        contextSequence = contextItem.toSequence();
    }
    // If we have one argument, we take it into account
    final Sequence seq;
    if (getSignature().getArgumentCount() > 0) {
        seq = getArgument(0).eval(contextSequence, contextItem);
    } else {
        // Otherwise, we take the context sequence and we iterate over it
        seq = contextSequence;
    }
    if (seq == null) {
        throw new XPathException(this, ErrorCodes.XPDY0002, "Undefined context item");
    }
    final Sequence result;
    if (seq.isEmpty()) {
        result = Sequence.EMPTY_SEQUENCE;
    } else {
        final Item item = seq.itemAt(0);
        if (!Type.subTypeOf(item.getType(), Type.NODE)) {
            throw new XPathException(this, ErrorCodes.XPTY0004, "item is not a node; got '" + Type.getTypeName(item.getType()) + "'");
        }
        // TODO : how to improve performance ?
        final Node n = ((NodeValue) item).getNode();
        // Returns an expanded-QName for node kinds that can have names.
        if (n instanceof INode) {
            final QName qn = ((INode) n).getQName();
            if (qn.equals(QName.EMPTY_QNAME)) {
                result = Sequence.EMPTY_SEQUENCE;
            } else {
                result = new QNameValue(context, qn);
            }
        // For other kinds of nodes it returns the empty sequence.
        } else {
            result = Sequence.EMPTY_SEQUENCE;
        }
    }
    if (context.getProfiler().isEnabled()) {
        context.getProfiler().end(this, "", result);
    }
    return result;
}
Also used : Item(org.exist.xquery.value.Item) NodeValue(org.exist.xquery.value.NodeValue) INode(org.exist.dom.INode) XPathException(org.exist.xquery.XPathException) QName(org.exist.dom.QName) INode(org.exist.dom.INode) Node(org.w3c.dom.Node) QNameValue(org.exist.xquery.value.QNameValue) Sequence(org.exist.xquery.value.Sequence)

Example 8 with QNameValue

use of org.exist.xquery.value.QNameValue in project exist by eXist-db.

the class QNameFunctions method eval.

/* (non-Javadoc)
	 * @see org.exist.xquery.BasicFunction#eval(org.exist.xquery.value.Sequence[], org.exist.xquery.value.Sequence)
	 */
public Sequence eval(Sequence[] args, Sequence contextSequence) throws XPathException {
    if (context.getProfiler().isEnabled()) {
        context.getProfiler().start(this);
        context.getProfiler().message(this, Profiler.DEPENDENCIES, "DEPENDENCIES", Dependency.getDependenciesName(this.getDependencies()));
        if (contextSequence != null) {
            context.getProfiler().message(this, Profiler.START_SEQUENCES, "CONTEXT SEQUENCE", contextSequence);
        }
    }
    Sequence result;
    if (args[0].isEmpty()) {
        result = Sequence.EMPTY_SEQUENCE;
    } else {
        final QNameValue value = (QNameValue) args[0].itemAt(0);
        final QName qname = value.getQName();
        if (isCalledAs("prefix-from-QName")) {
            final String prefix = qname.getPrefix();
            if (prefix == null || prefix.isEmpty()) {
                result = Sequence.EMPTY_SEQUENCE;
            } else {
                result = new StringValue(prefix, Type.NCNAME);
            }
        } else if (isCalledAs("local-name-from-QName")) {
            result = new StringValue(qname.getLocalPart(), Type.NCNAME);
        } else {
            // fn:namespace-uri-from-QName
            String uri = qname.getNamespaceURI();
            if (uri == null) {
                uri = "";
            }
            result = new AnyURIValue(uri);
        }
    }
    if (context.getProfiler().isEnabled()) {
        context.getProfiler().end(this, "", result);
    }
    return result;
}
Also used : QName(org.exist.dom.QName) QNameValue(org.exist.xquery.value.QNameValue) AnyURIValue(org.exist.xquery.value.AnyURIValue) Sequence(org.exist.xquery.value.Sequence) StringValue(org.exist.xquery.value.StringValue)

Example 9 with QNameValue

use of org.exist.xquery.value.QNameValue in project exist by eXist-db.

the class FunError method eval.

@Override
public Sequence eval(Sequence[] args, Sequence contextSequence) throws XPathException {
    // Define default values
    ErrorCode errorCode = DEFAULT_ERROR;
    String errorDesc = DEFAULT_DESCRIPTION;
    Sequence errorVal = Sequence.EMPTY_SEQUENCE;
    // Enter if one or more parameters are supplied
    if (args.length > 0) {
        // use 2nd argument for error description
        if (args.length > 1) {
            errorDesc = args[1].getStringValue();
        }
        // and construct error code
        if (!args[0].isEmpty()) {
            QName errorQName = ((QNameValue) args[0].itemAt(0)).getQName();
            String prefix = errorQName.getPrefix();
            if (prefix == null) {
                final String ns = errorQName.getNamespaceURI();
                prefix = getContext().getPrefixForURI(ns);
                errorQName = new QName(errorQName.getLocalPart(), errorQName.getNamespaceURI(), prefix);
            }
            errorCode = new ErrorCode(errorQName, errorDesc);
        }
        // If there is a third argument, use it.
        if (args.length == 3) {
            errorVal = args[2];
        }
    }
    if (LOG.isTraceEnabled()) {
        logger.trace("{}: {}", errorDesc, errorCode.toString());
    }
    throw new XPathException(this, errorCode, errorDesc, errorVal);
}
Also used : XPathException(org.exist.xquery.XPathException) QName(org.exist.dom.QName) QNameValue(org.exist.xquery.value.QNameValue) ErrorCode(org.exist.xquery.ErrorCodes.ErrorCode) Sequence(org.exist.xquery.value.Sequence)

Example 10 with QNameValue

use of org.exist.xquery.value.QNameValue in project exist by eXist-db.

the class FunctionAvailable method eval.

@Override
public Sequence eval(final Sequence[] args, final Sequence contextSequence) throws XPathException {
    final QName functionName = ((QNameValue) args[0].itemAt(0)).getQName();
    final int arity = ((IntegerValue) args[1].itemAt(0)).getInt();
    final org.exist.xquery.Module[] modules = context.getModules(functionName.getNamespaceURI());
    boolean found = false;
    if (isEmpty(modules)) {
        found = context.resolveFunction(functionName, arity) != null;
    } else {
        for (final org.exist.xquery.Module module : modules) {
            if (module instanceof InternalModule) {
                found = ((InternalModule) module).getFunctionDef(functionName, arity) != null;
            } else if (module instanceof ExternalModule) {
                found = ((ExternalModule) module).getFunction(functionName, arity, context) != null;
            }
            if (found) {
                break;
            }
        }
    }
    return BooleanValue.valueOf(found);
}
Also used : org.exist.xquery(org.exist.xquery) QName(org.exist.dom.QName) QNameValue(org.exist.xquery.value.QNameValue) IntegerValue(org.exist.xquery.value.IntegerValue)

Aggregations

QNameValue (org.exist.xquery.value.QNameValue)11 QName (org.exist.dom.QName)9 Sequence (org.exist.xquery.value.Sequence)9 XPathException (org.exist.xquery.XPathException)7 Item (org.exist.xquery.value.Item)5 AtomicValue (org.exist.xquery.value.AtomicValue)3 Collator (com.ibm.icu.text.Collator)2 NodeImpl (org.exist.dom.memtree.NodeImpl)2 ComputableValue (org.exist.xquery.value.ComputableValue)2 IntegerValue (org.exist.xquery.value.IntegerValue)2 NodeValue (org.exist.xquery.value.NodeValue)2 NumericValue (org.exist.xquery.value.NumericValue)2 SequenceIterator (org.exist.xquery.value.SequenceIterator)2 INode (org.exist.dom.INode)1 MemTreeBuilder (org.exist.dom.memtree.MemTreeBuilder)1 ElementImpl (org.exist.dom.persistent.ElementImpl)1 NodeProxy (org.exist.dom.persistent.NodeProxy)1 NodeSet (org.exist.dom.persistent.NodeSet)1 NativeValueIndex (org.exist.storage.NativeValueIndex)1 org.exist.xquery (org.exist.xquery)1