/****************************************************************************
**
** Copyright (C) 2016 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the QtXmlPatterns module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 3 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL3 included in the
** packaging of this file. Please review the following information to
** ensure the GNU Lesser General Public License version 3 requirements
** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 2.0 or (at your option) the GNU General
** Public license version 3 or any later version approved by the KDE Free
** Qt Foundation. The licenses are as published by the Free Software
** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
** included in the packaging of this file. Please review the following
** information to ensure the GNU General Public License requirements will
** be met: https://www.gnu.org/licenses/gpl-2.0.html and
** https://www.gnu.org/licenses/gpl-3.0.html.
**
** $QT_END_LICENSE$
**
****************************************************************************/

#include <QtCore/QBuffer>
#include <QtCore/QStringList>
#include <QtXmlPatterns/QXmlFormatter>

#include "qacceltreeresourceloader_p.h"
#include "qcommonvalues_p.h"
#include "qxmlresultitems.h"
#include "qxmlresultitems_p.h"
#include "qxmlserializer.h"
#include "qxpathhelper_p.h"

#include "qxmlquery.h"
#include "qxmlquery_p.h"

QT_BEGIN_NAMESPACE

/*!
  \class QXmlQuery

  \brief The QXmlQuery class performs XQueries on XML data, or on non-XML data modeled to look like XML.

  \reentrant
  \since 4.4
  \ingroup xml-tools
  \inmodule QtXmlPatterns

  The QXmlQuery class compiles and executes queries written in the
  \l {http://www.w3.org/TR/xquery/}{XQuery language}. QXmlQuery is
  typically used to query XML data, but it can also query non-XML
  data that has been modeled to look like XML.

  Using QXmlQuery to query XML data, as in the snippet below, is
  simple because it can use the built-in \l {QAbstractXmlNodeModel}
  {XML data model} as its delegate to the underlying query engine for
  traversing the data. The built-in data model is specified in \l
  {http://www.w3.org/TR/xpath-datamodel/} {XQuery 1.0 and XPath 2.0
  Data Model}.

  \snippet code/src_xmlpatterns_api_qabstractxmlreceiver.cpp 0

  The example uses QXmlQuery to match the first paragraph of an XML
  document and then \l {QXmlSerializer} {output the result} to a
  device as XML.

  Using QXmlQuery to query \e {non-XML} data requires writing a
  subclass of QAbstractXmlNodeModel to use as a replacement for the
  built-in XML data model. The custom data model will be able to
  traverse the non-XML data as required by the QAbstractXmlNodeModel
  interface. An instance of this custom data model then becomes the
  delegate used by the query engine to traverse the non-XML data. For
  an example of how to use QXmlQuery to query non-XML data, see the
  documentation for QAbstractXmlNodeModel.

  \section1 Running XQueries

  To run a query set up with QXmlQuery, call one of the evaluation
  functions.

  \list

  \li evaluateTo(QAbstractXmlReceiver *) is called with a pointer to an
  XML \l {QAbstractXmlReceiver} {receiver}, which receives the query
  results as a sequence of callbacks. The receiver callback class is
  like the callback class used for translating the output of a SAX
  parser. QXmlSerializer, for example, is a receiver callback class
  for translating the sequence of callbacks for output as unformatted
  XML text.

  \endlist

  \list

  \li evaluateTo(QXmlResultItems *) is called with a pointer to an
  iterator for an empty sequence of query \l {QXmlResultItems} {result
  items}.  The Java-like iterator allows the query results to be
  accessed sequentially.

  \endlist

  \list

  \li evaluateTo(QStringList *) is like evaluateTo(QXmlResultItems *),
  but the query must evaluate to a sequence of strings.

  \endlist

  \section1 Running XPath Expressions

  The XPath language is a subset of the XQuery language, so
  running an XPath expression is the same as running an XQuery
  query. Pass the XPath expression to QXmlQuery using setQuery().

  \section1 Running XSLT Stylesheets

  Running an XSLT stylesheet is like running an XQuery, except that
  when you construct your QXmlQuery, you must pass QXmlQuery::XSLT20
  to tell QXmlQuery to interpret whatever it gets from setQuery() as
  an XSLT stylesheet instead of as an XQuery. You must also set the
  input document by calling setFocus().

  \snippet code/src_xmlpatterns_api_qxmlquery.cpp 7

  \note Currently, setFocus() must be called \e before setQuery() when
  using XSLT.

  Another way to run an XSLT stylesheet is to use the \c xmlpatterns
  command line utility.

  \code
  xmlpatterns myStylesheet.xsl myInput.xml
  \endcode

  \note For the current release, XSLT support should be considered
  experimental. See section \l{XQuery#XSLT 2.0} {XSLT conformance} for
  details.

  Stylesheet parameters are bound using bindVariable().

  \section1 Binding A Query To A Starting Node

  When a query is run on XML data, as in the snippet above, the
  \c{doc()} function returns the node in the built-in data model where
  the query evaluation will begin. But when a query is run on a custom
  node model containing non-XML data, one of the bindVariable()
  functions must be called to bind a variable name to a starting node
  in the custom model.  A $variable reference is used in the XQuery
  text to access the starting node in the custom model. It is not
  necessary to declare the variable name external in the query. See
  the example in the documentation for QAbstractXmlNodeModel.

  \section1 Reentrancy and Thread-Safety

  QXmlQuery is reentrant but not thread-safe. It is safe to use the
  QxmlQuery copy constructor to create a copy of a query and run the
  same query multiple times. Behind the scenes, QXmlQuery will reuse
  resources such as opened files and compiled queries to the extent
  possible. But it is not safe to use the same instance of QXmlQuery
  in multiple threads.

  \section1 Error Handling

  Errors can occur during query evaluation. Examples include type
  errors and file loading errors. When an error occurs:

  \list

  \li The error message is sent to the messageHandler().

  \li QXmlResultItems::hasError() will return \c{true}, or
  evaluateTo() will return \c{false};

  \li The results of the evaluation are undefined.

  \endlist

  \section1 Resource Management

  When a query runs, it parses documents, allocating internal data
  structures to hold them, and it may load other resources over the
  network. It reuses these allocated resources when possible, to
  avoid having to reload and reparse them.

  When setQuery() is called, the query text is compiled into an
  internal data structure and optimized. The optimized form can
  then be reused for multiple evaluations of the query. Since the
  compile-and-optimize process can be expensive, repeating it for
  the same query should be avoided by using a separate instance of
  QXmlQuery for each query text.

  Once a document has been parsed, its internal representation is
  maintained in the QXmlQuery instance and shared among multiple
  QXmlQuery instances.

  An instance of QCoreApplication must exist before QXmlQuery can be
  used.

  \section1 Event Handling

  When QXmlQuery accesses resources (e.g., calling \c fn:doc() to load a file,
  or accessing a device via a bound variable), the event loop is used, which
  means events will be processed. To avoid processing events when QXmlQuery
  accesses resources, create your QXmlQuery instance in a separate thread.
 */

