1 /****************************************************************************
3 ** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
4 ** Contact: http://www.qt-project.org/
6 ** This file is part of the QtXmlPatterns module of the Qt Toolkit.
8 ** $QT_BEGIN_LICENSE:LGPL$
9 ** GNU Lesser General Public License Usage
10 ** This file may be used under the terms of the GNU Lesser General Public
11 ** License version 2.1 as published by the Free Software Foundation and
12 ** appearing in the file LICENSE.LGPL included in the packaging of this
13 ** file. Please review the following information to ensure the GNU Lesser
14 ** General Public License version 2.1 requirements will be met:
15 ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
17 ** In addition, as a special exception, Nokia gives you certain additional
18 ** rights. These rights are described in the Nokia Qt LGPL Exception
19 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
21 ** GNU General Public License Usage
22 ** Alternatively, this file may be used under the terms of the GNU General
23 ** Public License version 3.0 as published by the Free Software Foundation
24 ** and appearing in the file LICENSE.GPL included in the packaging of this
25 ** file. Please review the following information to ensure the GNU General
26 ** Public License version 3.0 requirements will be met:
27 ** http://www.gnu.org/copyleft/gpl.html.
30 ** Alternatively, this file may be used in accordance with the terms and
31 ** conditions contained in a signed written agreement between you and Nokia.
40 ****************************************************************************/
46 // This file is not part of the Qt API. It exists purely as an
47 // implementation detail. This header file may change from version to
48 // version without notice, or even be removed.
55 #include <QAbstractMessageHandler>
56 #include <QAbstractUriResolver>
58 #include <QSourceLocation>
62 #include <QXmlNamePool>
65 #include <private/qacceltreebuilder_p.h>
66 #include <private/qacceltreeresourceloader_p.h>
67 #include <private/qcoloringmessagehandler_p.h>
68 #include <private/qcommonsequencetypes_p.h>
69 #include <private/qexpressionfactory_p.h>
70 #include <private/qfocus_p.h>
71 #include <private/qfunctionfactorycollection_p.h>
72 #include <private/qgenericdynamiccontext_p.h>
73 #include <private/qgenericstaticcontext_p.h>
74 #include <private/qnamepool_p.h>
75 #include <private/qnetworkaccessdelegator_p.h>
76 #include <private/qreferencecountedvalue_p.h>
77 #include <private/qresourcedelegator_p.h>
78 #include <private/qstaticfocuscontext_p.h>
79 #include <private/quriloader_p.h>
80 #include <private/qvariableloader_p.h>
84 class QXmlQueryPrivate
88 inline QXmlQueryPrivate(const QXmlNamePool &np = QXmlNamePool()) : namePool(np)
91 , queryLanguage(QXmlQuery::XQuery10)
92 , m_networkAccessDelegator(new QPatternist::NetworkAccessDelegator(0, 0))
94 m_networkAccessDelegator->m_variableURIManager = new QPatternist::URILoader(ownerObject(), namePool.d, variableLoader());
100 m_variableLoader = QPatternist::VariableLoader::Ptr(new QPatternist::VariableLoader(namePool.d, m_variableLoader));
102 delete m_networkAccessDelegator->m_variableURIManager;
103 m_networkAccessDelegator->m_variableURIManager = new QPatternist::URILoader(ownerObject(), namePool.d, m_variableLoader);
107 const QPatternist::AccelTreeResourceLoader::Ptr nev(new QPatternist::AccelTreeResourceLoader(namePool.d,
108 m_networkAccessDelegator));
109 m_resourceLoader = QPatternist::ResourceLoader::Ptr(new QPatternist::ResourceDelegator(m_resourceLoader->deviceURIs(),
120 inline void recompileRequired()
125 inline QPatternist::VariableLoader::Ptr variableLoader()
127 if(!m_variableLoader)
128 m_variableLoader = QPatternist::VariableLoader::Ptr(new QPatternist::VariableLoader(namePool.d));
130 return m_variableLoader;
133 inline QPatternist::GenericStaticContext::Ptr staticContext()
135 if(m_staticContext && m_expr)
136 return m_staticContext;
137 /* Else, re-create the staticContext. */
140 messageHandler = new QPatternist::ColoringMessageHandler(ownerObject());
142 if(!m_functionFactory)
144 if(queryLanguage == QXmlQuery::XSLT20)
145 m_functionFactory = QPatternist::FunctionFactoryCollection::xslt20Factory(namePool.d);
147 m_functionFactory = QPatternist::FunctionFactoryCollection::xpath20Factory(namePool.d);
150 const QPatternist::GenericStaticContext::Ptr genericStaticContext(new QPatternist::GenericStaticContext(namePool.d,
155 genericStaticContext->setResourceLoader(resourceLoader());
157 genericStaticContext->setExternalVariableLoader(variableLoader());
159 m_staticContext = genericStaticContext;
161 if(!contextItem.isNull())
162 m_staticContext = QPatternist::StaticContext::Ptr(new QPatternist::StaticFocusContext(QPatternist::AtomicValue::qtToXDMType(contextItem), m_staticContext));
163 else if( queryLanguage == QXmlQuery::XmlSchema11IdentityConstraintField
164 || queryLanguage == QXmlQuery::XmlSchema11IdentityConstraintSelector
165 || queryLanguage == QXmlQuery::XPath20)
166 m_staticContext = QPatternist::StaticContext::Ptr(new QPatternist::StaticFocusContext(QPatternist::BuiltinTypes::node, m_staticContext));
168 for (int i = 0; i < m_additionalNamespaceBindings.count(); ++i) {
169 m_staticContext->namespaceBindings()->addBinding(m_additionalNamespaceBindings.at(i));
172 return m_staticContext;
175 inline QPatternist::DynamicContext::Ptr dynamicContext(QAbstractXmlReceiver *const callback = 0)
177 const QPatternist::StaticContext::Ptr statContext(staticContext());
178 Q_ASSERT(statContext);
180 QPatternist::GenericDynamicContext::Ptr dynContext(new QPatternist::GenericDynamicContext(namePool.d, statContext->messageHandler(),
181 statContext->sourceLocations()));
183 QPatternist::AutoPtr<QPatternist::NodeBuilder> nodeBuilder(new QPatternist::AccelTreeBuilder<false>(QUrl(), QUrl(), namePool.d,
185 dynContext->setNodeBuilder(nodeBuilder);
187 dynContext->setResourceLoader(statContext->resourceLoader());
188 dynContext->setExternalVariableLoader(statContext->externalVariableLoader());
189 dynContext->setUriResolver(uriResolver);
192 dynContext->setOutputReceiver(callback);
194 if(contextItem.isNull())
198 QPatternist::DynamicContext::Ptr focus(new QPatternist::Focus(dynContext));
199 QPatternist::Item::Iterator::Ptr it(QPatternist::makeSingletonIterator(QPatternist::Item::fromPublic(contextItem)));
201 focus->setFocusIterator(it);
206 inline QPatternist::AccelTreeResourceLoader::Ptr resourceLoader()
208 if(!m_resourceLoader)
209 m_resourceLoader = (new QPatternist::AccelTreeResourceLoader(namePool.d, m_networkAccessDelegator));
211 return m_resourceLoader;
214 void setRequiredType(const QPatternist::SequenceType::Ptr &seqType)
217 if(!m_requiredType || m_requiredType->is(seqType))
220 m_requiredType = seqType;
221 m_staticContext.reset();
224 QPatternist::SequenceType::Ptr requiredType()
227 return m_requiredType;
230 m_requiredType = QPatternist::CommonSequenceTypes::ZeroOrMoreItems;
231 return m_requiredType;
235 QPatternist::Expression::Ptr expression(QIODevice *const queryDevice = 0)
237 if(m_expr && !queryDevice)
240 /* If we need to update, but we don't have any source code, we can
241 * never create an Expression. */
243 return QPatternist::Expression::Ptr();
247 /* The static context has source locations, and they need to be
248 * updated to the new query. */
249 m_staticContext.reset();
251 if(!m_expressionFactory)
252 m_expressionFactory = QPatternist::ExpressionFactory::Ptr(new QPatternist::ExpressionFactory());
254 m_expr = m_expressionFactory->createExpression(queryDevice, staticContext(),
258 initialTemplateName);
260 catch(const QPatternist::Exception)
264 /* We don't call m_staticContext.reset() because it shouldn't be
265 * necessary, since m_staticContext is changed when the expression
272 inline void addAdditionalNamespaceBinding(const QXmlName &binding)
274 m_additionalNamespaceBindings.append(binding);
277 QXmlNamePool namePool;
278 QPointer<QAbstractMessageHandler> messageHandler;
280 * Must be absolute and valid.
283 const QAbstractUriResolver * uriResolver;
284 QXmlItem contextItem;
285 QXmlName initialTemplateName;
287 inline void setExpressionFactory(const QPatternist::ExpressionFactory::Ptr &expr)
289 m_expressionFactory = expr;
292 QXmlQuery::QueryLanguage queryLanguage;
293 QPointer<QNetworkAccessManager> userNetworkManager;
295 inline QObject *ownerObject()
298 m_owner = new QPatternist::ReferenceCountedValue<QObject>(new QObject());
300 return m_owner->value;
303 QPatternist::ExpressionFactory::Ptr m_expressionFactory;
304 QPatternist::StaticContext::Ptr m_staticContext;
305 QPatternist::VariableLoader::Ptr m_variableLoader;
306 QPatternist::DeviceResourceLoader::Ptr m_resourceLoader;
308 * This is the AST for the query.
310 QPatternist::Expression::Ptr m_expr;
311 QPatternist::ReferenceCountedValue<QObject>::Ptr m_owner;
314 * This is our effective network manager, that we end up using. The one the
315 * user sets is userNetworkManager.
317 QPatternist::SequenceType::Ptr m_requiredType;
318 QPatternist::FunctionFactory::Ptr m_functionFactory;
319 QPatternist::NetworkAccessDelegator::Ptr m_networkAccessDelegator;
321 QList<QXmlName> m_additionalNamespaceBindings;