use of org.exist.xquery.value.AtomicValue 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;
}
use of org.exist.xquery.value.AtomicValue in project exist by eXist-db.
the class ValueComparison method genericCompare.
protected Sequence genericCompare(Sequence contextSequence, Item contextItem) throws XPathException {
if (context.getProfiler().isEnabled()) {
context.getProfiler().message(this, Profiler.OPTIMIZATION_FLAGS, "OPTIMIZATION CHOICE", "genericCompare");
}
final Sequence ls = getLeft().eval(contextSequence, contextItem);
final Sequence rs = getRight().eval(contextSequence, contextItem);
if (ls.isEmpty() || rs.isEmpty()) {
return Sequence.EMPTY_SEQUENCE;
}
if (ls.hasOne() && rs.hasOne()) {
final AtomicValue lv = ls.itemAt(0).atomize();
final AtomicValue rv = rs.itemAt(0).atomize();
final Collator collator = getCollator(contextSequence);
return BooleanValue.valueOf(compareAtomic(collator, lv, rv, StringTruncationOperator.NONE, relation));
}
throw new XPathException(this, ErrorCodes.XPTY0004, "Type error: sequence with more than one item is not allowed here");
}
use of org.exist.xquery.value.AtomicValue in project exist by eXist-db.
the class SwitchExpression method eval.
public Sequence eval(Sequence contextSequence, Item contextItem) throws XPathException {
if (getContext().getXQueryVersion() < 30) {
throw new XPathException(this, ErrorCodes.EXXQDY0003, "switch expression is not available before XQuery 3.0", contextSequence);
}
if (contextItem != null) {
contextSequence = contextItem.toSequence();
}
final Sequence opSeq = operand.eval(contextSequence);
Sequence result = null;
if (opSeq.isEmpty()) {
result = defaultClause.returnClause.eval(contextSequence);
} else {
if (opSeq.hasMany()) {
throw new XPathException(this, ErrorCodes.XPTY0004, "Cardinality error in switch operand ", opSeq);
}
final AtomicValue opVal = opSeq.itemAt(0).atomize();
final Collator defaultCollator = context.getDefaultCollator();
for (final Case next : cases) {
for (final Expression caseOperand : next.operands) {
final Sequence caseSeq = caseOperand.eval(contextSequence, contextItem);
if (caseSeq.hasMany()) {
throw new XPathException(this, ErrorCodes.XPTY0004, "Cardinality error in switch case operand ", caseSeq);
}
final AtomicValue caseVal = caseSeq.isEmpty() ? AtomicValue.EMPTY_VALUE : caseSeq.itemAt(0).atomize();
if (FunDeepEqual.deepEquals(caseVal, opVal, defaultCollator)) {
return next.returnClause.eval(contextSequence);
}
}
}
}
if (result == null) {
result = defaultClause.returnClause.eval(contextSequence);
}
return result;
}
use of org.exist.xquery.value.AtomicValue in project exist by eXist-db.
the class QNameIndexLookup method eval.
public Sequence eval(Sequence contextSequence, Item contextItem) throws XPathException {
if (contextSequence == null || contextSequence.isEmpty()) {
// if the context sequence is empty, we create a default context
final RootNode rootNode = new RootNode(context);
contextSequence = rootNode.eval(null, null);
}
final Sequence[] args = getArguments(null, null);
final Item item = args[0].itemAt(0);
final QNameValue qval;
try {
// attempt to convert the first argument to a QName
qval = (QNameValue) item.convertTo(Type.QNAME);
} catch (final XPathException e) {
// wrong type: generate a diagnostic error
throw new XPathException(this, Messages.formatMessage(Error.FUNC_PARAM_TYPE, new Object[] { "1", getSignature().toString(), null, Type.getTypeName(Type.QNAME), Type.getTypeName(item.getType()) }));
}
QName qname = qval.getQName();
if (args.length == 3 && !(args[2].itemAt(0).toJavaObject(boolean.class))) {
qname = new QName(qname.getLocalPart(), qname.getNamespaceURI(), qname.getPrefix(), ElementValue.ATTRIBUTE);
}
final AtomicValue comparisonCriterion = args[1].itemAt(0).atomize();
final NativeValueIndex valueIndex = context.getBroker().getValueIndex();
final Sequence result = valueIndex.find(context.getWatchDog(), Comparison.EQ, contextSequence.getDocumentSet(), null, NodeSet.ANCESTOR, qname, comparisonCriterion);
return result;
}
use of org.exist.xquery.value.AtomicValue in project exist by eXist-db.
the class NativeValueIndexTest method convertToAtomic.
@Test
public void convertToAtomic() throws XPathException {
final String mockValue = "1234567890";
final AtomicValue result = NativeValueIndex.convertToAtomic(type, mockValue);
assertEquals(type, result.getType());
assertEquals(mockValue, result.getStringValue());
}
Aggregations