/*!
 \enum QXmlQuery::QueryLanguage
 \since 4.5

 Specifies whether you want QXmlQuery to interpret the input to
 setQuery() as an XQuery or as an XSLT stylesheet.

 \value XQuery10 XQuery 1.0.
 \value XSLT20 XSLT 2.0
 \omitvalue XmlSchema11IdentityConstraintSelector The selector, the restricted
            XPath pattern found in W3C XML Schema 1.1 for uniqueness
            contraints. Apart from restricting the syntax, the type check stage
            for the expression assumes a sequence of nodes to be the focus.
 \omitvalue XmlSchema11IdentityConstraintField The field, the restricted
            XPath pattern found in W3C XML Schema 1.1 for uniqueness
            contraints. Apart from restricting the syntax, the type check stage
            for the expression assumes a sequence of nodes to be the focus.
 \omitvalue XPath20 Signifies XPath 2.0. Has no effect in the public API, it's
            used internally. As With XmlSchema11IdentityConstraintSelector and
            XmlSchema11IdentityConstraintField, the type check stage
            for the expression assumes a sequence of nodes to be the focus.

 \sa setQuery()
 */

// ### Qt5: Merge constructor overloads
/*!
  Constructs an invalid, empty query that cannot be used until
  setQuery() is called.

  \note This constructor must not be used if you intend to use
  this QXmlQuery to process XSL-T stylesheets. The other constructor
  must be used in that case.
 */
QXmlQuery::QXmlQuery() : d(new QXmlQueryPrivate())
{
}

/*!
  Constructs a QXmlQuery that is a copy of \a other. The new
  instance will share resources with the existing query
  to the extent possible.
 */
QXmlQuery::QXmlQuery(const QXmlQuery &other) : d(new QXmlQueryPrivate(*other.d))
{
    /* First we have invoked QXmlQueryPrivate's synthesized copy constructor.
     * Keep this section in sync with QXmlQuery::operator=(). */
    d->detach();
}

/*!
  Constructs a query that will use \a np as its name pool. The query
  cannot be evaluated until setQuery() has been called.
 */
QXmlQuery::QXmlQuery(const QXmlNamePool &np) : d(new QXmlQueryPrivate(np))
{
}

