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.
52 #ifndef Patternist_XsdSchemaResolver_H
53 #define Patternist_XsdSchemaResolver_H
55 #include <private/qnamespacesupport_p.h>
56 #include <private/qschematype_p.h>
57 #include <private/qschematypefactory_p.h>
58 #include <private/qxsdalternative_p.h>
59 #include <private/qxsdattribute_p.h>
60 #include <private/qxsdattributegroup_p.h>
61 #include <private/qxsdelement_p.h>
62 #include <private/qxsdmodelgroup_p.h>
63 #include <private/qxsdnotation_p.h>
64 #include <private/qxsdreference_p.h>
65 #include <private/qxsdschema_p.h>
66 #include <private/qxsdschemachecker_p.h>
67 #include <private/qxsdsimpletype_p.h>
69 #include <QtCore/QExplicitlySharedDataPointer>
77 class XsdSchemaContext;
78 class XsdSchemaParserContext;
81 * @short Encapsulates the resolving of type/element references in a schema after parsing has finished.
83 * This class collects task for resolving types or element references. After the parsing has finished,
84 * one can start the resolve process by calling resolve().
86 * @ingroup Patternist_schema
87 * @author Tobias Koenig <tobias.koenig@nokia.com>
89 class XsdSchemaResolver : public QSharedData
92 typedef QExplicitlySharedDataPointer<XsdSchemaResolver> Ptr;
95 * Creates a new schema resolver.
97 * @param context The schema context used for error reporting etc..
98 * @param parserContext The schema parser context where all objects to resolve belong to.
100 XsdSchemaResolver(const QExplicitlySharedDataPointer<XsdSchemaContext> &context, const XsdSchemaParserContext *parserContext);
103 * Destroys the schema resolver.
105 ~XsdSchemaResolver();
108 * Starts the resolve process.
113 * Adds a resolve task for key references.
115 * The resolver will try to set the referencedKey property of @p keyRef to the <em>key</em> or <em>unique</em> object
116 * of @p element that has the given @p name.
118 void addKeyReference(const XsdElement::Ptr &element, const XsdIdentityConstraint::Ptr &keyRef, const QXmlName &name, const QSourceLocation &location);
121 * Adds a resolve task for the base type of restriction of a simple type.
123 * The resolver will set the base type of @p simpleType to the type named by @p baseName.
125 void addSimpleRestrictionBase(const XsdSimpleType::Ptr &simpleType, const QXmlName &baseName, const QSourceLocation &location);
128 * Removes the resolve task for the base type of restriction of the simple @p type.
130 void removeSimpleRestrictionBase(const XsdSimpleType::Ptr &type);
133 * Adds a resolve task for the list type of a simple type.
135 * The resolver will set the itemType property of @p simpleType to the type named by @p typeName.
137 void addSimpleListType(const XsdSimpleType::Ptr &simpleType, const QXmlName &typeName, const QSourceLocation &location);
140 * Adds a resolve task for the member types of a simple type.
142 * The resolver will set the memberTypes property of @p simpleType to the types named by @p typeNames.
144 void addSimpleUnionTypes(const XsdSimpleType::Ptr &simpleType, const QList<QXmlName> &typeNames, const QSourceLocation &location);
147 * Adds a resolve task for the type of an element.
149 * The resolver will set the type of the @p element to the type named by @p typeName.
151 void addElementType(const XsdElement::Ptr &element, const QXmlName &typeName, const QSourceLocation &location);
154 * Adds a resolve task for the base type of a complex type.
156 * The resolver will set the base type of @p complexType to the type named by @p baseName.
158 void addComplexBaseType(const XsdComplexType::Ptr &complexType, const QXmlName &baseName, const QSourceLocation &location, const XsdFacet::Hash &facets = XsdFacet::Hash());
161 * Removes the resolve task for the base type of the complex @p type.
163 void removeComplexBaseType(const XsdComplexType::Ptr &type);
166 * Adds a resolve task for the content type of a complex type.
168 * The resolver will set the content type properties for @p complexType based on the
169 * given explicit @p content and effective @p mixed value.
171 void addComplexContentType(const XsdComplexType::Ptr &complexType, const XsdParticle::Ptr &content, bool mixed);
174 * Adds a resolve task for the type of an attribute.
176 * The resolver will set the type of the @p attribute to the type named by @p typeName.
178 void addAttributeType(const XsdAttribute::Ptr &attribute, const QXmlName &typeName, const QSourceLocation &location);
181 * Adds a resolve task for the type of an alternative.
183 * The resolver will set the type of the @p alternative to the type named by @p typeName.
185 void addAlternativeType(const XsdAlternative::Ptr &alternative, const QXmlName &typeName, const QSourceLocation &location);
188 * Adds a resolve task for the type of an alternative.
190 * The resolver will set the type of the @p alternative to the type of the @p element after
191 * the type of the @p element has been resolved.
193 void addAlternativeType(const XsdAlternative::Ptr &alternative, const XsdElement::Ptr &element);
196 * Adds a resolve task for the substituion group affiliations of an element.
198 * The resolver will set the substitution group affiliations of the @p element to the
199 * top-level element named by @p elementNames.
201 void addSubstitutionGroupAffiliation(const XsdElement::Ptr &element, const QList<QXmlName> &elementName, const QSourceLocation &location);
204 * Adds a resolve task for an element that has no type specified, only a substitution group
207 * The resolver will set the type of the substitution group affiliation as type for the element.
209 void addSubstitutionGroupType(const XsdElement::Ptr &element);
212 * Adds the component location hash, so the resolver is able to report meaning full
215 void addComponentLocationHash(const QHash<NamedSchemaComponent::Ptr, QSourceLocation> &hash);
218 * Add a resolve task for enumeration facet values.
220 * In case the enumeration is of type QName or NOTATION, we have to resolve the QName later,
221 * so we store the namespace bindings together with the facet value here and resolve it as soon as
222 * we have all type information available.
224 void addEnumerationFacetValue(const AtomicValue::Ptr &facetValue, const NamespaceSupport &namespaceSupport);
227 * Add a check job for redefined groups.
229 * When an element group is redefined, we have to check whether the redefined group is a valid
230 * restriction of the group it redefines. As we need all type information for that, we keep them
231 * here for later checking.
233 void addRedefinedGroups(const XsdModelGroup::Ptr &redefinedGroup, const XsdModelGroup::Ptr &group);
236 * Add a check job for redefined attribute groups.
238 * When an attribute group is redefined, we have to check whether the redefined group is a valid
239 * restriction of the group it redefines. As we need all type information for that, we keep them
240 * here for later checking.
242 void addRedefinedAttributeGroups(const XsdAttributeGroup::Ptr &redefinedGroup, const XsdAttributeGroup::Ptr &group);
245 * Adds a check for nested <em>all</em> groups.
247 void addAllGroupCheck(const XsdReference::Ptr &reference);
250 * Copies the data to resolve to an @p other resolver.
252 * @note That functionality is only used by the redefine algorithm in the XsdSchemaParser.
254 void copyDataTo(const XsdSchemaResolver::Ptr &other) const;
257 * Returns the to resolve base type name for the given @p type.
259 * @note That functionality is only used by the redefine algorithm in the XsdSchemaParser.
261 QXmlName baseTypeNameOfType(const SchemaType::Ptr &type) const;
264 * Returns the to resolve type name for the given @p attribute.
266 * @note That functionality is only used by the redefine algorithm in the XsdSchemaParser.
268 QXmlName typeNameOfAttribute(const XsdAttribute::Ptr &attribute) const;
271 * Sets the defaultOpenContent object from the schema parser.
273 void setDefaultOpenContent(const XsdComplexType::OpenContent::Ptr &openContent, bool appliesToEmpty);
277 * Resolves key references.
279 void resolveKeyReferences();
282 * Resolves the base types of simple types derived by restriction.
284 void resolveSimpleRestrictionBaseTypes();
287 * Resolves the other properties except the base type
288 * of all simple restrictions.
290 void resolveSimpleRestrictions();
293 * Resolves the other properties except the base type
294 * of the given simple restriction.
296 * @param simpleType The restricted type to resolve.
297 * @param visitedTypes A set of already resolved types, used for termination of recursion.
299 void resolveSimpleRestrictions(const XsdSimpleType::Ptr &simpleType, QSet<XsdSimpleType::Ptr> &visitedTypes);
302 * Resolves the item type property of simple types derived by list.
304 void resolveSimpleListType();
307 * Resolves the member types property of simple types derived by union.
309 void resolveSimpleUnionTypes();
312 * Resolves element types.
314 void resolveElementTypes();
317 * Resolves base type of complex types.
319 void resolveComplexBaseTypes();
322 * Resolves the simple content model of a complex type
323 * depending on its base type.
325 void resolveSimpleContentComplexTypes();
328 * Resolves the complex content model of a complex type
329 * depending on its base type.
331 void resolveComplexContentComplexTypes();
334 * Resolves the simple content model of a complex type
335 * depending on its base type.
337 * @param complexType The complex type to resolve.
338 * @param visitedTypes A set of already resolved types, used for termination of recursion.
340 void resolveSimpleContentComplexTypes(const XsdComplexType::Ptr &complexType, QSet<XsdComplexType::Ptr> &visitedTypes);
343 * Resolves the complex content model of a complex type
344 * depending on its base type.
346 * @param complexType The complex type to resolve.
347 * @param visitedTypes A set of already resolved types, used for termination of recursion.
349 void resolveComplexContentComplexTypes(const XsdComplexType::Ptr &complexType, QSet<XsdComplexType::Ptr> &visitedTypes);
352 * Resolves attribute types.
354 void resolveAttributeTypes();
357 * Resolves alternative types.
359 void resolveAlternativeTypes();
362 * Resolves substitution group affiliations.
364 void resolveSubstitutionGroupAffiliations();
367 * Resolves substitution groups.
369 void resolveSubstitutionGroups();
372 * Resolves all XsdReferences in the schema by their corresponding XsdElement or XsdModelGroup terms.
374 void resolveTermReferences();
377 * Resolves all XsdReferences in the @p particle recursive by their corresponding XsdElement or XsdModelGroup terms.
379 void resolveTermReference(const XsdParticle::Ptr &particle, QSet<QXmlName> visitedGroups);
382 * Resolves all XsdAttributeReferences in the schema by their corresponding XsdAttributeUse objects.
384 void resolveAttributeTermReferences();
387 * Resolves all XsdAttributeReferences in the list of @p attributeUses by their corresponding XsdAttributeUse objects.
389 XsdAttributeUse::List resolveAttributeTermReferences(const XsdAttributeUse::List &attributeUses, XsdWildcard::Ptr &wildcard, QSet<QXmlName> visitedAttributeGroups);
392 * Resolves the attribute inheritance of complex types.
394 * @note This method must be called after all base types have been resolved.
396 void resolveAttributeInheritance();
399 * Resolves the attribute inheritance of the given complex types.
401 * @param complexType The complex type to resolve.
402 * @param visitedTypes A set of already resolved types, used for termination of recursion.
404 * @note This method must be called after all base types have been resolved.
406 void resolveAttributeInheritance(const XsdComplexType::Ptr &complexType, QSet<XsdComplexType::Ptr> &visitedTypes);
409 * Resolves the enumeration facet values for QName and NOTATION based facets.
411 void resolveEnumerationFacetValues();
414 * Returns the source location of the given schema @p component or a dummy
415 * source location if the component is not found in the component location hash.
417 QSourceLocation sourceLocation(const NamedSchemaComponent::Ptr component) const;
420 * Returns the facets that are marked for the given complex @p type with a simple
423 XsdFacet::Hash complexTypeFacets(const XsdComplexType::Ptr &complexType) const;
426 * Finds the primitive type for the given simple @p type.
428 * The type is found by walking up the inheritance tree, until one of the builtin
429 * primitive type definitions is reached.
431 AnySimpleType::Ptr findPrimitiveType(const AnySimpleType::Ptr &type, QSet<AnySimpleType::Ptr> &visitedTypes);
434 * Checks the redefined groups.
436 void checkRedefinedGroups();
439 * Checks the redefined attribute groups.
441 void checkRedefinedAttributeGroups();
446 XsdElement::Ptr element;
447 XsdIdentityConstraint::Ptr keyRef;
449 QSourceLocation location;
452 class SimpleRestrictionBase
455 XsdSimpleType::Ptr simpleType;
457 QSourceLocation location;
463 XsdSimpleType::Ptr simpleType;
465 QSourceLocation location;
468 class SimpleUnionType
471 XsdSimpleType::Ptr simpleType;
472 QList<QXmlName> typeNames;
473 QSourceLocation location;
479 XsdElement::Ptr element;
481 QSourceLocation location;
484 class ComplexBaseType
487 XsdComplexType::Ptr complexType;
489 QSourceLocation location;
490 XsdFacet::Hash facets;
493 class ComplexContentType
496 XsdComplexType::Ptr complexType;
497 XsdParticle::Ptr explicitContent;
504 XsdAttribute::Ptr attribute;
506 QSourceLocation location;
509 class AlternativeType
512 XsdAlternative::Ptr alternative;
514 QSourceLocation location;
517 class AlternativeTypeElement
520 XsdAlternative::Ptr alternative;
521 XsdElement::Ptr element;
524 class SubstitutionGroupAffiliation
527 XsdElement::Ptr element;
528 QList<QXmlName> elementNames;
529 QSourceLocation location;
532 class RedefinedGroups
535 XsdModelGroup::Ptr redefinedGroup;
536 XsdModelGroup::Ptr group;
539 class RedefinedAttributeGroups
542 XsdAttributeGroup::Ptr redefinedGroup;
543 XsdAttributeGroup::Ptr group;
546 QVector<KeyReference> m_keyReferences;
547 QVector<SimpleRestrictionBase> m_simpleRestrictionBases;
548 QVector<SimpleListType> m_simpleListTypes;
549 QVector<SimpleUnionType> m_simpleUnionTypes;
550 QVector<ElementType> m_elementTypes;
551 QVector<ComplexBaseType> m_complexBaseTypes;
552 QVector<ComplexContentType> m_complexContentTypes;
553 QVector<AttributeType> m_attributeTypes;
554 QVector<AlternativeType> m_alternativeTypes;
555 QVector<AlternativeTypeElement> m_alternativeTypeElements;
556 QVector<SubstitutionGroupAffiliation> m_substitutionGroupAffiliations;
557 QVector<XsdElement::Ptr> m_substitutionGroupTypes;
558 QVector<RedefinedGroups> m_redefinedGroups;
559 QVector<RedefinedAttributeGroups> m_redefinedAttributeGroups;
560 QHash<AtomicValue::Ptr, NamespaceSupport> m_enumerationFacetValues;
561 QSet<XsdReference::Ptr> m_allGroups;
563 QExplicitlySharedDataPointer<XsdSchemaContext> m_context;
564 QExplicitlySharedDataPointer<XsdSchemaChecker> m_checker;
565 NamePool::Ptr m_namePool;
566 XsdSchema::Ptr m_schema;
567 QHash<NamedSchemaComponent::Ptr, QSourceLocation> m_componentLocationHash;
568 XsdComplexType::OpenContent::Ptr m_defaultOpenContent;
569 bool m_defaultOpenContentAppliesToEmpty;
570 SchemaType::List m_predefinedSchemaTypes;