1 /****************************************************************************
2 **
3 ** Copyright (C) 2015 The Qt Company Ltd.
4 ** Contact: http://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 http://www.qt.io/terms-conditions. For further
15 ** information use the contact form at http://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 2.1 or version 3 as published by the Free
20 ** Software Foundation and appearing in the file LICENSE.LGPLv21 and
21 ** LICENSE.LGPLv3 included in the packaging of this file. Please review the
22 ** following information to ensure the GNU Lesser General Public License
23 ** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
24 ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
25 **
26 ** As a special exception, The Qt Company gives you certain additional
27 ** rights. These rights are described in The Qt Company LGPL Exception
28 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
29 **
30 ** GNU General Public License Usage
31 ** Alternatively, this file may be used under the terms of the GNU
32 ** General Public License version 3.0 as published by the Free Software
33 ** Foundation and appearing in the file LICENSE.GPL included in the
34 ** packaging of this file.  Please review the following information to
35 ** ensure the GNU General Public License version 3.0 requirements will be
36 ** met: http://www.gnu.org/copyleft/gpl.html.
37 **
38 ** $QT_END_LICENSE$
39 **
40 ****************************************************************************/
41 
42 //
43 //  W A R N I N G
44 //  -------------
45 //
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.
49 //
50 // We mean it.
51 
52 #ifndef Patternist_XsdSchemaChecker_H
53 #define Patternist_XsdSchemaChecker_H
54 
55 #include "qschematype_p.h"
56 #include "qxsdattribute_p.h"
57 #include "qxsdattributegroup_p.h"
58 #include "qxsdelement_p.h"
59 #include "qxsdmodelgroup_p.h"
60 #include "qxsdnotation_p.h"
61 #include "qxsdschema_p.h"
62 #include "qxsdsimpletype_p.h"
63 
64 #include <QtCore/QExplicitlySharedDataPointer>
65 
66 QT_BEGIN_HEADER
67 
68 QT_BEGIN_NAMESPACE
69 
70 namespace QPatternist
71 {
72     class XsdSchemaContext;
73     class XsdSchemaParserContext;
74 
75     /**
76      * @short Encapsulates the checking of schema valitity after reference resolving has finished.
77      *
78      * @ingroup Patternist_schema
79      * @author Tobias Koenig <tobias.koenig@nokia.com>
80      */
81     class XsdSchemaChecker : public QSharedData
82     {
83         public:
84             typedef QExplicitlySharedDataPointer<XsdSchemaChecker> Ptr;
85 
86             /**
87              * Creates a new schema checker.
88              *
89              * @param context The context that is used for customization.
90              * @param parserContext The context that contains all the data structures.
91              */
92             XsdSchemaChecker(const QExplicitlySharedDataPointer<XsdSchemaContext> &context, const XsdSchemaParserContext *parserContext);
93 
94             /**
95              * Destroys the schema checker.
96              */
97             ~XsdSchemaChecker();
98 
99             /**
100              * Starts a basic check process.
101              *
102              * This check only validates the basic super type inheritance
103              * of simple and complex types.
104              */
105             void basicCheck();
106 
107             /**
108              * Starts the real check process.
109              */
110             void check();
111 
112             /**
113              * Checks the constraining facets of all global and anonymous simple types for validity.
114              */
115             void checkConstrainingFacets();
116 
117             /**
118              * Adds the component location hash, so the checker is able to report meaning full
119              * error messages.
120              */
121             void addComponentLocationHash(const QHash<NamedSchemaComponent::Ptr, QSourceLocation> &hash);
122 
123         private:
124             void checkSimpleRestrictionBaseType();
125 
126             /**
127              * Checks that no simple or complex type inherits itself.
128              */
129             void checkBasicCircularInheritances();
130 
131             /**
132              * Checks the advanced circular inheritance.
133              */
134             void checkCircularInheritances();
135 
136             /**
137              * Checks for inheritance restrictions given by final or finalDefault
138              * attributes.
139              */
140             void checkInheritanceRestrictions();
141 
142             /**
143              * Checks for various constraints for simple types defined by schema.
144              */
145             void checkBasicSimpleTypeConstraints();
146             void checkSimpleTypeConstraints();
147 
148             /**
149              * Checks for various constraints for complex types defined by schema.
150              */
151             void checkBasicComplexTypeConstraints();
152             void checkComplexTypeConstraints();
153 
154             /**
155              * Checks for list and union derivation restrictions given by final or finalDefault
156              * attributes.
157              */
158             void checkSimpleDerivationRestrictions();
159 
160             /**
161              * Checks the set of constraining @p facets that belongs to @p simpleType for validity.
162              */
163             void checkConstrainingFacets(const XsdFacet::Hash &facets, const XsdSimpleType::Ptr &simpleType);
164 
165             /**
166              * Checks for duplicated attribute uses (attributes with the same name) inside a complex type.
167              */
168             void checkDuplicatedAttributeUses();
169 
170             /**
171              * Check the element constraints.
172              */
173             void checkElementConstraints();
174 
175             /**
176              * Check the attribute constraints.
177              */
178             void checkAttributeConstraints();
179 
180             /**
181              * Check the attribute use constraints.
182              */
183             void checkAttributeUseConstraints();
184 
185             /**
186              * A map used to find duplicated elements inside a model group.
187              */
188             typedef QHash<QXmlName, SchemaType::Ptr> DuplicatedElementMap;
189 
190             /**
191              * A map used to find duplicated wildcards inside a model group.
192              */
193             typedef QHash<XsdWildcard::NamespaceConstraint::Variety, XsdWildcard::Ptr> DuplicatedWildcardMap;
194 
195             /**
196              * Check for duplicated elements and element wildcards in all complex type particles.
197              */
198             void checkElementDuplicates();
199 
200             /**
201              * Check for duplicated elements and element wildcards in the given @p particle.
202              *
203              * @param particle The particle to check.
204              * @param elementMap A map to find the duplicated elements.
205              * @param wildcardMap A map to find the duplicated element wildcards.
206              */
207             void checkElementDuplicates(const XsdParticle::Ptr &particle, DuplicatedElementMap &elementMap, DuplicatedWildcardMap &wildcardMap);
208 
209             /**
210              * Setup fast lookup list for allowed facets of atomic simple types.
211              */
212             void setupAllowedAtomicFacets();
213 
214             /**
215              * Returns the source location of the given schema @p component or a dummy
216              * source location if the component is not found in the component location hash.
217              */
218             QSourceLocation sourceLocation(const NamedSchemaComponent::Ptr &component) const;
219 
220             /**
221              * Returns the source location of the given schema @p type or a dummy
222              * source location if the type is not found in the component location hash.
223              */
224             QSourceLocation sourceLocationForType(const SchemaType::Ptr &type) const;
225 
226             /**
227              * Checks that the string @p value is valid according the value space of @p type
228              * for the given @p component.
229              */
230             bool isValidValue(const QString &value, const AnySimpleType::Ptr &type, QString &errorMsg) const;
231 
232             /**
233              * Returns the list of facets for the given @p type.
234              */
235             XsdFacet::Hash facetsForType(const SchemaType::Ptr &type) const;
236 
237             /**
238              * Returns whether the given @p list of attribute uses contains two (or more) attribute
239              * uses that point to attributes with the same name. @p conflictingAttribute
240              * will contain the conflicting attribute in that case.
241              */
242             bool hasDuplicatedAttributeUses(const XsdAttributeUse::List &list, XsdAttribute::Ptr &conflictingAttribute) const;
243 
244             /**
245              * Returns whether the given @p list of attribute uses contains two (or more) attribute
246              * uses that have a type inherited by xs:ID.
247              */
248             bool hasMultipleIDAttributeUses(const XsdAttributeUse::List &list) const;
249 
250             /**
251              * Returns whether the given @p list of attribute uses contains an attribute
252              * uses that has a type inherited by xs:ID with a value constraint. @p conflictingAttribute
253              * will contain the conflicting attribute in that case.
254              */
255             bool hasConstraintIDAttributeUse(const XsdAttributeUse::List &list, XsdAttribute::Ptr &conflictingAttribute) const;
256 
257             /**
258              * Checks whether the @p particle equals the @p otherParticle recursively.
259              */
260             bool particleEqualsRecursively(const XsdParticle::Ptr &particle, const XsdParticle::Ptr &otherParticle) const;
261 
262             /**
263              * Checks whether the @p extension particle is a valid extension of the @p base particle.
264              */
265             bool isValidParticleExtension(const XsdParticle::Ptr &extension, const XsdParticle::Ptr &base) const;
266 
267             /**
268              * Checks whether the @p sequence of elements is accepted by the given @p particle.
269              */
270             bool elementSequenceAccepted(const XsdModelGroup::Ptr &sequence, const XsdParticle::Ptr &particle) const;
271 
272             QExplicitlySharedDataPointer<XsdSchemaContext>       m_context;
273             NamePool::Ptr                                        m_namePool;
274             XsdSchema::Ptr                                       m_schema;
275             QHash<QXmlName, QSet<XsdFacet::Type> >               m_allowedAtomicFacets;
276             QHash<NamedSchemaComponent::Ptr, QSourceLocation>    m_componentLocationHash;
277     };
278 }
279 
280 QT_END_NAMESPACE
281 
282 QT_END_HEADER
283 
284 #endif
285