/*!

  Constructs a query that will be used to run Xqueries or XSL-T
  stylesheets, depending on the value of \a queryLanguage. It will use
  \a np as its name pool.

  \note If your QXmlQuery will process XSL-T stylesheets, this
  constructor must be used. The default constructor can only
  create instances of QXmlQuery for running XQueries.

  \note The XSL-T support in this release is considered experimental.
  See the \l{XQuery#XSLT 2.0} {XSLT conformance} for details.

 \since 4.5
 \sa queryLanguage()
 */
QXmlQuery::QXmlQuery(QueryLanguage queryLanguage,
                     const QXmlNamePool &np) : d(new QXmlQueryPrivate(np))
{
    d->queryLanguage = queryLanguage;
}

/*!
  Destroys this QXmlQuery.
 */
QXmlQuery::~QXmlQuery()
{
    delete d;
}

/*!
  Assigns \a other to this QXmlQuery instance.
 */
QXmlQuery &QXmlQuery::operator=(const QXmlQuery &other)
{
    /* Keep this section in sync with QXmlQuery::QXmlQuery(const QXmlQuery &).
     */
    if(d != other.d)
    {
        *d = *other.d;
        d->detach();
    }

    return *this;
}

/*!
  Changes the \l {QAbstractMessageHandler}{message handler} for this
  QXmlQuery to \a aMessageHandler. The query sends all compile and
  runtime messages to this message handler. QXmlQuery does not take
  ownership of \a aMessageHandler.

  Normally, the default message handler is sufficient. It writes
  compile and runtime messages to \e stderr. The default message
  handler includes color codes if \e stderr can render colors.

  Note that changing the message handler after the query has been
  compiled has no effect, i.e. the query uses the same message handler
  at runtime that it uses at compile time.

  When QXmlQuery calls QAbstractMessageHandler::message(),
  the arguments are as follows:

  \table
  \header
    \li message() argument
    \li Semantics
  \row
    \li QtMsgType type
    \li Only QtWarningMsg and QtFatalMsg are used. The former
       identifies a compile or runtime warning, while the
       latter identifies a dynamic or static error.
  \row
    \li const QString & description
    \li An XHTML document which is the actual message. It is translated
       into the current language.
  \row
    \li const QUrl &identifier
    \li Identifies the error with a URI, where the fragment is
       the error code, and the rest of the URI is the error namespace.
  \row
    \li const QSourceLocation & sourceLocation
    \li Identifies where the error occurred.
  \endtable

 */
void QXmlQuery::setMessageHandler(QAbstractMessageHandler *aMessageHandler)
{
    d->messageHandler = aMessageHandler;
}

/*!
    Returns the message handler that handles compile and runtime
    messages for this QXmlQuery.
 */
QAbstractMessageHandler *QXmlQuery::messageHandler() const
{
    return d->messageHandler;
}

/*!
  Sets this QXmlQuery to an XQuery read from the \a sourceCode
  device.  The device must have been opened with at least
  QIODevice::ReadOnly.

  \a documentURI represents the query obtained from the \a sourceCode
  device. It is the base URI of the static context, as defined in the
  \l {http://www.w3.org/TR/xquery/}{XQuery language}. It is used
  internally to resolve relative URIs that appear in the query, and
  for message reporting. \a documentURI can be empty. If it is empty,
  the \l{QCoreApplication::applicationFilePath()} {application file
  path} is used. If it is not empty, it may be either relative or
  absolute. If it is relative, it is resolved itself against the
  \l {QCoreApplication::applicationFilePath()} {application file
  path} before it is used. If \a documentURI is neither a valid URI
  nor empty, the result is undefined.

  If the query contains a static error (e.g. syntax error), an error
  message is sent to the messageHandler(), and isValid() will return
  \e false.

  Variables must be bound before setQuery() is called.

  The encoding of the XQuery in \a sourceCode is detected internally
  using the rules for setting and detecting encoding of XQuery files,
  which are explained in the \l {http://www.w3.org/TR/xquery/}
  {XQuery language}.

  If \a sourceCode is \c null or not readable, or if \a documentURI is not
  a valid URI, behavior is undefined.
  \sa isValid()
 */
void QXmlQuery::setQuery(QIODevice *sourceCode, const QUrl &documentURI)
{
    if(!sourceCode)
    {
        qWarning("A null QIODevice pointer cannot be passed.");
        return;
    }

    if(!sourceCode->isReadable())
    {
        qWarning("The device must be readable.");
        return;
    }

    d->queryURI = QPatternist::XPathHelper::normalizeQueryURI(documentURI);
    d->expression(sourceCode);
}

