src/xmlpatterns/api/qxmlquery_p.h
changeset 0 1918ee327afb
child 4 3b1da2848fc7
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/xmlpatterns/api/qxmlquery_p.h	Mon Jan 11 14:00:40 2010 +0000
@@ -0,0 +1,328 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file.  Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights.  These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+//  W A R N I N G
+//  -------------
+//
+// This file is not part of the Qt API.  It exists purely as an
+// implementation detail.  This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+
+#ifndef QXMLQUERY_P_H
+#define QXMLQUERY_P_H
+
+#include <QAbstractMessageHandler>
+#include <QAbstractUriResolver>
+#include <QPointer>
+#include <QSourceLocation>
+#include <QUrl>
+#include <QVariant>
+#include <QXmlName>
+#include <QXmlNamePool>
+#include <QXmlQuery>
+
+#include "qacceltreebuilder_p.h"
+#include "qacceltreeresourceloader_p.h"
+#include "qcoloringmessagehandler_p.h"
+#include "qcommonsequencetypes_p.h"
+#include "qexpressionfactory_p.h"
+#include "qfocus_p.h"
+#include "qfunctionfactorycollection_p.h"
+#include "qgenericdynamiccontext_p.h"
+#include "qgenericstaticcontext_p.h"
+#include "qnamepool_p.h"
+#include "qnetworkaccessdelegator_p.h"
+#include "qreferencecountedvalue_p.h"
+#include "qresourcedelegator_p.h"
+#include "qstaticfocuscontext_p.h"
+#include "quriloader_p.h"
+#include "qvariableloader_p.h"
+
+QT_BEGIN_NAMESPACE
+
+class QXmlQueryPrivate
+{
+public:
+
+    inline QXmlQueryPrivate(const QXmlNamePool &np = QXmlNamePool()) : namePool(np)
+                                                                     , messageHandler(0)
+                                                                     , uriResolver(0)
+                                                                     , queryLanguage(QXmlQuery::XQuery10)
+                                                                     , m_networkAccessDelegator(new QPatternist::NetworkAccessDelegator(0, 0))
+    {
+        m_networkAccessDelegator->m_variableURIManager = new QPatternist::URILoader(ownerObject(), namePool.d, variableLoader());
+    }
+
+    void detach()
+    {
+        if(m_variableLoader)
+            m_variableLoader = QPatternist::VariableLoader::Ptr(new QPatternist::VariableLoader(namePool.d, m_variableLoader));
+
+        delete m_networkAccessDelegator->m_variableURIManager;
+        m_networkAccessDelegator->m_variableURIManager = new QPatternist::URILoader(ownerObject(), namePool.d, m_variableLoader);
+
+        if(m_resourceLoader)
+        {
+            const QPatternist::AccelTreeResourceLoader::Ptr nev(new QPatternist::AccelTreeResourceLoader(namePool.d,
+                                                                                                         m_networkAccessDelegator));
+            m_resourceLoader = QPatternist::ResourceLoader::Ptr(new QPatternist::ResourceDelegator(m_resourceLoader->deviceURIs(),
+                                                                                                   m_resourceLoader,
+                                                                                                   nev));
+        }
+    }
+
+    bool isValid()
+    {
+        return expression();
+    }
+
+    inline void recompileRequired()
+    {
+        m_expr.reset();
+    }
+
+    inline QPatternist::VariableLoader::Ptr variableLoader()
+    {
+        if(!m_variableLoader)
+            m_variableLoader = QPatternist::VariableLoader::Ptr(new QPatternist::VariableLoader(namePool.d));
+
+        return m_variableLoader;
+    }
+
+    inline QPatternist::GenericStaticContext::Ptr staticContext()
+    {
+        if(m_staticContext && m_expr)
+            return m_staticContext;
+        /* Else, re-create the staticContext. */
+
+        if(!messageHandler)
+            messageHandler = new QPatternist::ColoringMessageHandler(ownerObject());
+
+        if(!m_functionFactory)
+        {
+            if(queryLanguage == QXmlQuery::XSLT20)
+                m_functionFactory = QPatternist::FunctionFactoryCollection::xslt20Factory(namePool.d);
+            else
+                m_functionFactory = QPatternist::FunctionFactoryCollection::xpath20Factory(namePool.d);
+        }
+
+        const QPatternist::GenericStaticContext::Ptr genericStaticContext(new QPatternist::GenericStaticContext(namePool.d,
+                                                                                                                messageHandler,
+                                                                                                                queryURI,
+                                                                                                                m_functionFactory,
+                                                                                                                queryLanguage));
+        genericStaticContext->setResourceLoader(resourceLoader());
+
+        genericStaticContext->setExternalVariableLoader(variableLoader());
+
+        m_staticContext = genericStaticContext;
+
+        if(!contextItem.isNull())
+            m_staticContext = QPatternist::StaticContext::Ptr(new QPatternist::StaticFocusContext(QPatternist::AtomicValue::qtToXDMType(contextItem), m_staticContext));
+        else if(   queryLanguage == QXmlQuery::XmlSchema11IdentityConstraintField
+                || queryLanguage == QXmlQuery::XmlSchema11IdentityConstraintSelector
+                || queryLanguage == QXmlQuery::XPath20)
+            m_staticContext = QPatternist::StaticContext::Ptr(new QPatternist::StaticFocusContext(QPatternist::BuiltinTypes::node, m_staticContext));
+
+        for (int i = 0; i < m_additionalNamespaceBindings.count(); ++i) {
+            m_staticContext->namespaceBindings()->addBinding(m_additionalNamespaceBindings.at(i));
+        }
+
+        return m_staticContext;
+    }
+
+    inline QPatternist::DynamicContext::Ptr dynamicContext(QAbstractXmlReceiver *const callback = 0)
+    {
+        const QPatternist::StaticContext::Ptr statContext(staticContext());
+        Q_ASSERT(statContext);
+
+        QPatternist::GenericDynamicContext::Ptr dynContext(new QPatternist::GenericDynamicContext(namePool.d, statContext->messageHandler(),
+                                                                                                  statContext->sourceLocations()));
+
+        QPatternist::AutoPtr<QPatternist::NodeBuilder> nodeBuilder(new QPatternist::AccelTreeBuilder<false>(QUrl(), QUrl(), namePool.d,
+                                                                                                            dynContext.data()));
+        dynContext->setNodeBuilder(nodeBuilder);
+
+        dynContext->setResourceLoader(statContext->resourceLoader());
+        dynContext->setExternalVariableLoader(statContext->externalVariableLoader());
+        dynContext->setUriResolver(uriResolver);
+
+        if(callback)
+            dynContext->setOutputReceiver(callback);
+
+        if(contextItem.isNull())
+            return dynContext;
+        else
+        {
+            QPatternist::DynamicContext::Ptr focus(new QPatternist::Focus(dynContext));
+            QPatternist::Item::Iterator::Ptr it(QPatternist::makeSingletonIterator(QPatternist::Item::fromPublic(contextItem)));
+            it->next();
+            focus->setFocusIterator(it);
+            return focus;
+        }
+    }
+
+    inline QPatternist::AccelTreeResourceLoader::Ptr resourceLoader()
+    {
+        if(!m_resourceLoader)
+            m_resourceLoader = (new QPatternist::AccelTreeResourceLoader(namePool.d, m_networkAccessDelegator));
+
+        return m_resourceLoader;
+    }
+
+    void setRequiredType(const QPatternist::SequenceType::Ptr &seqType)
+    {
+        Q_ASSERT(seqType);
+        if(!m_requiredType || m_requiredType->is(seqType))
+            return;
+
+        m_requiredType = seqType;
+        m_staticContext.reset();
+    }
+
+    QPatternist::SequenceType::Ptr requiredType()
+    {
+        if(m_requiredType)
+            return m_requiredType;
+        else
+        {
+            m_requiredType = QPatternist::CommonSequenceTypes::ZeroOrMoreItems;
+            return m_requiredType;
+        }
+    }
+
+    QPatternist::Expression::Ptr expression(QIODevice *const queryDevice = 0)
+    {
+        if(m_expr && !queryDevice)
+            return m_expr;
+
+        /* If we need to update, but we don't have any source code, we can
+         * never create an Expression. */
+        if(!queryDevice)
+            return QPatternist::Expression::Ptr();
+
+        try
+        {
+            /* The static context has source locations, and they need to be
+             * updated to the new query. */
+            m_staticContext.reset();
+
+            if(!m_expressionFactory)
+                m_expressionFactory = QPatternist::ExpressionFactory::Ptr(new QPatternist::ExpressionFactory());
+
+            m_expr = m_expressionFactory->createExpression(queryDevice, staticContext(),
+                                                           queryLanguage,
+                                                           requiredType(),
+                                                           queryURI,
+                                                           initialTemplateName);
+        }
+        catch(const QPatternist::Exception)
+        {
+            m_expr.reset();
+
+            /* We don't call m_staticContext.reset() because it shouldn't be
+             * necessary, since m_staticContext is changed when the expression
+             * is changed. */
+        }
+
+        return m_expr;
+    }
+
+    inline void addAdditionalNamespaceBinding(const QXmlName &binding)
+    {
+        m_additionalNamespaceBindings.append(binding);
+    }
+
+    QXmlNamePool                                namePool;
+    QPointer<QAbstractMessageHandler>           messageHandler;
+    /**
+     * Must be absolute and valid.
+     */
+    QUrl                                        queryURI;
+    const QAbstractUriResolver *                uriResolver;
+    QXmlItem                                    contextItem;
+    QXmlName                                    initialTemplateName;
+
+    inline void setExpressionFactory(const QPatternist::ExpressionFactory::Ptr &expr)
+    {
+        m_expressionFactory = expr;
+    }
+
+    QXmlQuery::QueryLanguage                    queryLanguage;
+    QPointer<QNetworkAccessManager>             userNetworkManager;
+
+    inline QObject *ownerObject()
+    {
+        if(!m_owner)
+            m_owner = new QPatternist::ReferenceCountedValue<QObject>(new QObject());
+
+        return m_owner->value;
+    }
+
+    QPatternist::ExpressionFactory::Ptr         m_expressionFactory;
+    QPatternist::StaticContext::Ptr             m_staticContext;
+    QPatternist::VariableLoader::Ptr            m_variableLoader;
+    QPatternist::DeviceResourceLoader::Ptr      m_resourceLoader;
+    /**
+     * This is the AST for the query.
+     */
+    QPatternist::Expression::Ptr                m_expr;
+    QPatternist::ReferenceCountedValue<QObject>::Ptr m_owner;
+
+    /**
+     * This is our effective network manager, that we end up using. The one the
+     * user sets is userNetworkManager.
+     */
+    QPatternist::SequenceType::Ptr              m_requiredType;
+    QPatternist::FunctionFactory::Ptr           m_functionFactory;
+    QPatternist::NetworkAccessDelegator::Ptr    m_networkAccessDelegator;
+
+    QList<QXmlName>                             m_additionalNamespaceBindings;
+};
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif