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