/*!
  \overload
  The behavior and requirements of this function are the same as for
  setQuery(QIODevice*, const QUrl&), after the XQuery has been read
  from the IO device into a string. Because \a sourceCode is already
  a Unicode string, detection of its encoding is unnecessary.
*/
void QXmlQuery::setQuery(const QString &sourceCode, const QUrl &documentURI)
{
    Q_ASSERT_X(documentURI.isEmpty() || documentURI.isValid(), Q_FUNC_INFO,
               "The document URI must be valid.");

    QByteArray query(sourceCode.toUtf8());
    QBuffer buffer(&query);
    buffer.open(QIODevice::ReadOnly);

    setQuery(&buffer, documentURI);
}

/*!
  Sets this QXmlQuery to the XQuery read from the \a queryURI.  Use
  isValid() after calling this function. If an error occurred reading
  \a queryURI, e.g., the query does not exist, cannot be read, or is
  invalid, isValid() will return \e false.

  The supported URI schemes are the same as those in the XQuery
  function \c{fn:doc}, except that queryURI can be the object of
  a variable binding.

  \a baseURI is the Base URI of the static context, as defined in the
  \l {http://www.w3.org/TR/xquery/}{XQuery language}. It is used
  internally to resolve relative URIs that appear in the query, and
  for message reporting. If \a baseURI is empty, \a queryURI is used.
  Otherwise, \a baseURI is used, and it is resolved against the \l
  {QCoreApplication::applicationFilePath()} {application file path} if
  it is relative.

  If \a queryURI is empty or invalid, or if \a baseURI is invalid,
  the behavior of this function is undefined.
 */
void QXmlQuery::setQuery(const QUrl &queryURI, const QUrl &baseURI)
{
    Q_ASSERT_X(queryURI.isValid(), Q_FUNC_INFO, "The passed URI must be valid.");

    const QUrl canonicalURI(QPatternist::XPathHelper::normalizeQueryURI(queryURI));
    Q_ASSERT(canonicalURI.isValid());
    Q_ASSERT(!canonicalURI.isRelative());
    Q_ASSERT(baseURI.isValid() || baseURI.isEmpty());

    d->queryURI = QPatternist::XPathHelper::normalizeQueryURI(baseURI.isEmpty() ? queryURI : baseURI);

    QPatternist::AutoPtr<QIODevice> result;

    try
    {
        result.reset(QPatternist::AccelTreeResourceLoader::load(canonicalURI, d->m_networkAccessDelegator,
                                                                d->staticContext()));
    }
    catch(const QPatternist::Exception)
    {
        /* We do nothing, result will be 0. */
    }

    if(result)
    {
        setQuery(result.data(), d->queryURI);
        result->close();
    }
    else
        d->recompileRequired();
}

/*!
  Binds the variable \a name to the \a value so that $\a name can be
  used from within the query to refer to the \a value.

  \a name must not be \e null. \a {name}.isNull() must return false.
  If \a name has already been bound by a previous bindVariable() call,
  its previous binding will be overridden.

  If \a {value} is null so that \a {value}.isNull() returns true, and
  \a {name} already has a binding, the effect is to remove the
  existing binding for \a {name}.

  To bind a value of type QString or QUrl, wrap the value in a
  QVariant such that QXmlItem's QVariant constructor is called.

  All strings processed by the query must be valid XQuery strings,
  which means they must contain only XML 1.0 characters. However,
  this requirement is not checked. If the query processes an invalid
  string, the behavior is undefined.

  \sa QVariant::isValid(), {QtXDM}{How QVariant maps to XQuery's Data Model},
   QXmlItem::isNull()
 */
void QXmlQuery::bindVariable(const QXmlName &name, const QXmlItem &value)
{
    if(name.isNull())
    {
        qWarning("The variable name cannot be null.");
        return;
    }

    const QPatternist::VariableLoader::Ptr vl(d->variableLoader());
    const QVariant variant(QVariant::fromValue(value));

    /* If the type of the variable changed(as opposed to only the value),
     * we will have to recompile. */
    if(vl->invalidationRequired(name, variant) || value.isNull())
        d->recompileRequired();

    vl->addBinding(name, variant);
}

/*!
  \overload

  This function constructs a QXmlName from \a localName using the
  query's \l {QXmlNamePool} {namespace}. The function then behaves as
  the overloaded function. It is equivalent to the following snippet.

  \snippet code/src_xmlpatterns_api_qxmlquery.cpp 0
 */
void QXmlQuery::bindVariable(const QString &localName, const QXmlItem &value)
{
    bindVariable(QXmlName(d->namePool, localName), value);
}

