1 | /**************************************************************************** |
2 | ** |
3 | ** Copyright (C) 2016 The Qt Company Ltd. |
4 | ** Contact: https://www.qt.io/licensing/ |
5 | ** |
6 | ** This file is part of the QtXmlPatterns module of the Qt Toolkit. |
7 | ** |
8 | ** $QT_BEGIN_LICENSE:LGPL$ |
9 | ** Commercial License Usage |
10 | ** Licensees holding valid commercial Qt licenses may use this file in |
11 | ** accordance with the commercial license agreement provided with the |
12 | ** Software or, alternatively, in accordance with the terms contained in |
13 | ** a written agreement between you and The Qt Company. For licensing terms |
14 | ** and conditions see https://www.qt.io/terms-conditions. For further |
15 | ** information use the contact form at https://www.qt.io/contact-us. |
16 | ** |
17 | ** GNU Lesser General Public License Usage |
18 | ** Alternatively, this file may be used under the terms of the GNU Lesser |
19 | ** General Public License version 3 as published by the Free Software |
20 | ** Foundation and appearing in the file LICENSE.LGPL3 included in the |
21 | ** packaging of this file. Please review the following information to |
22 | ** ensure the GNU Lesser General Public License version 3 requirements |
23 | ** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. |
24 | ** |
25 | ** GNU General Public License Usage |
26 | ** Alternatively, this file may be used under the terms of the GNU |
27 | ** General Public License version 2.0 or (at your option) the GNU General |
28 | ** Public license version 3 or any later version approved by the KDE Free |
29 | ** Qt Foundation. The licenses are as published by the Free Software |
30 | ** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 |
31 | ** included in the packaging of this file. Please review the following |
32 | ** information to ensure the GNU General Public License requirements will |
33 | ** be met: https://www.gnu.org/licenses/gpl-2.0.html and |
34 | ** https://www.gnu.org/licenses/gpl-3.0.html. |
35 | ** |
36 | ** $QT_END_LICENSE$ |
37 | ** |
38 | ****************************************************************************/ |
39 | |
40 | // |
41 | // W A R N I N G |
42 | // ------------- |
43 | // |
44 | // This file is not part of the Qt API. It exists purely as an |
45 | // implementation detail. This header file may change from version to |
46 | // version without notice, or even be removed. |
47 | // |
48 | // We mean it. |
49 | |
50 | #ifndef Patternist_MaintainingReader_H |
51 | #define Patternist_MaintainingReader_H |
52 | |
53 | #include <QSet> |
54 | #include <QSourceLocation> |
55 | #include <QStack> |
56 | #include <QStringList> |
57 | #include <QXmlStreamReader> |
58 | |
59 | #include <private/qxpathhelper_p.h> |
60 | #include <private/qxslttokenlookup_p.h> |
61 | |
62 | QT_BEGIN_NAMESPACE |
63 | |
64 | class QUrl; |
65 | |
66 | namespace QPatternist |
67 | { |
68 | /** |
69 | * @short A structure that lists the optional and required |
70 | * attributes of an element. Used with MaintainingReader. |
71 | * |
72 | * A constant source to misunderstandings is mixing up the order of |
73 | * arguments for functions that takes a local name and a namespace. Be wary |
74 | * of this. |
75 | * |
76 | * @author Frans Englich <frans.englich@nokia.com> |
77 | * @since 4.5 |
78 | */ |
79 | template<typename TokenLookupClass, |
80 | typename LookupKey = typename TokenLookupClass::NodeName> |
81 | class ElementDescription |
82 | { |
83 | public: |
84 | typedef QHash<LookupKey, ElementDescription<TokenLookupClass, LookupKey> > Hash; |
85 | QSet<typename TokenLookupClass::NodeName> requiredAttributes; |
86 | QSet<typename TokenLookupClass::NodeName> optionalAttributes; |
87 | }; |
88 | |
89 | /** |
90 | * @short Base class for tokenizers that reads XML formats. This is |
91 | * XSLTTokenizer, and the W3C XML Schema parser. |
92 | * |
93 | * MaintainingReader is intended for sub-classing. |
94 | * |
95 | * @tparam TokenLookupClass The name of the class that is generated by |
96 | * QTokenAutomaton and which supplies tokenizing tokens. For XSLTTokenizer, |
97 | * this is XSLTTokenLookup, for instance. |
98 | * |
99 | * @tparam LookupKey The type that is passed to validateElement() and is |
100 | * the key in ElementDescription. For the schema code, where elements have |
101 | * different interpretations depending on context, the lookup key is hence |
102 | * not equal element name. |
103 | * |
104 | * @author Frans Englich <frans.englich@nokia.com> |
105 | * @since 4.5 |
106 | */ |
107 | template<typename TokenLookupClass, |
108 | typename LookupKey = typename TokenLookupClass::NodeName> |
109 | class MaintainingReader : public QXmlStreamReader |
110 | , protected TokenLookupClass |
111 | { |
112 | protected: |
113 | |
114 | MaintainingReader(const typename ElementDescription<TokenLookupClass, LookupKey>::Hash &elementDescriptions, |
115 | const QSet<typename TokenLookupClass::NodeName> &standardAttributes, |
116 | const ReportContext::Ptr &context, |
117 | QIODevice *const queryDevice); |
118 | |
119 | virtual ~MaintainingReader(); |
120 | |
121 | TokenType readNext(); |
122 | |
123 | /** |
124 | * Returns the name of the current element. |
125 | */ |
126 | inline typename TokenLookupClass::NodeName currentElementName() const; |
127 | |
128 | /** |
129 | * @short Convenience function for calling ReportContext::error(). |
130 | */ |
131 | void error(const QString &message, |
132 | const ReportContext::ErrorCode code) const; |
133 | |
134 | /** |
135 | * @short Convenience function for calling ReportContext::warning(). |
136 | */ |
137 | void warning(const QString &message) const; |
138 | |
139 | /** |
140 | * @short Returns the location of the document that MaintainingReader |
141 | * is parsing. Used for error reporting |
142 | */ |
143 | virtual QUrl documentURI() const = 0; |
144 | |
145 | /** |
146 | * @short Returns @c true, if any attribute is allowed on the |
147 | * element currently being validated. |
148 | */ |
149 | virtual bool isAnyAttributeAllowed() const = 0; |
150 | |
151 | /** |
152 | * QXmlStreamReader::isWhitespace() returns true for whitespace that is |
153 | * not expressed as character references, while XSL-T operatates ontop |
154 | * of the XDM, which means we needs to return true for those too. |
155 | * |
156 | * @see <a href="http://www.w3.org/TR/xslt20/#data-model">4 Data Model</a> |
157 | */ |
158 | bool isWhitespace() const; |
159 | |
160 | /** |
161 | * This function is not merged with handleStandardAttributes() because |
162 | * handleStandardAttributes() needs to be called for all elements, |
163 | * while validateElement() only applies to XSL-T elements. |
164 | * |
165 | * @see handleStandardAttributes() |
166 | */ |
167 | void validateElement(const LookupKey name) const; |
168 | |
169 | QXmlStreamAttributes m_currentAttributes; |
170 | |
171 | bool m_hasHandledStandardAttributes; |
172 | |
173 | /** |
174 | * This stack mirrors the depth of elements in the parsed document. If |
175 | * no @c xml:space is present on the current element, MaintainingReader |
176 | * simply pushes the current top(). However, it never sets the value |
177 | * depending on @c xml:space's value. |
178 | */ |
179 | QStack<bool> m_stripWhitespace; |
180 | |
181 | /** |
182 | * @short Returns the value for attribute by name \a name. |
183 | * |
184 | * If it doesn't exist, an error is raised. |
185 | * |
186 | * It is assumed that m_reader's current state is |
187 | * QXmlStreamReader::StartElement. |
188 | */ |
189 | QString readAttribute(const QString &localName, |
190 | const QString &namespaceURI = QString()) const; |
191 | |
192 | /** |
193 | * @short Returns @c true if the current element has an attribute whose |
194 | * name is @p namespaceURI and local name is @p localName. |
195 | */ |
196 | bool hasAttribute(const QString &namespaceURI, const QString &localName) const; |
197 | |
198 | /** |
199 | * @short Returns @c true if the current element has an attribute whose |
200 | * local name is @p localName and namespace URI is null. |
201 | */ |
202 | inline bool hasAttribute(const QString &localName) const; |
203 | |
204 | private: |
205 | typename TokenLookupClass::NodeName m_currentElementName; |
206 | |
207 | /** |
208 | * This member is private, see the error() and warning() functions in |
209 | * this class. |
210 | */ |
211 | const ReportContext::Ptr m_context; |
212 | |
213 | /** |
214 | * Returns the current location that QXmlStreamReader has. |
215 | */ |
216 | inline QSourceLocation currentLocation() const; |
217 | |
218 | const typename ElementDescription<TokenLookupClass, LookupKey>::Hash m_elementDescriptions; |
219 | const QSet<typename TokenLookupClass::NodeName> m_standardAttributes; |
220 | Q_DISABLE_COPY(MaintainingReader) |
221 | }; |
222 | |
223 | #include "qmaintainingreader_tpl_p.h" |
224 | |
225 | } |
226 | |
227 | QT_END_NAMESPACE |
228 | |
229 | #endif |
230 | |
231 | |