use of org.exist.xquery.functions.array.ArrayType in project exist by eXist-db.
the class JSON method readValue.
private static Item readValue(XQueryContext context, JsonParser parser, Item parent, String handleDuplicates) throws IOException, XPathException {
JsonToken token;
Item next = null;
while ((token = parser.nextValue()) != null) {
if (token == JsonToken.END_OBJECT || token == JsonToken.END_ARRAY) {
return parent;
}
switch(token) {
case START_OBJECT:
next = new MapType(context, null);
readValue(context, parser, next, handleDuplicates);
break;
case START_ARRAY:
next = new ArrayType(context, Sequence.EMPTY_SEQUENCE);
readValue(context, parser, next, handleDuplicates);
break;
case VALUE_FALSE:
next = BooleanValue.FALSE;
break;
case VALUE_TRUE:
next = BooleanValue.TRUE;
break;
case VALUE_NUMBER_FLOAT:
case VALUE_NUMBER_INT:
// according to spec, all numbers are converted to double
next = new StringValue(parser.getText()).convertTo(Type.DOUBLE);
break;
case VALUE_NULL:
next = null;
break;
default:
next = new StringValue(parser.getText());
break;
}
if (parent != null) {
switch(parent.getType()) {
case Type.ARRAY:
((ArrayType) parent).add(next == null ? Sequence.EMPTY_SEQUENCE : next.toSequence());
break;
case Type.MAP:
final String currentName = parser.getCurrentName();
if (currentName == null) {
throw new XPathException(ErrorCodes.FOJS0001, "Invalid JSON object");
}
final StringValue name = new StringValue(currentName);
final MapType map = (MapType) parent;
if (map.contains(name)) {
// handle duplicate keys
if (handleDuplicates.equals(OPTION_DUPLICATES_REJECT)) {
throw new XPathException(ErrorCodes.FOJS0003, "Duplicate key: " + currentName);
}
if (handleDuplicates.equals(OPTION_DUPLICATES_USE_LAST)) {
map.add(name, next == null ? Sequence.EMPTY_SEQUENCE : next.toSequence());
}
} else {
map.add(name, next == null ? Sequence.EMPTY_SEQUENCE : next.toSequence());
}
break;
}
}
}
return next;
}
use of org.exist.xquery.functions.array.ArrayType in project exist by eXist-db.
the class FunDeepEqual method deepEquals.
public static boolean deepEquals(Item a, Item b, Collator collator) {
try {
if (a.getType() == Type.ARRAY || b.getType() == Type.ARRAY) {
if (a.getType() != b.getType()) {
return false;
}
final ArrayType ar = (ArrayType) a;
final ArrayType br = (ArrayType) b;
if (ar.getSize() != br.getSize()) {
return false;
}
for (int i = 0; i < ar.getSize(); i++) {
if (!deepEqualsSeq(ar.get(i), br.get(i), collator)) {
return false;
}
}
return true;
}
if (a.getType() == Type.MAP || b.getType() == Type.MAP) {
if (a.getType() != b.getType()) {
return false;
}
final AbstractMapType amap = (AbstractMapType) a;
final AbstractMapType bmap = (AbstractMapType) b;
if (amap.size() != bmap.size()) {
return false;
}
for (final IEntry<AtomicValue, Sequence> aentry : amap) {
if (!bmap.contains(aentry.key())) {
return false;
}
if (!deepEqualsSeq(aentry.value(), bmap.get(aentry.key()), collator)) {
return false;
}
}
return true;
}
final boolean aAtomic = Type.subTypeOf(a.getType(), Type.ATOMIC);
final boolean bAtomic = Type.subTypeOf(b.getType(), Type.ATOMIC);
if (aAtomic || bAtomic) {
if (!aAtomic || !bAtomic) {
return false;
}
try {
final AtomicValue av = (AtomicValue) a;
final AtomicValue bv = (AtomicValue) b;
if (Type.subTypeOfUnion(av.getType(), Type.NUMBER) && Type.subTypeOfUnion(bv.getType(), Type.NUMBER)) {
// or if both values are NaN
if (((NumericValue) a).isNaN() && ((NumericValue) b).isNaN()) {
return true;
}
}
return ValueComparison.compareAtomic(collator, av, bv, StringTruncationOperator.NONE, Comparison.EQ);
} catch (final XPathException e) {
return false;
}
}
if (a.getType() != b.getType()) {
return false;
}
final NodeValue nva = (NodeValue) a;
final NodeValue nvb = (NodeValue) b;
if (nva == nvb) {
return true;
}
try {
// since the symbol table is ignored.
if (nva.getImplementationType() != NodeValue.IN_MEMORY_NODE && nva.equals(nvb)) // shortcut!
{
return true;
}
} catch (final XPathException e) {
// apparently incompatible values, do manual comparison
}
final Node na;
final Node nb;
switch(a.getType()) {
case Type.DOCUMENT:
// NodeValue.getNode() doesn't seem to work for document nodes
na = nva instanceof Node ? (Node) nva : ((NodeProxy) nva).getOwnerDocument();
nb = nvb instanceof Node ? (Node) nvb : ((NodeProxy) nvb).getOwnerDocument();
return compareContents(na, nb);
case Type.ELEMENT:
na = nva.getNode();
nb = nvb.getNode();
return compareElements(na, nb);
case Type.ATTRIBUTE:
na = nva.getNode();
nb = nvb.getNode();
return compareNames(na, nb) && safeEquals(na.getNodeValue(), nb.getNodeValue());
case Type.PROCESSING_INSTRUCTION:
case Type.NAMESPACE:
na = nva.getNode();
nb = nvb.getNode();
return safeEquals(na.getNodeName(), nb.getNodeName()) && safeEquals(nva.getStringValue(), nvb.getStringValue());
case Type.TEXT:
case Type.COMMENT:
return safeEquals(nva.getStringValue(), nvb.getStringValue());
default:
throw new RuntimeException("unexpected item type " + Type.getTypeName(a.getType()));
}
} catch (final XPathException e) {
logger.error(e.getMessage());
e.printStackTrace();
return false;
}
}
use of org.exist.xquery.functions.array.ArrayType in project exist by eXist-db.
the class FunHigherOrderFun method eval.
@Override
public Sequence eval(final Sequence[] args, final Sequence contextSequence) throws XPathException {
Sequence result = new ValueSequence();
if (isCalledAs("for-each")) {
try (final FunctionReference ref = (FunctionReference) args[1].itemAt(0)) {
ref.analyze(cachedContextInfo);
if (funcRefHasDifferentArity(ref, 1)) {
throw new XPathException(this, ErrorCodes.XPTY0004, "The supplied function (" + ref.getStringValue() + ") has " + ref.getSignature().getArgumentCount() + " arguments - expected 1");
}
for (final SequenceIterator i = args[0].iterate(); i.hasNext(); ) {
final Item item = i.nextItem();
final Sequence r = ref.evalFunction(null, null, new Sequence[] { item.toSequence() });
result.addAll(r);
}
}
} else if (isCalledAs("filter")) {
final FunctionReference refParam;
final Sequence seq;
// Hack: switch parameters for backwards compatibility
if (Type.subTypeOf(args[1].getItemType(), Type.FUNCTION_REFERENCE)) {
refParam = (FunctionReference) args[1].itemAt(0);
seq = args[0];
} else {
refParam = (FunctionReference) args[0].itemAt(0);
seq = args[1];
}
try (final FunctionReference ref = refParam) {
ref.analyze(cachedContextInfo);
if (funcRefHasDifferentArity(ref, 1)) {
throw new XPathException(this, ErrorCodes.XPTY0004, "The supplied function (" + ref.getStringValue() + ") has " + ref.getSignature().getArgumentCount() + " arguments - expected 1");
}
for (final SequenceIterator i = seq.iterate(); i.hasNext(); ) {
final Item item = i.nextItem();
final Sequence r = ref.evalFunction(null, null, new Sequence[] { item.toSequence() });
// two pending tests in exist-core/src/test/xquery/xquery3/fnHigherOrderFunctions.xql
if (r.effectiveBooleanValue()) {
result.add(item);
}
}
}
} else if (isCalledAs("fold-left")) {
try (final FunctionReference ref = (FunctionReference) args[2].itemAt(0)) {
ref.analyze(cachedContextInfo);
if (funcRefHasDifferentArity(ref, 2)) {
throw new XPathException(this, ErrorCodes.XPTY0004, "The supplied function (" + ref.getStringValue() + ") has " + ref.getSignature().getArgumentCount() + " arguments - expected 2");
}
final Sequence seq = args[0];
final Sequence zero = args[1];
result = foldLeft(ref, zero, seq.iterate());
}
} else if (isCalledAs("fold-right")) {
try (final FunctionReference ref = (FunctionReference) args[2].itemAt(0)) {
ref.analyze(cachedContextInfo);
if (funcRefHasDifferentArity(ref, 2)) {
throw new XPathException(this, ErrorCodes.XPTY0004, "The supplied function (" + ref.getStringValue() + ") has " + ref.getSignature().getArgumentCount() + " arguments - expected 2");
}
final Sequence zero = args[1];
final Sequence seq = args[0];
if (seq instanceof ValueSequence) {
result = foldRightNonRecursive(ref, zero, ((ValueSequence) seq).iterateInReverse());
} else if (seq instanceof RangeSequence) {
result = foldRightNonRecursive(ref, zero, ((RangeSequence) seq).iterateInReverse());
} else {
result = foldRight(ref, zero, seq);
}
}
} else if (isCalledAs("for-each-pair")) {
try (final FunctionReference ref = (FunctionReference) args[2].itemAt(0)) {
ref.analyze(cachedContextInfo);
if (funcRefHasDifferentArity(ref, 2)) {
throw new XPathException(this, ErrorCodes.XPTY0004, "The supplied function (" + ref.getStringValue() + ") has " + ref.getSignature().getArgumentCount() + " arguments - expected 2");
}
final SequenceIterator i1 = args[0].iterate();
final SequenceIterator i2 = args[1].iterate();
while (i1.hasNext() && i2.hasNext()) {
final Sequence r = ref.evalFunction(null, null, new Sequence[] { i1.nextItem().toSequence(), i2.nextItem().toSequence() });
result.addAll(r);
}
}
} else if (isCalledAs("apply")) {
try (final FunctionReference ref = (FunctionReference) args[0].itemAt(0)) {
ref.analyze(cachedContextInfo);
final ArrayType array = (ArrayType) args[1].itemAt(0);
if (funcRefHasDifferentArity(ref, array.getSize())) {
throw new XPathException(this, ErrorCodes.FOAP0001, "Number of arguments supplied to fn:apply does not match function signature. Expected: " + ref.getSignature().getArgumentCount() + ", got: " + array.getSize());
}
final Sequence[] fargs = array.toArray();
return ref.evalFunction(null, null, fargs);
}
}
return result;
}
Aggregations