/*!
  Binds the variable \a name to the \a device so that $\a name can be
  used from within the query to refer to the \a device. The QIODevice
  \a device is exposed to the query as a URI of type \c{xs:anyURI},
  which can be passed to the \c{fn:doc()} function to be read. E.g.,
  this function can be used to pass an XML document in memory to
  \c{fn:doc}.

  \snippet code/src_xmlpatterns_api_qxmlquery.cpp 1

  The caller must ensure that \a device has been opened with at least
  QIODevice::ReadOnly prior to this binding. Otherwise, behavior is
  undefined.

  If the query will access an XML document contained in a QString, use
  a QBuffer as shown in the following snippet. Suppose \e myQString
  contains \c{<document>content</document>}

  \snippet qxmlquery/bindingExample.cpp 0

  \a name must not be \e null. \a {name}.isNull() must return false.
  If \a name has already been bound, its previous binding will be
  overridden. The URI that \a name evaluates to is arbitrary and may
  change.

  If the type of the variable binding changes (e.g., if a previous
  binding by the same name was a QVariant, or if there was no previous
  binding), isValid() will return \c{false}, and recompilation of the
  query text is required. To recompile the query, call setQuery(). For
  this reason, bindVariable() should be called before setQuery(), if
  possible.

  \note \a device must not be deleted while this QXmlQuery exists.
*/
void QXmlQuery::bindVariable(const QXmlName &name, QIODevice *device)
{
    if(device && !device->isReadable())
    {
        qWarning("A null, or readable QIODevice must be passed.");
        return;
    }

    if(name.isNull())
    {
        qWarning("The variable name cannot be null.");
        return;
    }

    const QPatternist::VariableLoader::Ptr vl(d->variableLoader());

    if(device)
    {
        const QVariant variant(QVariant::fromValue(device));

        if(vl->invalidationRequired(name, variant))
            d->recompileRequired();

        vl->addBinding(name, variant);

        /* We need to tell the resource loader to discard its document, because
         * the underlying QIODevice has changed, but the variable name is the
         * same which means that the URI is the same, and hence the resource
         * loader will return the document for the old QIODevice.
         */
        d->resourceLoader()->clear(QUrl(QLatin1String("tag:trolltech.com,2007:QtXmlPatterns:QIODeviceVariable:") + d->namePool.d->stringForLocalName(name.localName())));
    }
    else
    {
        vl->removeBinding(name);
        d->recompileRequired();
    }
}

/*!
  \overload

  If \a localName is a valid \l {QXmlName::isNCName()} {NCName}, this
  function is equivalent to the following snippet.

  \snippet code/src_xmlpatterns_api_qxmlquery.cpp 2

  A QXmlName is constructed from \a localName, and is passed
  to the appropriate overload along with \a device.

  \sa QXmlName::isNCName()
 */
void QXmlQuery::bindVariable(const QString &localName, QIODevice *device)
{
    bindVariable(QXmlName(d->namePool, localName), device);
}

/*!
  Evaluates this query and sends the result as a sequence of callbacks
  to the \l {QAbstractXmlReceiver} {receiver} \a callback. QXmlQuery
  does not take ownership of \a callback.

  If an error occurs during the evaluation, error messages are sent to
  messageHandler() and \c false is returned.

  If this query \l {isValid()} {is invalid}, \c{false} is returned
  and the behavior is undefined. If \a callback is null,
  behavior is undefined.

  \sa QAbstractXmlReceiver, isValid()
 */
bool QXmlQuery::evaluateTo(QAbstractXmlReceiver *callback) const
{
    if(!callback)
    {
        qWarning("A non-null callback must be passed.");
        return false;
    }

    if(isValid())
    {
        try
        {
            /*
             * This order is significant. expression() might cause
             * query recompilation, and as part of that it recreates
             * the static context. However, if we create the dynamic
             * context before the query recompilation has been
             * triggered, it will use the old static context, and
             * hence old source locations.
             */
            const QPatternist::Expression::Ptr expr(d->expression());
            const QPatternist::DynamicContext::Ptr dynContext(d->dynamicContext(callback));
            callback->startOfSequence();
            expr->evaluateToSequenceReceiver(dynContext);
            callback->endOfSequence();
            return true;
        }
        catch(const QPatternist::Exception)
        {
            return false;
        }
    }
    else
        return false;
}

/*!
  Attempts to evaluate the query and returns the results in the
  \a target \l {QStringList} {string list}.

  If the query \l {isValid()} {is valid} and the evaluation succeeds,
  true is returned. Otherwise, false is returned and the contents of
  \a target are undefined.

  The query must evaluate to a sequence of \c{xs:string} values. If
  the query does not evaluate to a sequence of strings, the values can
  often be converted by adding a call to \c{string()} at the end of
  the XQuery.

  If \a target is null, the behavior is undefined.
 */
