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_XsdSchemaResolver_H 51 #define Patternist_XsdSchemaResolver_H 52 53 #include <private/qnamespacesupport_p.h> 54 #include <private/qschematype_p.h> 55 #include <private/qschematypefactory_p.h> 56 #include <private/qxsdalternative_p.h> 57 #include <private/qxsdattribute_p.h> 58 #include <private/qxsdattributegroup_p.h> 59 #include <private/qxsdelement_p.h> 60 #include <private/qxsdmodelgroup_p.h> 61 #include <private/qxsdnotation_p.h> 62 #include <private/qxsdreference_p.h> 63 #include <private/qxsdschema_p.h> 64 #include <private/qxsdschemachecker_p.h> 65 #include <private/qxsdsimpletype_p.h> 66 67 #include <QtCore/QExplicitlySharedDataPointer> 68 69 QT_BEGIN_NAMESPACE 70 71 namespace QPatternist 72 { 73 class XsdSchemaContext; 74 class XsdSchemaParserContext; 75 76 /** 77 * @short Encapsulates the resolving of type/element references in a schema after parsing has finished. 78 * 79 * This class collects task for resolving types or element references. After the parsing has finished, 80 * one can start the resolve process by calling resolve(). 81 * 82 * @ingroup Patternist_schema 83 * @author Tobias Koenig <tobias.koenig@nokia.com> 84 */ 85 class XsdSchemaResolver : public QSharedData 86 { 87 public: 88 typedef QExplicitlySharedDataPointer<XsdSchemaResolver> Ptr; 89 90 /** 91 * Creates a new schema resolver. 92 * 93 * @param context The schema context used for error reporting etc.. 94 * @param parserContext The schema parser context where all objects to resolve belong to. 95 */ 96 XsdSchemaResolver(const QExplicitlySharedDataPointer<XsdSchemaContext> &context, const XsdSchemaParserContext *parserContext); 97 98 /** 99 * Destroys the schema resolver. 100 */ 101 ~XsdSchemaResolver(); 102 103 /** 104 * Starts the resolve process. 105 */ 106 void resolve(); 107 108 /** 109 * Adds a resolve task for key references. 110 * 111 * The resolver will try to set the referencedKey property of @p keyRef to the <em>key</em> or <em>unique</em> object 112 * of @p element that has the given @p name. 113 */ 114 void addKeyReference(const XsdElement::Ptr &element, const XsdIdentityConstraint::Ptr &keyRef, const QXmlName &name, const QSourceLocation &location); 115 116 /** 117 * Adds a resolve task for the base type of restriction of a simple type. 118 * 119 * The resolver will set the base type of @p simpleType to the type named by @p baseName. 120 */ 121 void addSimpleRestrictionBase(const XsdSimpleType::Ptr &simpleType, const QXmlName &baseName, const QSourceLocation &location); 122 123 /** 124 * Removes the resolve task for the base type of restriction of the simple @p type. 125 */ 126 void removeSimpleRestrictionBase(const XsdSimpleType::Ptr &type); 127 128 /** 129 * Adds a resolve task for the list type of a simple type. 130 * 131 * The resolver will set the itemType property of @p simpleType to the type named by @p typeName. 132 */ 133 void addSimpleListType(const XsdSimpleType::Ptr &simpleType, const QXmlName &typeName, const QSourceLocation &location); 134 135 /** 136 * Adds a resolve task for the member types of a simple type. 137 * 138 * The resolver will set the memberTypes property of @p simpleType to the types named by @p typeNames. 139 */ 140 void addSimpleUnionTypes(const XsdSimpleType::Ptr &simpleType, const QList<QXmlName> &typeNames, const QSourceLocation &location); 141 142 /** 143 * Adds a resolve task for the type of an element. 144 * 145 * The resolver will set the type of the @p element to the type named by @p typeName. 146 */ 147 void addElementType(const XsdElement::Ptr &element, const QXmlName &typeName, const QSourceLocation &location); 148 149 /** 150 * Adds a resolve task for the base type of a complex type. 151 * 152 * The resolver will set the base type of @p complexType to the type named by @p baseName. 153 */ 154 void addComplexBaseType(const XsdComplexType::Ptr &complexType, const QXmlName &baseName, const QSourceLocation &location, const XsdFacet::Hash &facets = XsdFacet::Hash()); 155 156 /** 157 * Removes the resolve task for the base type of the complex @p type. 158 */ 159 void removeComplexBaseType(const XsdComplexType::Ptr &type); 160 161 /** 162 * Adds a resolve task for the content type of a complex type. 163 * 164 * The resolver will set the content type properties for @p complexType based on the 165 * given explicit @p content and effective @p mixed value. 166 */ 167 void addComplexContentType(const XsdComplexType::Ptr &complexType, const XsdParticle::Ptr &content, bool mixed); 168 169 /** 170 * Adds a resolve task for the type of an attribute. 171 * 172 * The resolver will set the type of the @p attribute to the type named by @p typeName. 173 */ 174 void addAttributeType(const XsdAttribute::Ptr &attribute, const QXmlName &typeName, const QSourceLocation &location); 175 176 /** 177 * Adds a resolve task for the type of an alternative. 178 * 179 * The resolver will set the type of the @p alternative to the type named by @p typeName. 180 */ 181 void addAlternativeType(const XsdAlternative::Ptr &alternative, const QXmlName &typeName, const QSourceLocation &location); 182 183 /** 184 * Adds a resolve task for the type of an alternative. 185 * 186 * The resolver will set the type of the @p alternative to the type of the @p element after 187 * the type of the @p element has been resolved. 188 */ 189 void addAlternativeType(const XsdAlternative::Ptr &alternative, const XsdElement::Ptr &element); 190 191 /** 192 * Adds a resolve task for the substituion group affiliations of an element. 193 * 194 * The resolver will set the substitution group affiliations of the @p element to the 195 * top-level element named by @p elementNames. 196 */ 197 void addSubstitutionGroupAffiliation(const XsdElement::Ptr &element, const QList<QXmlName> &elementName, const QSourceLocation &location); 198 199 /** 200 * Adds a resolve task for an element that has no type specified, only a substitution group 201 * affiliation. 202 * 203 * The resolver will set the type of the substitution group affiliation as type for the element. 204 */ 205 void addSubstitutionGroupType(const XsdElement::Ptr &element); 206 207 /** 208 * Adds the component location hash, so the resolver is able to report meaning full 209 * error messages. 210 */ 211 void addComponentLocationHash(const QHash<NamedSchemaComponent::Ptr, QSourceLocation> &hash); 212 213 /** 214 * Add a resolve task for enumeration facet values. 215 * 216 * In case the enumeration is of type QName or NOTATION, we have to resolve the QName later, 217 * so we store the namespace bindings together with the facet value here and resolve it as soon as 218 * we have all type information available. 219 */ 220 void addEnumerationFacetValue(const AtomicValue::Ptr &facetValue, const NamespaceSupport &namespaceSupport); 221 222 /** 223 * Add a check job for redefined groups. 224 * 225 * When an element group is redefined, we have to check whether the redefined group is a valid 226 * restriction of the group it redefines. As we need all type information for that, we keep them 227 * here for later checking. 228 */ 229 void addRedefinedGroups(const XsdModelGroup::Ptr &redefinedGroup, const XsdModelGroup::Ptr &group); 230 231 /** 232 * Add a check job for redefined attribute groups. 233 * 234 * When an attribute group is redefined, we have to check whether the redefined group is a valid 235 * restriction of the group it redefines. As we need all type information for that, we keep them 236 * here for later checking. 237 */ 238 void addRedefinedAttributeGroups(const XsdAttributeGroup::Ptr &redefinedGroup, const XsdAttributeGroup::Ptr &group); 239 240 /** 241 * Adds a check for nested <em>all</em> groups. 242 */ 243 void addAllGroupCheck(const XsdReference::Ptr &reference); 244 245 /** 246 * Copies the data to resolve to an @p other resolver. 247 * 248 * @note That functionality is only used by the redefine algorithm in the XsdSchemaParser. 249 */ 250 void copyDataTo(const XsdSchemaResolver::Ptr &other) const; 251 252 /** 253 * Returns the to resolve base type name for the given @p type. 254 * 255 * @note That functionality is only used by the redefine algorithm in the XsdSchemaParser. 256 */ 257 QXmlName baseTypeNameOfType(const SchemaType::Ptr &type) const; 258 259 /** 260 * Returns the to resolve type name for the given @p attribute. 261 * 262 * @note That functionality is only used by the redefine algorithm in the XsdSchemaParser. 263 */ 264 QXmlName typeNameOfAttribute(const XsdAttribute::Ptr &attribute) const; 265 266 /** 267 * Sets the defaultOpenContent object from the schema parser. 268 */ 269 void setDefaultOpenContent(const XsdComplexType::OpenContent::Ptr &openContent, bool appliesToEmpty); 270 271 private: 272 /** 273 * Resolves key references. 274 */ 275 void resolveKeyReferences(); 276 277 /** 278 * Resolves the base types of simple types derived by restriction. 279 */ 280 void resolveSimpleRestrictionBaseTypes(); 281 282 /** 283 * Resolves the other properties except the base type 284 * of all simple restrictions. 285 */ 286 void resolveSimpleRestrictions(); 287 288 /** 289 * Resolves the other properties except the base type 290 * of the given simple restriction. 291 * 292 * @param simpleType The restricted type to resolve. 293 * @param visitedTypes A set of already resolved types, used for termination of recursion. 294 */ 295 void resolveSimpleRestrictions(const XsdSimpleType::Ptr &simpleType, QSet<XsdSimpleType::Ptr> &visitedTypes); 296 297 /** 298 * Resolves the item type property of simple types derived by list. 299 */ 300 void resolveSimpleListType(); 301 302 /** 303 * Resolves the member types property of simple types derived by union. 304 */ 305 void resolveSimpleUnionTypes(); 306 307 /** 308 * Resolves element types. 309 */ 310 void resolveElementTypes(); 311 312 /** 313 * Resolves base type of complex types. 314 */ 315 void resolveComplexBaseTypes(); 316 317 /** 318 * Resolves the simple content model of a complex type 319 * depending on its base type. 320 */ 321 void resolveSimpleContentComplexTypes(); 322 323 /** 324 * Resolves the complex content model of a complex type 325 * depending on its base type. 326 */ 327 void resolveComplexContentComplexTypes(); 328 329 /** 330 * Resolves the simple content model of a complex type 331 * depending on its base type. 332 * 333 * @param complexType The complex type to resolve. 334 * @param visitedTypes A set of already resolved types, used for termination of recursion. 335 */ 336 void resolveSimpleContentComplexTypes(const XsdComplexType::Ptr &complexType, QSet<XsdComplexType::Ptr> &visitedTypes); 337 338 /** 339 * Resolves the complex content model of a complex type 340 * depending on its base type. 341 * 342 * @param complexType The complex type to resolve. 343 * @param visitedTypes A set of already resolved types, used for termination of recursion. 344 */ 345 void resolveComplexContentComplexTypes(const XsdComplexType::Ptr &complexType, QSet<XsdComplexType::Ptr> &visitedTypes); 346 347 /** 348 * Resolves attribute types. 349 */ 350 void resolveAttributeTypes(); 351 352 /** 353 * Resolves alternative types. 354 */ 355 void resolveAlternativeTypes(); 356 357 /** 358 * Resolves substitution group affiliations. 359 */ 360 void resolveSubstitutionGroupAffiliations(); 361 362 /** 363 * Resolves substitution groups. 364 */ 365 void resolveSubstitutionGroups(); 366 367 /** 368 * Resolves all XsdReferences in the schema by their corresponding XsdElement or XsdModelGroup terms. 369 */ 370 void resolveTermReferences(); 371 372 /** 373 * Resolves all XsdReferences in the @p particle recursive by their corresponding XsdElement or XsdModelGroup terms. 374 */ 375 void resolveTermReference(const XsdParticle::Ptr &particle, QSet<QXmlName> visitedGroups); 376 377 /** 378 * Resolves all XsdAttributeReferences in the schema by their corresponding XsdAttributeUse objects. 379 */ 380 void resolveAttributeTermReferences(); 381 382 /** 383 * Resolves all XsdAttributeReferences in the list of @p attributeUses by their corresponding XsdAttributeUse objects. 384 */ 385 XsdAttributeUse::List resolveAttributeTermReferences(const XsdAttributeUse::List &attributeUses, XsdWildcard::Ptr &wildcard, QSet<QXmlName> visitedAttributeGroups); 386 387 /** 388 * Resolves the attribute inheritance of complex types. 389 * 390 * @note This method must be called after all base types have been resolved. 391 */ 392 void resolveAttributeInheritance(); 393 394 /** 395 * Resolves the attribute inheritance of the given complex types. 396 * 397 * @param complexType The complex type to resolve. 398 * @param visitedTypes A set of already resolved types, used for termination of recursion. 399 * 400 * @note This method must be called after all base types have been resolved. 401 */ 402 void resolveAttributeInheritance(const XsdComplexType::Ptr &complexType, QSet<XsdComplexType::Ptr> &visitedTypes); 403 404 /** 405 * Resolves the enumeration facet values for QName and NOTATION based facets. 406 */ 407 void resolveEnumerationFacetValues(); 408 409 /** 410 * Returns the source location of the given schema @p component or a dummy 411 * source location if the component is not found in the component location hash. 412 */ 413 QSourceLocation sourceLocation(const NamedSchemaComponent::Ptr component) const; 414 415 /** 416 * Returns the facets that are marked for the given complex @p type with a simple 417 * type restriction. 418 */ 419 XsdFacet::Hash complexTypeFacets(const XsdComplexType::Ptr &complexType) const; 420 421 /** 422 * Finds the primitive type for the given simple @p type. 423 * 424 * The type is found by walking up the inheritance tree, until one of the builtin 425 * primitive type definitions is reached. 426 */ 427 AnySimpleType::Ptr findPrimitiveType(const AnySimpleType::Ptr &type, QSet<AnySimpleType::Ptr> &visitedTypes); 428 429 /** 430 * Checks the redefined groups. 431 */ 432 void checkRedefinedGroups(); 433 434 /** 435 * Checks the redefined attribute groups. 436 */ 437 void checkRedefinedAttributeGroups(); 438 439 class KeyReference 440 { 441 public: 442 XsdElement::Ptr element; 443 XsdIdentityConstraint::Ptr keyRef; 444 QXmlName reference; 445 QSourceLocation location; 446 }; 447 448 class SimpleRestrictionBase 449 { 450 public: 451 XsdSimpleType::Ptr simpleType; 452 QXmlName baseName; 453 QSourceLocation location; 454 }; 455 456 class SimpleListType 457 { 458 public: 459 XsdSimpleType::Ptr simpleType; 460 QXmlName typeName; 461 QSourceLocation location; 462 }; 463 464 class SimpleUnionType 465 { 466 public: 467 XsdSimpleType::Ptr simpleType; 468 QList<QXmlName> typeNames; 469 QSourceLocation location; 470 }; 471 472 class ElementType 473 { 474 public: 475 XsdElement::Ptr element; 476 QXmlName typeName; 477 QSourceLocation location; 478 }; 479 480 class ComplexBaseType 481 { 482 public: 483 XsdComplexType::Ptr complexType; 484 QXmlName baseName; 485 QSourceLocation location; 486 XsdFacet::Hash facets; 487 }; 488 489 class ComplexContentType 490 { 491 public: 492 XsdComplexType::Ptr complexType; 493 XsdParticle::Ptr explicitContent; 494 bool effectiveMixed; 495 }; 496 497 class AttributeType 498 { 499 public: 500 XsdAttribute::Ptr attribute; 501 QXmlName typeName; 502 QSourceLocation location; 503 }; 504 505 class AlternativeType 506 { 507 public: 508 XsdAlternative::Ptr alternative; 509 QXmlName typeName; 510 QSourceLocation location; 511 }; 512 513 class AlternativeTypeElement 514 { 515 public: 516 XsdAlternative::Ptr alternative; 517 XsdElement::Ptr element; 518 }; 519 520 class SubstitutionGroupAffiliation 521 { 522 public: 523 XsdElement::Ptr element; 524 QList<QXmlName> elementNames; 525 QSourceLocation location; 526 }; 527 528 class RedefinedGroups 529 { 530 public: 531 XsdModelGroup::Ptr redefinedGroup; 532 XsdModelGroup::Ptr group; 533 }; 534 535 class RedefinedAttributeGroups 536 { 537 public: 538 XsdAttributeGroup::Ptr redefinedGroup; 539 XsdAttributeGroup::Ptr group; 540 }; 541 542 QVector<KeyReference> m_keyReferences; 543 QVector<SimpleRestrictionBase> m_simpleRestrictionBases; 544 QVector<SimpleListType> m_simpleListTypes; 545 QVector<SimpleUnionType> m_simpleUnionTypes; 546 QVector<ElementType> m_elementTypes; 547 QVector<ComplexBaseType> m_complexBaseTypes; 548 QVector<ComplexContentType> m_complexContentTypes; 549 QVector<AttributeType> m_attributeTypes; 550 QVector<AlternativeType> m_alternativeTypes; 551 QVector<AlternativeTypeElement> m_alternativeTypeElements; 552 QVector<SubstitutionGroupAffiliation> m_substitutionGroupAffiliations; 553 QVector<XsdElement::Ptr> m_substitutionGroupTypes; 554 QVector<RedefinedGroups> m_redefinedGroups; 555 QVector<RedefinedAttributeGroups> m_redefinedAttributeGroups; 556 QHash<AtomicValue::Ptr, NamespaceSupport> m_enumerationFacetValues; 557 QSet<XsdReference::Ptr> m_allGroups; 558 559 QExplicitlySharedDataPointer<XsdSchemaContext> m_context; 560 QExplicitlySharedDataPointer<XsdSchemaChecker> m_checker; 561 NamePool::Ptr m_namePool; 562 XsdSchema::Ptr m_schema; 563 QHash<NamedSchemaComponent::Ptr, QSourceLocation> m_componentLocationHash; 564 XsdComplexType::OpenContent::Ptr m_defaultOpenContent; 565 bool m_defaultOpenContentAppliesToEmpty; 566 SchemaType::List m_predefinedSchemaTypes; 567 }; 568 } 569 570 QT_END_NAMESPACE 571 572 #endif 573