/**************************************************************************** ** ** Copyright (C) 2016 The Qt Company Ltd. ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the QtXmlPatterns module of the Qt Toolkit. ** ** $QT_BEGIN_LICENSE:LGPL$ ** Commercial License Usage ** Licensees holding valid commercial Qt licenses may use this file in ** accordance with the commercial license agreement provided with the ** Software or, alternatively, in accordance with the terms contained in ** a written agreement between you and The Qt Company. For licensing terms ** and conditions see https://www.qt.io/terms-conditions. For further ** information use the contact form at https://www.qt.io/contact-us. ** ** GNU Lesser General Public License Usage ** Alternatively, this file may be used under the terms of the GNU Lesser ** General Public License version 3 as published by the Free Software ** Foundation and appearing in the file LICENSE.LGPL3 included in the ** packaging of this file. Please review the following information to ** ensure the GNU Lesser General Public License version 3 requirements ** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. ** ** GNU General Public License Usage ** Alternatively, this file may be used under the terms of the GNU ** General Public License version 2.0 or (at your option) the GNU General ** Public license version 3 or any later version approved by the KDE Free ** Qt Foundation. The licenses are as published by the Free Software ** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 ** included in the packaging of this file. Please review the following ** information to ensure the GNU General Public License requirements will ** be met: https://www.gnu.org/licenses/gpl-2.0.html and ** https://www.gnu.org/licenses/gpl-3.0.html. ** ** $QT_END_LICENSE$ ** ****************************************************************************/ // // W A R N I N G // ------------- // // This file is not part of the Qt API. It exists purely as an // implementation detail. This header file may change from version to // version without notice, or even be removed. // // We mean it. #ifndef Patternist_XsdSchemaParser_H #define Patternist_XsdSchemaParser_H #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include QT_BEGIN_NAMESPACE namespace QPatternist { /** * @short Implements the parsing of XML schema file. * * This class parses a XML schema in XML presentation from an QIODevice * and returns object representation as XsdSchema. * * @ingroup Patternist_schema * @author Tobias Koenig */ class XsdSchemaParser : public MaintainingReader { friend class ElementNamespaceHandler; friend class TagValidationHandler; public: enum ParserType { TopLevelParser, IncludeParser, ImportParser, RedefineParser }; /** * Creates a new schema parser object. */ XsdSchemaParser(const XsdSchemaContext::Ptr &context, const XsdSchemaParserContext::Ptr &parserContext, QIODevice *device); /** * Parses the XML schema file. * * @return @c true on success, @c false if the schema is somehow invalid. */ bool parse(ParserType parserType = TopLevelParser); /** * Describes a set of namespace URIs */ typedef QSet NamespaceSet; /** * Adds @p schemas to the list of already included schemas, so the parser * can detect multiple includes of the same schema. */ void addIncludedSchemas(const NamespaceSet &schemas); /** * Sets which @p schemas have been included already, so the parser * can detect multiple includes of the same schema. */ void setIncludedSchemas(const NamespaceSet &schemas); /** * Adds @p schemas to the list of already imported schemas, so the parser * can detect multiple imports of the same schema. */ void addImportedSchemas(const NamespaceSet &schemas); /** * Sets which @p schemas have been imported already, so the parser * can detect circular imports. */ void setImportedSchemas(const NamespaceSet &schemas); /** * Adds @p schemas to the list of already redefined schemas, so the parser * can detect multiple redefines of the same schema. */ void addRedefinedSchemas(const NamespaceSet &schemas); /** * Sets which @p schemas have been redefined already, so the parser * can detect multiple redefines of the same schema. */ void setRedefinedSchemas(const NamespaceSet &schemas); /** * Sets the target namespace of the schema to parse. */ void setTargetNamespace(const QString &targetNamespace); /** * Sets the document URI of the schema to parse. */ void setDocumentURI(const QUrl &uri); /** * Returns the document URI of the schema to parse. */ QUrl documentURI() const; /** * Reimplemented from MaintainingReader, always returns @c false. */ bool isAnyAttributeAllowed() const; private: /** * Used internally to report any kind of parsing error or * schema inconsistency. */ virtual void error(const QString &msg); void attributeContentError(const char *attributeName, const char *elementName, const QString &value, const SchemaType::Ptr &type = SchemaType::Ptr()); /** * Sets the target namespace of the schema to parse. */ void setTargetNamespaceExtended(const QString &targetNamespace); /** * This method is called for parsing the top-level schema object. */ void parseSchema(ParserType parserType); /** * This method is called for parsing any top-level include object. */ void parseInclude(); /** * This method is called for parsing any top-level import object. */ void parseImport(); /** * This method is called for parsing any top-level redefine object. */ void parseRedefine(); /** * This method is called for parsing any annotation object everywhere * in the schema. */ XsdAnnotation::Ptr parseAnnotation(); /** * This method is called for parsing an appinfo object as child of * an annotation object. */ XsdApplicationInformation::Ptr parseAppInfo(); /** * This method is called for parsing a documentation object as child of * an annotation object. */ XsdDocumentation::Ptr parseDocumentation(); /** * This method is called for parsing a defaultOpenContent object. */ void parseDefaultOpenContent(); /** * This method is called for parsing any top-level simpleType object. */ XsdSimpleType::Ptr parseGlobalSimpleType(); /** * This method is called for parsing any simpleType object as descendant * of an element or complexType object. */ XsdSimpleType::Ptr parseLocalSimpleType(); /** * This method is called for parsing a restriction object as child * of a simpleType object. */ void parseSimpleRestriction(const XsdSimpleType::Ptr &ptr); /** * This method is called for parsing a list object as child * of a simpleType object. */ void parseList(const XsdSimpleType::Ptr &ptr); /** * This method is called for parsing a union object as child * of a simpleType object. */ void parseUnion(const XsdSimpleType::Ptr &ptr); /** * This method is called for parsing a minExclusive object as child * of a restriction object. */ XsdFacet::Ptr parseMinExclusiveFacet(); /** * This method is called for parsing a minInclusive object as child * of a restriction object. */ XsdFacet::Ptr parseMinInclusiveFacet(); /** * This method is called for parsing a maxExclusive object as child * of a restriction object. */ XsdFacet::Ptr parseMaxExclusiveFacet(); /** * This method is called for parsing a maxInclusive object as child * of a restriction object. */ XsdFacet::Ptr parseMaxInclusiveFacet(); /** * This method is called for parsing a totalDigits object as child * of a restriction object. */ XsdFacet::Ptr parseTotalDigitsFacet(); /** * This method is called for parsing a fractionDigits object as child * of a restriction object. */ XsdFacet::Ptr parseFractionDigitsFacet(); /** * This method is called for parsing a length object as child * of a restriction object. */ XsdFacet::Ptr parseLengthFacet(); /** * This method is called for parsing a minLength object as child * of a restriction object. */ XsdFacet::Ptr parseMinLengthFacet(); /** * This method is called for parsing a maxLength object as child * of a restriction object. */ XsdFacet::Ptr parseMaxLengthFacet(); /** * This method is called for parsing an enumeration object as child * of a restriction object. */ XsdFacet::Ptr parseEnumerationFacet(); /** * This method is called for parsing a whiteSpace object as child * of a restriction object. */ XsdFacet::Ptr parseWhiteSpaceFacet(); /** * This method is called for parsing a pattern object as child * of a restriction object. */ XsdFacet::Ptr parsePatternFacet(); /** * This method is called for parsing an assertion object as child * of a restriction object. */ XsdFacet::Ptr parseAssertionFacet(); /** * This method is called for parsing any top-level complexType object. */ XsdComplexType::Ptr parseGlobalComplexType(); /** * This method is called for parsing any complexType object as descendant * of an element object. */ XsdComplexType::Ptr parseLocalComplexType(); /** * This method resolves the content type of the @p complexType for the given * @p effectiveMixed value. */ void resolveComplexContentType(const XsdComplexType::Ptr &complexType, bool effectiveMixed); /** * This method is called for parsing a simpleContent object as child * of a complexType object. */ void parseSimpleContent(const XsdComplexType::Ptr &complexType); /** * This method is called for parsing a restriction object as child * of a simpleContent object. */ void parseSimpleContentRestriction(const XsdComplexType::Ptr &complexType); /** * This method is called for parsing an extension object as child * of a simpleContent object. */ void parseSimpleContentExtension(const XsdComplexType::Ptr &complexType); /** * This method is called for parsing a complexContent object as child * of a complexType object. * * @param complexType The complex type the complex content belongs to. * @param mixed The output parameter for the mixed value. */ void parseComplexContent(const XsdComplexType::Ptr &complexType, bool *mixed); /** * This method is called for parsing a restriction object as child * of a complexContent object. */ void parseComplexContentRestriction(const XsdComplexType::Ptr &complexType); /** * This method is called for parsing an extension object as child * of a complexContent object. */ void parseComplexContentExtension(const XsdComplexType::Ptr &complexType); /** * This method is called for parsing an assert object as child * of a complexType or parsing a assertion facet object as * child of a simpleType. * * @param nodeName Either XsdSchemaToken::Assert or XsdSchemaToken::Assertion. * @param tag Either XsdTagScope::Assert or XsdTagScope::Assertion. */ XsdAssertion::Ptr parseAssertion(const XsdSchemaToken::NodeName &nodeName, const XsdTagScope::Type &tag); /** * This method is called for parsing an openContent object. */ XsdComplexType::OpenContent::Ptr parseOpenContent(); /** * This method is called for parsing a top-level group object. */ XsdModelGroup::Ptr parseNamedGroup(); /** * This method is called for parsing a non-top-level group object * that contains a ref attribute. */ XsdTerm::Ptr parseReferredGroup(const XsdParticle::Ptr &particle); /** * This method is called for parsing an all object as child * of a top-level group object. * * @param parent The schema component the all object is part of. */ XsdModelGroup::Ptr parseAll(const NamedSchemaComponent::Ptr &parent); /** * This method is called for parsing an all object as descendant * of a complexType object. * * @param particle The particle the all object belongs to. * @param parent The schema component the all object is part of. */ XsdModelGroup::Ptr parseLocalAll(const XsdParticle::Ptr &particle, const NamedSchemaComponent::Ptr &parent); /** * This method is called for parsing a choice object as child * of a top-level group object. * * @param parent The schema component the choice object is part of. */ XsdModelGroup::Ptr parseChoice(const NamedSchemaComponent::Ptr &parent); /** * This method is called for parsing a choice object as descendant * of a complexType object or a choice object. * * @param particle The particle the choice object belongs to. * @param parent The schema component the choice object is part of. */ XsdModelGroup::Ptr parseLocalChoice(const XsdParticle::Ptr &particle, const NamedSchemaComponent::Ptr &parent); /** * This method is called for parsing a sequence object as child * of a top-level group object. * * @param parent The schema component the sequence object is part of. */ XsdModelGroup::Ptr parseSequence(const NamedSchemaComponent::Ptr &parent); /** * This method is called for parsing a sequence object as descendant * of a complexType object or a sequence object. * * @param particle The particle the sequence object belongs to. * @param parent The schema component the sequence object is part of. */ XsdModelGroup::Ptr parseLocalSequence(const XsdParticle::Ptr &particle, const NamedSchemaComponent::Ptr &parent); /** * A helper method that parses the minOccurs and maxOccurs constraints for * the given @p particle that has the given @p tagName. */ bool parseMinMaxConstraint(const XsdParticle::Ptr &particle, const char* tagName); /** * This method is called for parsing any top-level attribute object. */ XsdAttribute::Ptr parseGlobalAttribute(); /** * This method is called for parsing any non-top-level attribute object as a * descendant of a complexType object or an attributeGroup object. * * @param parent The parent component the attribute object is part of. */ XsdAttributeUse::Ptr parseLocalAttribute(const NamedSchemaComponent::Ptr &parent); /** * This method is called for parsing a top-level attributeGroup object. */ XsdAttributeGroup::Ptr parseNamedAttributeGroup(); /** * This method is called for parsing a non-top-level attributeGroup object * that contains a ref attribute. */ XsdAttributeUse::Ptr parseReferredAttributeGroup(); /** * This method is called for parsing any top-level element object. */ XsdElement::Ptr parseGlobalElement(); /** * This method is called for parsing any non-top-level element object as a * descendant of a complexType object or a group object. * * @param particle The particle the element object belongs to. * @param parent The parent component the element object is part of. */ XsdTerm::Ptr parseLocalElement(const XsdParticle::Ptr &particle, const NamedSchemaComponent::Ptr &parent); /** * This method is called for parsing a unique object as child of an element object. */ XsdIdentityConstraint::Ptr parseUnique(); /** * This method is called for parsing a key object as child of an element object. */ XsdIdentityConstraint::Ptr parseKey(); /** * This method is called for parsing a keyref object as child of an element object. */ XsdIdentityConstraint::Ptr parseKeyRef(const XsdElement::Ptr &element); /** * This method is called for parsing a selector object as child of an unique object, * key object or keyref object, * * @param ptr The identity constraint it belongs to. */ void parseSelector(const XsdIdentityConstraint::Ptr &ptr); /** * This method is called for parsing a field object as child of an unique object, * key object or keyref object, * * @param ptr The identity constraint it belongs to. */ void parseField(const XsdIdentityConstraint::Ptr &ptr); /** * This method is called for parsing an alternative object inside an element object. */ XsdAlternative::Ptr parseAlternative(); /** * This method is called for parsing a top-level notation object. */ XsdNotation::Ptr parseNotation(); /** * This method is called for parsing an any object somewhere in * the schema. * * @param particle The particle the any object belongs to. */ XsdWildcard::Ptr parseAny(const XsdParticle::Ptr &particle); /** * This method is called for parsing an anyAttribute object somewhere in * the schema. */ XsdWildcard::Ptr parseAnyAttribute(); /** * This method is called for parsing unknown object as descendant of the annotation object. */ void parseUnknownDocumentation(); /** * This method is called for parsing unknown object in the schema. */ void parseUnknown(); /** * Returnes an source location for the current position. */ QSourceLocation currentSourceLocation() const; /** * Converts a @p qualified name into a QXmlName @p name and does some error handling. */ void convertName(const QString &qualified, NamespaceSupport::NameType type, QXmlName &name); /** * A helper method that reads in a 'name' attribute and checks it for syntactic errors. */ inline QString readNameAttribute(const char *elementName); /** * A helper method that reads in an attribute that contains an QName and * checks it for syntactic errors. */ inline QString readQNameAttribute(const QString &typeAttribute, const char *elementName); /** * A helper method that reads in a namespace attribute and checks for syntactic errors. */ inline QString readNamespaceAttribute(const QString &attributeName, const char *elementName); /** * A helper method that reads the final attribute and does correct handling of schema default definitions. */ inline SchemaType::DerivationConstraints readDerivationConstraintAttribute(const SchemaType::DerivationConstraints &allowedConstraints, const char *elementName); /** * A helper method that reads the block attribute and does correct handling of schema default definitions. */ inline NamedSchemaComponent::BlockingConstraints readBlockingConstraintAttribute(const NamedSchemaComponent::BlockingConstraints &allowedConstraints, const char *elementName); /** * A helper method that reads all components for a xpath expression for the current scope. */ XsdXPathExpression::Ptr readXPathExpression(const char *elementName); /** * Describes the type of XPath that is allowed by the readXPathAttribute method. */ enum XPathType { XPath20, XPathSelector, XPathField }; /** * A helper method that reads an attribute that represents a xpath query and does basic * validation. */ QString readXPathAttribute(const QString &attributeName, XPathType type, const char *elementName); /** * A helper method that reads in an "id" attribute, checks it for syntactic errors * and tests whether a component with the same id has already been parsed. */ inline void validateIdAttribute(const char *elementName); /** * Adds an @p element to the schema and checks for duplicated entries. */ void addElement(const XsdElement::Ptr &element); /** * Adds an @p attribute to the schema and checks for duplicated entries. */ void addAttribute(const XsdAttribute::Ptr &attribute); /** * Adds a @p type to the schema and checks for duplicated entries. */ void addType(const SchemaType::Ptr &type); /** * Adds an anonymous @p type to the schema and checks for duplicated entries. */ void addAnonymousType(const SchemaType::Ptr &type); /** * Adds an attribute @p group to the schema and checks for duplicated entries. */ void addAttributeGroup(const XsdAttributeGroup::Ptr &group); /** * Adds an element @p group to the schema and checks for duplicated entries. */ void addElementGroup(const XsdModelGroup::Ptr &group); /** * Adds a @p notation to the schema and checks for duplicated entries. */ void addNotation(const XsdNotation::Ptr ¬ation); /** * Adds an identity @p constraint to the schema and checks for duplicated entries. */ void addIdentityConstraint(const XsdIdentityConstraint::Ptr &constraint); /** * Adds the @p facet to the list of @p facets for @p type and checks for duplicates. */ void addFacet(const XsdFacet::Ptr &facet, XsdFacet::Hash &facets, const SchemaType::Ptr &type); /** * Sets up the state machines for validating the right occurrence of xml elements. */ void setupStateMachines(); /** * Sets up a list of names of known builtin types. */ void setupBuiltinTypeNames(); /** * Checks whether the given @p tag is equal to the given @p token and * the given @p namespaceToken is the XML Schema namespace. */ inline bool isSchemaTag(XsdSchemaToken::NodeName tag, XsdSchemaToken::NodeName token, XsdSchemaToken::NodeName namespaceToken) const; XsdSchemaContext::Ptr m_context; XsdSchemaParserContext::Ptr m_parserContext; NamePool::Ptr m_namePool; NamespaceSupport m_namespaceSupport; XsdSchemaResolver::Ptr m_schemaResolver; XsdSchema::Ptr m_schema; QString m_targetNamespace; QString m_attributeFormDefault; QString m_elementFormDefault; QString m_blockDefault; QString m_finalDefault; QString m_xpathDefaultNamespace; QXmlName m_defaultAttributes; XsdComplexType::OpenContent::Ptr m_defaultOpenContent; bool m_defaultOpenContentAppliesToEmpty; NamespaceSet m_includedSchemas; NamespaceSet m_importedSchemas; NamespaceSet m_redefinedSchemas; QUrl m_documentURI; XsdIdCache::Ptr m_idCache; QHash > m_stateMachines; ComponentLocationHash m_componentLocationHash; QSet m_builtinTypeNames; }; } QT_END_NAMESPACE #endif