use of org.exist.xquery.functions.map.AbstractMapType in project exist by eXist-db.
the class Sync method getOptions.
private Map<String, Sequence> getOptions(final Sequence parameter) throws XPathException {
final Map<String, Sequence> options = new HashMap<>();
options.put(AFTER_OPT, Sequence.EMPTY_SEQUENCE);
options.put(PRUNE_OPT, new BooleanValue(false));
options.put(EXCLUDES_OPT, Sequence.EMPTY_SEQUENCE);
if (parameter.isEmpty()) {
return options;
}
final Item item = parameter.itemAt(0);
if (item.getType() == Type.MAP) {
final AbstractMapType optionsMap = (AbstractMapType) item;
final Sequence seq = optionsMap.get(new StringValue(EXCLUDES_OPT));
if (!seq.isEmpty() && seq.getItemType() != Type.STRING) {
throw new XPathException(this, ErrorCodes.XPTY0004, "Invalid value for option \"excludes\", expected xs:string* got " + Type.getTypeName(seq.getItemType()));
}
options.put(EXCLUDES_OPT, seq);
checkOption(optionsMap, PRUNE_OPT, Type.BOOLEAN, options);
checkOption(optionsMap, AFTER_OPT, Type.DATE_TIME, options);
} else if (parameter.itemAt(0).getType() == Type.DATE_TIME) {
options.put(AFTER_OPT, parameter);
} else {
throw new XPathException(this, ErrorCodes.XPTY0004, "Invalid 3rd parameter, allowed parameter types are xs:dateTime or map(*) got " + Type.getTypeName(item.getType()));
}
return options;
}
use of org.exist.xquery.functions.map.AbstractMapType 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.map.AbstractMapType in project exist by eXist-db.
the class LoadXQueryModule method eval.
@Override
public Sequence eval(Sequence[] args, Sequence contextSequence) throws XPathException {
final String targetNamespace = args[0].getStringValue();
if (targetNamespace.isEmpty()) {
throw new XPathException(this, ErrorCodes.FOQM0001, "Target namespace must be a string with length > 0");
}
AnyURIValue[] locationHints = null;
String xqVersion = getXQueryVersion(context.getXQueryVersion());
AbstractMapType externalVars = new MapType(context);
Sequence contextItem = Sequence.EMPTY_SEQUENCE;
// evaluate options
if (getArgumentCount() == 2) {
final AbstractMapType map = (AbstractMapType) args[1].itemAt(0);
final Sequence locationHintsOption = map.get(OPTIONS_LOCATION_HINTS);
locationHints = new AnyURIValue[locationHintsOption.getItemCount()];
for (int i = 0; i < locationHints.length; i++) {
locationHints[i] = (AnyURIValue) locationHintsOption.itemAt(i).convertTo(Type.ANY_URI);
}
final Sequence versions = map.get(OPTIONS_XQUERY_VERSION);
if (!versions.isEmpty()) {
xqVersion = versions.itemAt(0).getStringValue();
}
final Sequence vars = map.get(OPTIONS_VARIABLES);
if (!vars.isEmpty()) {
if (vars.hasOne() && vars.itemAt(0).getType() == Type.MAP) {
externalVars = (AbstractMapType) vars.itemAt(0);
} else {
throw new XPathException(this, ErrorCodes.XPTY0004, "Option 'variables' must be a map");
}
}
contextItem = map.get(OPTIONS_CONTEXT_ITEM);
if (contextItem.getItemCount() > 1) {
throw new XPathException(this, ErrorCodes.XPTY0004, "Option 'context-item' must contain zero or one " + "items");
}
}
// create temporary context so main context is not polluted
final XQueryContext tempContext = new XQueryContext(context.getBroker().getBrokerPool(), context.getProfiler());
tempContext.setModuleLoadPath(context.getModuleLoadPath());
setExternalVars(externalVars, tempContext::declareGlobalVariable);
tempContext.prepareForExecution();
Module[] loadedModules = null;
try {
loadedModules = tempContext.importModule(targetNamespace, null, locationHints);
} catch (final XPathException e) {
if (e.getErrorCode() == ErrorCodes.XQST0059) {
// importModule may throw exception if no location is given and module cannot be resolved
throw new XPathException(this, ErrorCodes.FOQM0002, "Module with URI " + targetNamespace + " not found");
}
throw new XPathException(this, ErrorCodes.FOQM0003, "Error found when importing module: " + e.getMessage());
}
// not found, raise error
if (loadedModules == null || loadedModules.length == 0) {
throw new XPathException(this, ErrorCodes.FOQM0002, "Module with URI " + targetNamespace + " not found");
}
if (!xqVersion.equals(getXQueryVersion(tempContext.getXQueryVersion()))) {
throw new XPathException(ErrorCodes.FOQM0003, "Imported module has wrong XQuery version: " + getXQueryVersion(tempContext.getXQueryVersion()));
}
final IMap<AtomicValue, Sequence> variables = newLinearMap(null);
final IMap<AtomicValue, IMap<AtomicValue, Sequence>> functions = newLinearMap(null);
for (final Module loadedModule : loadedModules) {
loadedModule.setContextItem(contextItem);
setExternalVars(externalVars, loadedModule::declareVariable);
if (!loadedModule.isInternalModule()) {
// ensure variable declarations in the imported module are analyzed.
// unlike when using a normal import statement, this is not done automatically
((ExternalModule) loadedModule).analyzeGlobalVars();
}
getModuleVariables(loadedModule, variables);
getModuleFunctions(loadedModule, tempContext, functions);
}
final IMap<AtomicValue, Sequence> result = Map.from(io.lacuna.bifurcan.List.of(new Maps.Entry<>(RESULT_FUNCTIONS, new MapType(context, functions.mapValues((k, v) -> (Sequence) new MapType(context, v.forked(), Type.INTEGER)).forked(), Type.QNAME)), new Maps.Entry<>(RESULT_VARIABLES, new MapType(context, variables.forked(), Type.QNAME))));
return new MapType(context, result, Type.STRING);
}
Aggregations