source: trunk/src/xmlpatterns/expr/qelementconstructor.cpp@ 561

Last change on this file since 561 was 561, checked in by Dmitry A. Kuminov, 15 years ago

trunk: Merged in qt 4.6.1 sources.

File size: 6.1 KB
Line 
1/****************************************************************************
2**
3** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
4** All rights reserved.
5** Contact: Nokia Corporation ([email protected])
6**
7** This file is part of the QtXmlPatterns module of the Qt Toolkit.
8**
9** $QT_BEGIN_LICENSE:LGPL$
10** Commercial Usage
11** Licensees holding valid Qt Commercial licenses may use this file in
12** accordance with the Qt Commercial License Agreement provided with the
13** Software or, alternatively, in accordance with the terms contained in
14** a written agreement between you and Nokia.
15**
16** GNU Lesser General Public License Usage
17** Alternatively, this file may be used under the terms of the GNU Lesser
18** General Public License version 2.1 as published by the Free Software
19** Foundation and appearing in the file LICENSE.LGPL included in the
20** packaging of this file. Please review the following information to
21** ensure the GNU Lesser General Public License version 2.1 requirements
22** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
23**
24** In addition, as a special exception, Nokia gives you certain additional
25** rights. These rights are described in the Nokia Qt LGPL Exception
26** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
27**
28** GNU General Public License Usage
29** Alternatively, this file may be used under the terms of the GNU
30** General Public License version 3.0 as published by the Free Software
31** Foundation and appearing in the file LICENSE.GPL included in the
32** packaging of this file. Please review the following information to
33** ensure the GNU General Public License version 3.0 requirements will be
34** met: http://www.gnu.org/copyleft/gpl.html.
35**
36** If you have questions regarding the use of this file, please contact
37** Nokia at [email protected].
38** $QT_END_LICENSE$
39**
40****************************************************************************/
41
42#include "qcommonsequencetypes_p.h"
43#include "qdelegatingnamespaceresolver_p.h"
44#include "qnamespaceconstructor_p.h"
45#include "qnodebuilder_p.h"
46#include "qoutputvalidator_p.h"
47#include "qqnamevalue_p.h"
48#include "qstaticnamespacecontext_p.h"
49
50#include "qelementconstructor_p.h"
51
52QT_BEGIN_NAMESPACE
53
54using namespace QPatternist;
55
56ElementConstructor::ElementConstructor(const Expression::Ptr &op1,
57 const Expression::Ptr &op2,
58 const bool isXSLT) : PairContainer(op1, op2)
59 , m_isXSLT(isXSLT)
60{
61}
62
63Item ElementConstructor::evaluateSingleton(const DynamicContext::Ptr &context) const
64{
65 const Item name(m_operand1->evaluateSingleton(context));
66
67 const NodeBuilder::Ptr nodeBuilder(context->nodeBuilder(m_staticBaseURI));
68 OutputValidator validator(nodeBuilder.data(), context, this, m_isXSLT);
69
70 const DynamicContext::Ptr receiverContext(context->createReceiverContext(&validator));
71
72 nodeBuilder->startElement(name.as<QNameValue>()->qName());
73 m_operand2->evaluateToSequenceReceiver(receiverContext);
74 nodeBuilder->endElement();
75
76 const QAbstractXmlNodeModel::Ptr nm(nodeBuilder->builtDocument());
77 context->addNodeModel(nm);
78
79 return nm->root(QXmlNodeModelIndex());
80}
81
82void ElementConstructor::evaluateToSequenceReceiver(const DynamicContext::Ptr &context) const
83{
84 /* We create an OutputValidator here too. If we're serializing(a common
85 * case, unfortunately) the receiver is already validating in order to
86 * catch cases where a computed attribute constructor is followed by an
87 * element constructor, but in the cases where we're not serializing it's
88 * necessary that we validate in this step. */
89 const Item name(m_operand1->evaluateSingleton(context));
90 QAbstractXmlReceiver *const receiver = context->outputReceiver();
91
92 OutputValidator validator(receiver, context, this, m_isXSLT);
93 const DynamicContext::Ptr receiverContext(context->createReceiverContext(&validator));
94
95 receiver->startElement(name.as<QNameValue>()->qName());
96 m_operand2->evaluateToSequenceReceiver(receiverContext);
97 receiver->endElement();
98}
99
100Expression::Ptr ElementConstructor::typeCheck(const StaticContext::Ptr &context,
101 const SequenceType::Ptr &reqType)
102{
103 /* What does this code do? When type checking our children, our namespace
104 * bindings, which are also children of the form of NamespaceConstructor
105 * instances, must be statically in-scope for them, so find them and
106 * shuffle their bindings into the StaticContext. */
107
108 m_staticBaseURI = context->baseURI();
109
110 /* Namespace declarations changes the in-scope bindings, so let's
111 * first lookup our child NamespaceConstructors. */
112 const ID operandID = m_operand2->id();
113
114 NamespaceResolver::Bindings overrides;
115 if(operandID == IDExpressionSequence)
116 {
117 const Expression::List operands(m_operand2->operands());
118 const int len = operands.count();
119
120 for(int i = 0; i < len; ++i)
121 {
122 if(operands.at(i)->is(IDNamespaceConstructor))
123 {
124 const QXmlName &nb = operands.at(i)->as<NamespaceConstructor>()->namespaceBinding();
125 overrides.insert(nb.prefix(), nb.namespaceURI());
126 }
127 }
128 }
129
130 const NamespaceResolver::Ptr newResolver(new DelegatingNamespaceResolver(context->namespaceBindings(), overrides));
131 const StaticContext::Ptr augmented(new StaticNamespaceContext(newResolver, context));
132
133 return PairContainer::typeCheck(augmented, reqType);
134}
135
136SequenceType::Ptr ElementConstructor::staticType() const
137{
138 return CommonSequenceTypes::ExactlyOneElement;
139}
140
141SequenceType::List ElementConstructor::expectedOperandTypes() const
142{
143 SequenceType::List result;
144 result.append(CommonSequenceTypes::ExactlyOneQName);
145 result.append(CommonSequenceTypes::ZeroOrMoreItems);
146 return result;
147}
148
149Expression::Properties ElementConstructor::properties() const
150{
151 return DisableElimination | IsNodeConstructor;
152}
153
154ExpressionVisitorResult::Ptr
155ElementConstructor::accept(const ExpressionVisitor::Ptr &visitor) const
156{
157 return visitor->visit(this);
158}
159
160QT_END_NAMESPACE
Note: See TracBrowser for help on using the repository browser.