Search in sources :

Example 1 with AtomicValue

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

the class GeneralComparison method genericCompare.

protected Sequence genericCompare(Sequence ls, Sequence contextSequence, Item contextItem) throws XPathException {
    final long start = System.currentTimeMillis();
    final Sequence rs = getRight().eval(contextSequence, contextItem);
    final Collator collator = getCollator(contextSequence);
    Sequence result = BooleanValue.FALSE;
    if (ls.isEmpty() && rs.isEmpty()) {
        result = BooleanValue.valueOf(compareAtomic(collator, AtomicValue.EMPTY_VALUE, AtomicValue.EMPTY_VALUE));
    } else if (ls.isEmpty() && !rs.isEmpty()) {
        for (final SequenceIterator i2 = Atomize.atomize(rs).iterate(); i2.hasNext(); ) {
            if (compareAtomic(collator, AtomicValue.EMPTY_VALUE, i2.nextItem().atomize())) {
                result = BooleanValue.TRUE;
                break;
            }
        }
    } else if (!ls.isEmpty() && rs.isEmpty()) {
        for (final SequenceIterator i1 = Atomize.atomize(ls).iterate(); i1.hasNext(); ) {
            final AtomicValue lv = i1.nextItem().atomize();
            if (compareAtomic(collator, lv, AtomicValue.EMPTY_VALUE)) {
                result = BooleanValue.TRUE;
                break;
            }
        }
    } else if (ls.hasOne() && rs.hasOne() && ls.itemAt(0).getType() != Type.ARRAY && rs.itemAt(0).getType() != Type.ARRAY) {
        result = BooleanValue.valueOf(compareAtomic(collator, ls.itemAt(0).atomize(), rs.itemAt(0).atomize()));
    } else {
        for (final SequenceIterator i1 = Atomize.atomize(ls).iterate(); i1.hasNext(); ) {
            final AtomicValue lv = i1.nextItem().atomize();
            if (rs.isEmpty()) {
                if (compareAtomic(collator, lv, AtomicValue.EMPTY_VALUE)) {
                    result = BooleanValue.TRUE;
                    break;
                }
            } else if (rs.hasOne() && rs.itemAt(0).getType() != Type.ARRAY) {
                if (compareAtomic(collator, lv, rs.itemAt(0).atomize())) {
                    // return early if we are successful, continue otherwise
                    result = BooleanValue.TRUE;
                    break;
                }
            } else {
                for (final SequenceIterator i2 = Atomize.atomize(rs).iterate(); i2.hasNext(); ) {
                    if (compareAtomic(collator, lv, i2.nextItem().atomize())) {
                        result = BooleanValue.TRUE;
                        break;
                    }
                }
            }
        }
    }
    if (context.getProfiler().traceFunctions()) {
        context.getProfiler().traceIndexUsage(context, PerformanceStats.RANGE_IDX_TYPE, this, PerformanceStats.NO_INDEX, System.currentTimeMillis() - start);
    }
    return (result);
}
Also used : SequenceIterator(org.exist.xquery.value.SequenceIterator) AtomicValue(org.exist.xquery.value.AtomicValue) Sequence(org.exist.xquery.value.Sequence) Collator(com.ibm.icu.text.Collator)

Example 2 with AtomicValue

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

the class ValueComparison method nodeSetCompare.

protected Sequence nodeSetCompare(NodeSet nodes, Sequence contextSequence) throws XPathException {
    if (context.getProfiler().isEnabled()) {
        context.getProfiler().message(this, Profiler.OPTIMIZATION_FLAGS, "OPTIMIZATION CHOICE", "nodeSetCompare");
    }
    final NodeSet result = new ExtArrayNodeSet();
    final Collator collator = getCollator(contextSequence);
    if (contextSequence != null && !contextSequence.isEmpty()) {
        for (final NodeProxy current : nodes) {
            ContextItem context = current.getContext();
            if (context == null) {
                throw new XPathException(this, ErrorCodes.XPDY0002, "Context is missing for node set comparison");
            }
            do {
                final AtomicValue lv = current.atomize();
                final Sequence rs = getRight().eval(context.getNode().toSequence());
                if (!rs.hasOne()) {
                    throw new XPathException(this, ErrorCodes.XPTY0004, "Type error: sequence with less or more than one item is not allowed here");
                }
                if (compareAtomic(collator, lv, rs.itemAt(0).atomize(), StringTruncationOperator.NONE, relation)) {
                    result.add(current);
                }
            } while ((context = context.getNextDirect()) != null);
        }
    } else {
        final Sequence rs = getRight().eval(null);
        if (!rs.hasOne()) {
            throw new XPathException(this, ErrorCodes.XPTY0004, "Type error: sequence with less or more than one item is not allowed here");
        }
        final AtomicValue rv = rs.itemAt(0).atomize();
        for (final NodeProxy current : nodes) {
            final AtomicValue lv = current.atomize();
            if (compareAtomic(collator, lv, rv, StringTruncationOperator.NONE, Comparison.EQ)) {
                result.add(current);
            }
        }
    }
    return result;
}
Also used : ExtArrayNodeSet(org.exist.dom.persistent.ExtArrayNodeSet) NodeSet(org.exist.dom.persistent.NodeSet) ContextItem(org.exist.dom.persistent.ContextItem) ExtArrayNodeSet(org.exist.dom.persistent.ExtArrayNodeSet) AtomicValue(org.exist.xquery.value.AtomicValue) Sequence(org.exist.xquery.value.Sequence) NodeProxy(org.exist.dom.persistent.NodeProxy) Collator(com.ibm.icu.text.Collator)

