Search in sources :

Example 1 with AbstractMapType

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;
}
Also used : XPathException(org.exist.xquery.XPathException) AbstractMapType(org.exist.xquery.functions.map.AbstractMapType)

Example 2 with AbstractMapType

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;
    }
}
Also used : ArrayType(org.exist.xquery.functions.array.ArrayType) NodeValue(org.exist.xquery.value.NodeValue) XPathException(org.exist.xquery.XPathException) Node(org.w3c.dom.Node) ReferenceNode(org.exist.dom.memtree.ReferenceNode) AtomicValue(org.exist.xquery.value.AtomicValue) Sequence(org.exist.xquery.value.Sequence) NodeProxy(org.exist.dom.persistent.NodeProxy) AbstractMapType(org.exist.xquery.functions.map.AbstractMapType)

Example 3 with AbstractMapType

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);
}
Also used : IEntry(io.lacuna.bifurcan.IEntry) AbstractMapType(org.exist.xquery.functions.map.AbstractMapType) java.util(java.util) Module(org.exist.xquery.Module) MapType.newLinearMap(org.exist.xquery.functions.map.MapType.newLinearMap) QName(org.exist.dom.QName) MapType(org.exist.xquery.functions.map.MapType) org.exist.xquery.value(org.exist.xquery.value) XQueryAST(org.exist.xquery.parser.XQueryAST) org.exist.xquery(org.exist.xquery) Maps(io.lacuna.bifurcan.Maps) ConsumerE(com.evolvedbinary.j8fu.function.ConsumerE) IMap(io.lacuna.bifurcan.IMap) Map(io.lacuna.bifurcan.Map) AbstractMapType(org.exist.xquery.functions.map.AbstractMapType) AbstractMapType(org.exist.xquery.functions.map.AbstractMapType) MapType(org.exist.xquery.functions.map.MapType) IMap(io.lacuna.bifurcan.IMap) IEntry(io.lacuna.bifurcan.IEntry) Module(org.exist.xquery.Module)

Aggregations

AbstractMapType (org.exist.xquery.functions.map.AbstractMapType)3 XPathException (org.exist.xquery.XPathException)2 ConsumerE (com.evolvedbinary.j8fu.function.ConsumerE)1 IEntry (io.lacuna.bifurcan.IEntry)1 IMap (io.lacuna.bifurcan.IMap)1 Map (io.lacuna.bifurcan.Map)1 Maps (io.lacuna.bifurcan.Maps)1 java.util (java.util)1 QName (org.exist.dom.QName)1 ReferenceNode (org.exist.dom.memtree.ReferenceNode)1 NodeProxy (org.exist.dom.persistent.NodeProxy)1 org.exist.xquery (org.exist.xquery)1 Module (org.exist.xquery.Module)1 ArrayType (org.exist.xquery.functions.array.ArrayType)1 MapType (org.exist.xquery.functions.map.MapType)1 MapType.newLinearMap (org.exist.xquery.functions.map.MapType.newLinearMap)1 XQueryAST (org.exist.xquery.parser.XQueryAST)1 org.exist.xquery.value (org.exist.xquery.value)1 AtomicValue (org.exist.xquery.value.AtomicValue)1 NodeValue (org.exist.xquery.value.NodeValue)1