bool QXmlQuery::evaluateTo(QStringList *target) const
{
    if(!target)
    {
        qWarning("A non-null callback must be passed.");
        return false;
    }

    if(isValid())
    {
        try
        {
            /*
             * This order is significant. expression() might cause
             * query recompilation, and as part of that it recreates
             * the static context. However, if we create the dynamic
             * context before the query recompilation has been
             * triggered, it will use the old static context, and
             * hence old source locations.
             */
            const QPatternist::Expression::Ptr expr(d->expression());
            if(!expr)
                return false;

            QPatternist::DynamicContext::Ptr dynContext(d->dynamicContext());

            if(!QPatternist::BuiltinTypes::xsString->xdtTypeMatches(expr->staticType()->itemType()))
                return false;

            const QPatternist::Item::Iterator::Ptr it(expr->evaluateSequence(dynContext));
            QPatternist::Item next(it->next());

            while(!next.isNull())
            {
                target->append(next.stringValue());
                next = it->next();
            }

            return true;
        }
        catch(const QPatternist::Exception)
        {
            return false;
        }
    }
    else
        return false;
}

/*!
  Evaluates the query or stylesheet, and writes the output to \a target.

  QXmlSerializer is used to write the output to \a target. In a future
  release, it is expected that this function will be changed to
  respect serialization options set in the stylesheet.

  If an error occurs during the evaluation, error messages are sent to
  messageHandler() and \c false is returned.

  If \a target is \c null, or is not opened in at least
  QIODevice::WriteOnly mode, the behavior is undefined.  QXmlQuery
  does not take ownership of \a target.

  \since 4.5
  \overload
 */
bool QXmlQuery::evaluateTo(QIODevice *target) const
{
    if(!target)
    {
        qWarning("The pointer to the device cannot be null.");
        return false;
    }

    if(!target->isWritable())
    {
        qWarning("The device must be writable.");
        return false;
    }

    QXmlSerializer serializer(*this, target);
    return evaluateTo(&serializer);
}

/*!
  Starts the evaluation and makes it available in \a result.  If \a
  result is null, the behavior is undefined. The evaluation takes
  place incrementally (lazy evaluation), as the caller uses
  QXmlResultItems::next() to get the next result.

  \sa QXmlResultItems::next()
*/
void QXmlQuery::evaluateTo(QXmlResultItems *result) const
{
    if(!result)
    {
        qWarning("A null pointer cannot be passed.");
        return;
    }

    if(isValid())
    {
        try
        {
            /*
             * We don't have the d->expression() calls and
             * d->dynamicContext() calls in the same order as seen in
             * QXmlQuery::evaluateTo(), and the reason to why
             * that isn't a problem, is that we call isValid().
             */
            const QPatternist::DynamicContext::Ptr dynContext(d->dynamicContext());
            result->d_ptr->setDynamicContext(dynContext);
            result->d_ptr->iterator = d->expression()->evaluateSequence(dynContext);
        }
        catch(const QPatternist::Exception)
        {
            result->d_ptr->iterator = QPatternist::CommonValues::emptyIterator;
            result->d_ptr->hasError = true;
        }
    }
    else
    {
        result->d_ptr->iterator= QPatternist::CommonValues::emptyIterator;
        result->d_ptr->hasError = true;
    }
}

/*!
  Evaluates the query, and serializes the output as XML to \a output.

  If an error occurs during the evaluation, error messages are sent to
  messageHandler(), the content of \a output is undefined and \c false is
  returned, otherwise \c true is returned.

  If \a output is \c null behavior is undefined. QXmlQuery
  does not take ownership of \a output.

  Internally, the class QXmlFormatter is used for this.
 \since 4.5
 */
bool QXmlQuery::evaluateTo(QString *output) const
{
    Q_ASSERT_X(output, Q_FUNC_INFO,
               "The input cannot be null");

    QBuffer outputDevice;
    outputDevice.open(QIODevice::ReadWrite);

    QXmlFormatter formatter(*this, &outputDevice);
    const bool success = evaluateTo(&formatter);

    outputDevice.close();
    *output = QString::fromUtf8(outputDevice.data().constData());

    return success;
}

/*!
  Returns true if this query is valid. Examples of invalid queries
  are ones that contain syntax errors or that have not had setQuery()
  called for them yet.
 */
bool QXmlQuery::isValid() const
{
    return d->isValid();
}

/*!
  Sets the URI resolver to \a resolver. QXmlQuery does not take
  ownership of \a resolver.

  \sa uriResolver()
 */
void QXmlQuery::setUriResolver(const QAbstractUriResolver *resolver)
{
    d->uriResolver = resolver;
}