Example 3 with AtomicValue

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

the class TestCase method getResource.

public Resource getResource(Object r) throws XMLDBException {
    LocalCollection collection = null;
    Subject user = null;
    LocalXMLResource res = null;
    final BrokerPool pool = existEmbeddedServer.getBrokerPool();
    if (r instanceof NodeProxy) {
        NodeProxy p = (NodeProxy) r;
        res = new LocalXMLResource(user, pool, collection, p);
    } else if (r instanceof Node) {
        res = new LocalXMLResource(user, pool, collection, XmldbURI.EMPTY_URI);
        res.setContentAsDOM((Node) r);
    } else if (r instanceof AtomicValue) {
        res = new LocalXMLResource(user, pool, collection, XmldbURI.EMPTY_URI);
        res.setContent(r);
    } else if (r instanceof LocalXMLResource)
        res = (LocalXMLResource) r;
    else
        throw new XMLDBException(ErrorCodes.VENDOR_ERROR, "unknown object " + r.getClass());
    try {
        Field field = res.getClass().getDeclaredField("outputProperties");
        field.setAccessible(true);
        field.set(res, new Properties(defaultProperties));
    } catch (Exception e) {
    }
    return res;
}
Also used : Field(java.lang.reflect.Field) LocalXMLResource(org.exist.xmldb.LocalXMLResource) LocalCollection(org.exist.xmldb.LocalCollection) Node(org.w3c.dom.Node) XMLDBException(org.xmldb.api.base.XMLDBException) AtomicValue(org.exist.xquery.value.AtomicValue) Properties(java.util.Properties) NodeProxy(org.exist.dom.persistent.NodeProxy) Subject(org.exist.security.Subject) BrokerPool(org.exist.storage.BrokerPool) XMLDBException(org.xmldb.api.base.XMLDBException) IOException(java.io.IOException) SAXException(org.xml.sax.SAXException)

Example 4 with AtomicValue

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

the class ResourceFunctionExecutorImpl method convertToType.

// TODO this needs to be abstracted into EXQuery library / or not, see the TODOs below
private <X> TypedValue<X> convertToType(final XQueryContext xqueryContext, final String argumentName, final TypedValue typedValue, final org.exquery.xquery.Type destinationType, final Class<X> underlyingDestinationClass) throws RestXqServiceException {
    // TODO consider changing Types that can be used as <T> to TypedValue to a set of interfaces for XDM types that
    // require absolute minimal implementation, and we provide some default or abstract implementations if possible
    final Item convertedValue;
    try {
        final int existDestinationType = TypeAdapter.toExistType(destinationType);
        final Item value;
        // Consider a factory or java.util.ServiceLoader pattern
        if (typedValue instanceof org.exquery.xdm.type.StringTypedValue) {
            value = new StringValue(((org.exquery.xdm.type.StringTypedValue) typedValue).getValue());
        } else if (typedValue instanceof org.exquery.xdm.type.Base64BinaryTypedValue) {
            value = BinaryValueFromInputStream.getInstance(xqueryContext, new Base64BinaryValueType(), ((org.exquery.xdm.type.Base64BinaryTypedValue) typedValue).getValue());
        } else {
            value = (Item) typedValue.getValue();
        }
        if (existDestinationType == value.getType()) {
            convertedValue = value;
        } else if (value instanceof AtomicValue) {
            convertedValue = value.convertTo(existDestinationType);
        } else {
            LOG.warn("Could not convert parameter '{}' from '{}' to '{}'.", argumentName, typedValue.getType().name(), destinationType.name());
            convertedValue = value;
        }
    } catch (final XPathException xpe) {
        // TODO define an ErrorCode
        throw new RestXqServiceException("TODO need to implement error code for problem with parameter conversion!: " + xpe.getMessage(), xpe);
    }
    return new TypedValue<X>() {

        @Override
        public org.exquery.xquery.Type getType() {
            // return destinationType;
            return TypeAdapter.toExQueryType(convertedValue.getType());
        }

        @Override
        public X getValue() {
            return (X) convertedValue;
        }
    };
}
Also used : RestXqServiceException(org.exquery.restxq.RestXqServiceException) org.exist.xquery(org.exist.xquery) Base64BinaryValueType(org.exist.xquery.value.Base64BinaryValueType) AtomicValue(org.exist.xquery.value.AtomicValue) Item(org.exist.xquery.value.Item) StringValue(org.exist.xquery.value.StringValue) TypedValue(org.exquery.xquery.TypedValue)

