All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.exist.xquery.XQueryContext Maven / Gradle / Ivy

There is a newer version: 6.3.0
Show newest version
/*
 *  eXist Open Source Native XML Database
 *  Copyright (C) 2001-2018 The eXist Project
 *  http://exist-db.org
 *
 *  This program is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public License
 *  as published by the Free Software Foundation; either version 2
 *  of the License, or (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public
 *  License along with this library; if not, write to the Free Software
 *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 */
package org.exist.xquery;

import java.io.IOException;
import java.io.Reader;
import java.lang.reflect.Constructor;
import java.net.MalformedURLException;
import java.net.URI;
import java.net.URISyntaxException;
import java.nio.charset.Charset;
import java.nio.file.Path;
import java.util.*;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.atomic.AtomicReference;
import java.util.function.Predicate;
import java.util.stream.Collectors;
import java.util.stream.Stream;

import javax.annotation.Nullable;
import javax.xml.datatype.DatatypeConfigurationException;
import javax.xml.datatype.DatatypeFactory;
import javax.xml.datatype.Duration;
import javax.xml.datatype.XMLGregorianCalendar;
import javax.xml.stream.XMLStreamException;

import antlr.RecognitionException;
import antlr.TokenStreamException;
import antlr.collections.AST;
import com.evolvedbinary.j8fu.Either;
import com.evolvedbinary.j8fu.function.TriFunctionE;
import com.evolvedbinary.j8fu.function.QuadFunctionE;
import com.evolvedbinary.j8fu.tuple.Tuple2;
import com.ibm.icu.text.Collator;
import net.jcip.annotations.Immutable;
import net.jcip.annotations.ThreadSafe;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.exist.Database;
import org.exist.EXistException;
import org.exist.Namespaces;
import org.exist.collections.Collection;
import org.exist.debuggee.Debuggee;
import org.exist.debuggee.DebuggeeJoint;
import org.exist.dom.persistent.*;
import org.exist.dom.QName;
import org.exist.http.servlets.*;
import org.exist.interpreter.Context;
import org.exist.dom.memtree.InMemoryXMLStreamReader;
import org.exist.dom.memtree.MemTreeBuilder;
import org.exist.dom.memtree.NodeImpl;
import org.exist.numbering.NodeId;
import org.exist.repo.ExistRepository;
import org.exist.security.AuthenticationException;
import org.exist.security.Permission;
import org.exist.security.PermissionDeniedException;
import org.exist.security.Subject;
import org.exist.source.*;
import org.exist.stax.ExtendedXMLStreamReader;
import org.exist.storage.DBBroker;
import org.exist.storage.UpdateListener;
import org.exist.storage.lock.Lock.LockMode;
import org.exist.storage.lock.LockedDocumentMap;
import org.exist.storage.txn.Txn;
import org.exist.util.Collations;
import org.exist.util.Configuration;
import org.exist.util.LockException;
import org.exist.util.hashtable.NamePool;
import org.exist.xmldb.XmldbURI;
import org.exist.xquery.parser.*;
import org.exist.xquery.pragmas.*;
import org.exist.xquery.update.Modification;
import org.exist.xquery.util.SerializerUtils;
import org.exist.xquery.value.*;
import org.w3c.dom.Node;

import static com.evolvedbinary.j8fu.tuple.Tuple.Tuple;
import static javax.xml.XMLConstants.XMLNS_ATTRIBUTE;
import static javax.xml.XMLConstants.XML_NS_PREFIX;
import static org.exist.Namespaces.XML_NS;

/**
 * The current XQuery execution context. Contains the static as well as the dynamic
 * XQuery context components.
 *
 * @author Wolfgang Meier
 */
public class XQueryContext implements BinaryValueManager, Context {

    private static final Logger LOG = LogManager.getLogger(XQueryContext.class);

    public static final String ENABLE_QUERY_REWRITING_ATTRIBUTE = "enable-query-rewriting";
    public static final String XQUERY_BACKWARD_COMPATIBLE_ATTRIBUTE = "backwardCompatible";
    public static final String XQUERY_RAISE_ERROR_ON_FAILED_RETRIEVAL_ATTRIBUTE = "raise-error-on-failed-retrieval";
    public static final String ENFORCE_INDEX_USE_ATTRIBUTE = "enforce-index-use";

    //TODO : move elsewhere ?
    public static final String BUILT_IN_MODULE_URI_ATTRIBUTE = "uri";
    public static final String BUILT_IN_MODULE_CLASS_ATTRIBUTE = "class";
    public static final String BUILT_IN_MODULE_SOURCE_ATTRIBUTE = "src";

    public static final String PROPERTY_XQUERY_BACKWARD_COMPATIBLE = "xquery.backwardCompatible";
    public static final String PROPERTY_ENABLE_QUERY_REWRITING = "xquery.enable-query-rewriting";
    public static final String PROPERTY_XQUERY_RAISE_ERROR_ON_FAILED_RETRIEVAL = "xquery.raise-error-on-failed-retrieval";
    public static final boolean XQUERY_RAISE_ERROR_ON_FAILED_RETRIEVAL_DEFAULT = false;
    public static final String PROPERTY_ENFORCE_INDEX_USE = "xquery.enforce-index-use";

    //TODO : move elsewhere ?
    public static final String PROPERTY_BUILT_IN_MODULES = "xquery.modules";
    public static final String PROPERTY_STATIC_MODULE_MAP = "xquery.modules.static";
    public static final String PROPERTY_MODULE_PARAMETERS = "xquery.modules.parameters";

    public static final String JAVA_URI_START = "java:";
    //private static final String XMLDB_URI_START = "xmldb:exist://";

    private static final String TEMP_STORE_ERROR = "Error occurred while storing temporary data";
    public static final String XQUERY_CONTEXTVAR_XQUERY_UPDATE_ERROR = "_eXist_xquery_update_error";
    public static final String HTTP_SESSIONVAR_XMLDB_USER = "_eXist_xmldb_user";

    public static final String HTTP_REQ_ATTR_USER = "xquery.user";
    public static final String HTTP_REQ_ATTR_PASS = "xquery.password";

    // Static namespace/prefix mappings
    protected Map staticNamespaces = new HashMap<>();

    // Static prefix/namespace mappings
    protected Map staticPrefixes = new HashMap<>();

    // Local in-scope namespace/prefix mappings in the current context
    Map inScopeNamespaces = new HashMap<>();

    // Local prefix/namespace mappings in the current context
    private Map inScopePrefixes = new HashMap<>();

    // Inherited in-scope namespace/prefix mappings in the current context
    private Map inheritedInScopeNamespaces = new HashMap<>();

    // Inherited prefix/namespace mappings in the current context
    private Map inheritedInScopePrefixes = new HashMap<>();

    private Map mappedModules = new HashMap<>();

    private boolean preserveNamespaces = true;

    private boolean inheritNamespaces = true;

    // Local namespace stack
    private Deque> namespaceStack = new ArrayDeque<>();

    // Known user defined functions in the local module
    private TreeMap declaredFunctions = new TreeMap<>();

    // Globally declared variables
    protected Map globalVariables = new TreeMap<>();

    // The last element in the linked list of local in-scope variables
    private LocalVariable lastVar = null;

    private Deque contextStack = new ArrayDeque<>();

    private Deque callStack = new ArrayDeque<>();

    // The current size of the variable stack
    private int variableStackSize = 0;

    // Unresolved references to user defined functions
    private Deque forwardReferences = new ArrayDeque<>();

    // Inline functions using closures need to be cleared after execution
    private Deque closures = new ArrayDeque<>();

    // List of options declared for this query at compile time - i.e. declare option
    private List