/*!
  Returns the query's URI resolver. If no URI resolver has been set,
  Qt XML Patterns will use the URIs in queries as they are.

  The URI resolver provides a level of abstraction, or \e{polymorphic
  URIs}. A resolver can rewrite \e{logical} URIs to physical ones, or
  it can translate obsolete or invalid URIs to valid ones.

  Qt XML Patterns calls the URI resolver for all URIs it encounters,
  except for namespaces. Specifically, all builtin functions that deal
  with URIs (\c{fn:doc()}, and \c{fn:doc-available()}).

  In the case of \c{fn:doc()}, the absolute URI is the base URI in the
  static context (which most likely is the location of the query).
  Rather than use the URI the user specified, the return value of
  QAbstractUriResolver::resolve() will be used.

  When Qt XML Patterns calls QAbstractUriResolver::resolve() the
  absolute URI is the URI mandated by the XQuery language, and the
  relative URI is the URI specified by the user.

  \sa setUriResolver()
 */
const QAbstractUriResolver *QXmlQuery::uriResolver() const
{
    return d->uriResolver;
}

/*!
  Returns the name pool used by this QXmlQuery for constructing \l
  {QXmlName} {names}. There is no setter for the name pool, because
  mixing name pools causes errors due to name confusion.
 */
QXmlNamePool QXmlQuery::namePool() const
{
    return d->namePool;
}

/*!
  Sets the focus to \a item. The focus is the set of items that the
  context item expression and path expressions navigate from. For
  example, in the expression \e p/span, the element that \e p
  evaluates to is the focus for the following expression, \e span.

  The focus can be accessed using the context item expression, i.e.,
  dot (".").

  By default, the focus is not set and is undefined. It will
  therefore result in a dynamic error, \c XPDY0002, if the focus
  is attempted to be accessed. The focus must be set before the
  query is set with setQuery().

  There is no behavior defined for setting an item which is null.

 */
void QXmlQuery::setFocus(const QXmlItem &item)
{
    d->contextItem = item;
}

/**
 * This function should be a private member function of QXmlQuery,
 * but we don't dare that due to our weird compilers.
 * @internal
 * @relates QXmlQuery
 */
template<typename TInputType>
bool setFocusHelper(QXmlQuery *const queryInstance,
                    const TInputType &focusValue)
{
    /* We call resourceLoader(), so we have ensured that we have a resourceLoader
     * that we will share in our copy. */
    queryInstance->d->resourceLoader();

    QXmlQuery focusQuery(*queryInstance);

    /* Now we use the same, so we own the loaded document. */
    focusQuery.d->m_resourceLoader = queryInstance->d->m_resourceLoader;

    /* The copy constructor doesn't allow us to copy an existing QXmlQuery and
     * changing the language at the same time so we need to use private API. */
    focusQuery.d->queryLanguage = QXmlQuery::XQuery10;

    Q_ASSERT(focusQuery.queryLanguage() == QXmlQuery::XQuery10);
    focusQuery.bindVariable(QChar::fromLatin1('u'), focusValue);
    focusQuery.setQuery(QLatin1String("doc($u)"));
    Q_ASSERT(focusQuery.isValid());

    QXmlResultItems focusResult;

    queryInstance->d->m_resourceLoader = focusQuery.d->m_resourceLoader;

    focusQuery.evaluateTo(&focusResult);
    const QXmlItem focusItem(focusResult.next());

    if(focusItem.isNull() || focusResult.hasError())
        return false;
    else
    {
        queryInstance->setFocus(focusItem);
        return true;
    }
}

/*!
  \since 4.5
  \overload

  Sets the focus to be the document located at \a documentURI and
  returns true. If \a documentURI cannot be loaded, false is returned.
  It is undefined at what time the document may be loaded. When
  loading the document, the message handler and URI resolver set on
  this QXmlQuery are used.

  If \a documentURI is empty or is not a valid URI, the behavior of
  this function is undefined.
 */
bool QXmlQuery::setFocus(const QUrl &documentURI)
{
    Q_ASSERT_X(documentURI.isValid() && !documentURI.isEmpty(),
               Q_FUNC_INFO,
               "The URI passed must be valid.");

    return setFocusHelper(this, QVariant(documentURI));
}

/*!

  Sets the focus to be the \a document read from the QIODevice and
  returns true. If \a document cannot be loaded, false is returned.

  QXmlQuery does not take ownership of \a document. The user
  guarantees that a document is available from the \a document device
  and that the document is not empty. The device must be opened in at
  least read-only mode. \a document must stay in scope as long as the
  current query is active.

 \since 4.5
 \overload
 */
bool QXmlQuery::setFocus(QIODevice *document)
{
    if(!document)
    {
        qWarning("A null QIODevice pointer cannot be passed.");
        return false;
    }

    if(!document->isReadable())
    {
        qWarning("The device must be readable.");
        return false;
    }

    return setFocusHelper(this, document);
}