Example 5 with AtomicValue

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

the class FunMin 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());
        }
    }
    boolean computableProcessing = false;
    Sequence result;
    final Sequence arg = getArgument(0).eval(contextSequence, contextItem);
    if (arg.isEmpty()) {
        result = Sequence.EMPTY_SEQUENCE;
    } else {
        // 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 min = 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 (min != null && min.getType() != Type.YEAR_MONTH_DURATION) {
                        throw new XPathException(this, ErrorCodes.FORG0006, "Cannot compare " + Type.getTypeName(min.getType()) + " and " + Type.getTypeName(value.getType()), value);
                    }
                } else if (value.getType() == Type.DAY_TIME_DURATION) {
                    if (min != null && min.getType() != Type.DAY_TIME_DURATION) {
                        throw new XPathException(this, ErrorCodes.FORG0006, "Cannot compare " + Type.getTypeName(min.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 (min == null) {
                min = value;
            } else {
                if (Type.getCommonSuperType(min.getType(), value.getType()) == Type.ATOMIC) {
                    throw new XPathException(this, ErrorCodes.FORG0006, "Cannot compare " + Type.getTypeName(min.getType()) + " and " + Type.getTypeName(value.getType()), value);
                }
                // Any value of type xdt:untypedAtomic is cast to xs:double
                if (value.getType() == Type.ATOMIC) {
                    value = value.convertTo(Type.DOUBLE);
                }
                // Numeric tests
                if (Type.subTypeOfUnion(value.getType(), Type.NUMBER)) {
                    // Don't mix comparisons
                    if (!Type.subTypeOfUnion(min.getType(), Type.NUMBER)) {
                        throw new XPathException(this, ErrorCodes.FORG0006, "Cannot compare " + Type.getTypeName(min.getType()) + " and " + Type.getTypeName(value.getType()), min);
                    }
                    if (((NumericValue) value).isNaN()) {
                        // Type NaN correctly
                        value = value.promote(min);
                        if (value.getType() == Type.FLOAT) {
                            min = FloatValue.NaN;
                        } else {
                            min = DoubleValue.NaN;
                        }
                        // although result will be NaN, we need to continue on order to type correctly
                        continue;
                    }
                    min = min.promote(value);
                }
                // Ugly test
                if (value instanceof ComputableValue) {
                    if (!(min instanceof ComputableValue)) {
                        throw new XPathException(this, ErrorCodes.FORG0006, "Cannot compare " + Type.getTypeName(min.getType()) + " and " + Type.getTypeName(value.getType()), min);
                    }
                    // Type value correctly
                    value = value.promote(min);
                    min = min.min(collator, value);
                    computableProcessing = true;
                } else {
                    if (computableProcessing) {
                        throw new XPathException(this, ErrorCodes.FORG0006, "Cannot compare " + Type.getTypeName(min.getType()) + " and " + Type.getTypeName(value.getType()), value);
                    }
                    if (Collations.compare(collator, value.getStringValue(), min.getStringValue()) < 0) {
                        min = value;
                    }
                }
            }
        }
        result = min;
    }
    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)

Aggregations

AtomicValue (org.exist.xquery.value.AtomicValue)26 Sequence (org.exist.xquery.value.Sequence)16 Collator (com.ibm.icu.text.Collator)9 Item (org.exist.xquery.value.Item)9 SequenceIterator (org.exist.xquery.value.SequenceIterator)9 XPathException (org.exist.xquery.XPathException)6 NumericValue (org.exist.xquery.value.NumericValue)6 StringValue (org.exist.xquery.value.StringValue)5 NodeProxy (org.exist.dom.persistent.NodeProxy)4 ComputableValue (org.exist.xquery.value.ComputableValue)4 IOException (java.io.IOException)3 QName (org.exist.dom.QName)3 QNameValue (org.exist.xquery.value.QNameValue)3 ValueSequence (org.exist.xquery.value.ValueSequence)3 Test (org.junit.Test)3 ReentrantLock (java.util.concurrent.locks.ReentrantLock)2 EXistException (org.exist.EXistException)2 Collection (org.exist.collections.Collection)2 ContextItem (org.exist.dom.persistent.ContextItem)2 NodeSet (org.exist.dom.persistent.NodeSet)2