/*!
  This function behaves identically to calling the setFocus() overload with a
  QIODevice whose content is \a focus encoded as UTF-8. That is, \a focus is
  treated as if it contained an XML document.

  Returns the same result as the overload.

  \overload
  \since 4.6
 */
bool QXmlQuery::setFocus(const QString &focus)
{
    QBuffer device;
    device.setData(focus.toUtf8());
    device.open(QIODevice::ReadOnly);

    return setFocusHelper(this, &device);
}

/*!
  Returns a value indicating what this QXmlQuery is being used for.
  The default is QXmlQuery::XQuery10, which means the QXmlQuery is
  being used for running XQuery and XPath queries. QXmlQuery::XSLT20
  can also be returned, which indicates the QXmlQuery is for running
  XSL-T spreadsheets.

 \since 4.5
 */
QXmlQuery::QueryLanguage QXmlQuery::queryLanguage() const
{
    return d->queryLanguage;
}

/*!
  Sets the \a name of the initial template. The initial template is
  the one the processor calls first, instead of attempting to match a
  template to the context node (if any). If an initial template is not
  set, the standard order of template invocation will be used.

  This function only applies when using QXmlQuery to process XSL-T
  stylesheets. The name becomes part of the compiled stylesheet.
  Therefore, this function must be called before calling setQuery().

  If the stylesheet has no template named \a name, the processor will
  use the standard order of template invocation.

  \since 4.5
  \sa initialTemplateName()
 */
void QXmlQuery::setInitialTemplateName(const QXmlName &name)
{
    d->initialTemplateName = name;
}

/*!
  \overload

  Sets the name of the initial template to \a localName, which must be
  a valid \l{QXmlName::localName}{local name}. The initial template
  is the one the processor calls first, instead of attempting to match
  a template to the context node (if any). If an initial template is
  not set, the standard order of template invocation will be used.

  This function only applies when using QXmlQuery to process XSL-T
  stylesheets. The name becomes part of the compiled stylesheet.
  Therefore, this function must be called before calling setQuery().

  If \a localName is not a valid \l{QXmlName::localName} {local
  name}, the effect is undefined. If the stylesheet has no template
  named \a localName, the processor will use the standard order of
  template invocation.

  \since 4.5
  \sa initialTemplateName()
 */
void QXmlQuery::setInitialTemplateName(const QString &localName)
{
    Q_ASSERT_X(QXmlName::isNCName(localName),
               Q_FUNC_INFO,
               "The name passed must be a valid NCName.");
    setInitialTemplateName(QXmlName(d->namePool, localName));
}

/*!
  Returns the name of the XSL-T stylesheet template that the processor
  will call first when running an XSL-T stylesheet. This function only
  applies when using QXmlQuery to process XSL-T stylesheets. By
  default, no initial template is set. In that case, a default
  constructed QXmlName is returned.

  \since 4.5
 */
QXmlName QXmlQuery::initialTemplateName() const
{
    return d->initialTemplateName;
}

/*!
  Sets the network manager to \a newManager.
  QXmlQuery does not take ownership of \a newManager.

  \sa networkAccessManager()
  \since 4.5
 */
void QXmlQuery::setNetworkAccessManager(QNetworkAccessManager *newManager)
{
    d->m_networkAccessDelegator->m_genericManager = newManager;
}

/*!
  Returns the network manager, or 0 if it has not been set.

  \sa setNetworkAccessManager()
  \since 4.5
 */
QNetworkAccessManager *QXmlQuery::networkAccessManager() const
{
    return d->m_networkAccessDelegator->m_genericManager;
}

/*!
  Binds the result of the query \a query, to a variable by name \a name.

  Evaluation of \a query will be commenced when this function is called.

  If \a query is invalid, behavior is undefined. \a query will be copied.

  \since 4.5
  \sa isValid()
 */
void QXmlQuery::bindVariable(const QXmlName &name, const QXmlQuery &query)
{
    Q_ASSERT_X(query.isValid(), Q_FUNC_INFO, "The query being bound must be valid.");

    const QPatternist::VariableLoader::Ptr vl(d->variableLoader());
    const QVariant variant(QVariant::fromValue(query));

    if(vl->invalidationRequired(name, variant))
        d->recompileRequired();

    vl->addBinding(name, variant);
}

/*!
 \overload

 Has the same behavior and effects as the function being overloaded, but takes
 the variable name \a localName as a QString. \a query is used as in the
 overloaded function.

  \since 4.5
 */
void QXmlQuery::bindVariable(const QString &localName, const QXmlQuery &query)
{
    return bindVariable(QXmlName(d->namePool, localName), query);
}

QT_END_NAMESPACE
