From 210bd7b6033e41aad61fe131002dc5e496d7427a Mon Sep 17 00:00:00 2001 From: Tobias Koenig Date: Sat, 16 May 2009 12:15:40 +0200 Subject: Extended QRegExp by a W3C XML Schema mode --- src/corelib/tools/qregexp.cpp | 330 +++++++++++++++++++++++++++++++++++++++++- src/corelib/tools/qregexp.h | 2 +- 2 files changed, 329 insertions(+), 3 deletions(-) diff --git a/src/corelib/tools/qregexp.cpp b/src/corelib/tools/qregexp.cpp index e1c3921..f69a99f 100644 --- a/src/corelib/tools/qregexp.cpp +++ b/src/corelib/tools/qregexp.cpp @@ -70,6 +70,8 @@ int qFindString(const QChar *haystack, int haystackLen, int from, #define RXERR_LEFTDELIM QT_TRANSLATE_NOOP("QRegExp", "missing left delim") #define RXERR_END QT_TRANSLATE_NOOP("QRegExp", "unexpected end") #define RXERR_LIMIT QT_TRANSLATE_NOOP("QRegExp", "met internal limit") +#define RXERR_INTERVAL QT_TRANSLATE_NOOP("QRegExp", "invalid interval") +#define RXERR_CATEGORY QT_TRANSLATE_NOOP("QRegExp", "invalid category") /* WARNING! Be sure to read qregexp.tex before modifying this file. @@ -1116,6 +1118,7 @@ private: bool valid; // is the regular expression valid? Qt::CaseSensitivity cs; // case sensitive? bool greedyQuantifiers; // RegExp2? + bool xmlSchemaExtensions; #ifndef QT_NO_REGEXP_BACKREF int nbrefs; // number of back-references #endif @@ -1193,6 +1196,8 @@ private: friend class Box; + void setupCategoriesRangeMap(); + /* This is the lexical analyzer for regular expressions. */ @@ -1232,6 +1237,7 @@ private: int yyTok; // the last token read bool yyMayCapture; // set this to false to disable capturing + QHash > categoriesRangeMap; // fast lookup hash for xml schema extensions friend struct QRegExpMatchState; }; @@ -1253,7 +1259,8 @@ struct QRegExpLookahead #endif QRegExpEngine::QRegExpEngine(const QRegExpEngineKey &key) - : cs(key.cs), greedyQuantifiers(key.patternSyntax == QRegExp::RegExp2) + : cs(key.cs), greedyQuantifiers(key.patternSyntax == QRegExp::RegExp2), + xmlSchemaExtensions(false) { setup(); @@ -1268,6 +1275,8 @@ QRegExpEngine::QRegExpEngine(const QRegExpEngineKey &key) case QRegExp::FixedString: rx = QRegExp::escape(key.pattern); break; + case QRegExp::W3CXmlSchema11: + xmlSchemaExtensions = true; default: rx = key.pattern; } @@ -2621,6 +2630,152 @@ void QRegExpEngine::Box::addAnchorsToEngine(const Box &to) const } } +void QRegExpEngine::setupCategoriesRangeMap() +{ + categoriesRangeMap.insert("IsBasicLatin", qMakePair(0x0000, 0x007F)); + categoriesRangeMap.insert("IsLatin-1Supplement", qMakePair(0x0080, 0x00FF)); + categoriesRangeMap.insert("IsLatinExtended-A", qMakePair(0x0100, 0x017F)); + categoriesRangeMap.insert("IsLatinExtended-B", qMakePair(0x0180, 0x024F)); + categoriesRangeMap.insert("IsIPAExtensions", qMakePair(0x0250, 0x02AF)); + categoriesRangeMap.insert("IsSpacingModifierLetters", qMakePair(0x02B0, 0x02FF)); + categoriesRangeMap.insert("IsCombiningDiacriticalMarks", qMakePair(0x0300, 0x036F)); + categoriesRangeMap.insert("IsGreek", qMakePair(0x0370, 0x03FF)); + categoriesRangeMap.insert("IsCyrillic", qMakePair(0x0400, 0x04FF)); + categoriesRangeMap.insert("IsCyrillicSupplement", qMakePair(0x0500, 0x052F)); + categoriesRangeMap.insert("IsArmenian", qMakePair(0x0530, 0x058F)); + categoriesRangeMap.insert("IsHebrew", qMakePair(0x0590, 0x05FF)); + categoriesRangeMap.insert("IsArabic", qMakePair(0x0600, 0x06FF)); + categoriesRangeMap.insert("IsSyriac", qMakePair(0x0700, 0x074F)); + categoriesRangeMap.insert("IsArabicSupplement", qMakePair(0x0750, 0x077F)); + categoriesRangeMap.insert("IsThaana", qMakePair(0x0780, 0x07BF)); + categoriesRangeMap.insert("IsDevanagari", qMakePair(0x0900, 0x097F)); + categoriesRangeMap.insert("IsBengali", qMakePair(0x0980, 0x09FF)); + categoriesRangeMap.insert("IsGurmukhi", qMakePair(0x0A00, 0x0A7F)); + categoriesRangeMap.insert("IsGujarati", qMakePair(0x0A80, 0x0AFF)); + categoriesRangeMap.insert("IsOriya", qMakePair(0x0B00, 0x0B7F)); + categoriesRangeMap.insert("IsTamil", qMakePair(0x0B80, 0x0BFF)); + categoriesRangeMap.insert("IsTelugu", qMakePair(0x0C00, 0x0C7F)); + categoriesRangeMap.insert("IsKannada", qMakePair(0x0C80, 0x0CFF)); + categoriesRangeMap.insert("IsMalayalam", qMakePair(0x0D00, 0x0D7F)); + categoriesRangeMap.insert("IsSinhala", qMakePair(0x0D80, 0x0DFF)); + categoriesRangeMap.insert("IsThai", qMakePair(0x0E00, 0x0E7F)); + categoriesRangeMap.insert("IsLao", qMakePair(0x0E80, 0x0EFF)); + categoriesRangeMap.insert("IsTibetan", qMakePair(0x0F00, 0x0FFF)); + categoriesRangeMap.insert("IsMyanmar", qMakePair(0x1000, 0x109F)); + categoriesRangeMap.insert("IsGeorgian", qMakePair(0x10A0, 0x10FF)); + categoriesRangeMap.insert("IsHangulJamo", qMakePair(0x1100, 0x11FF)); + categoriesRangeMap.insert("IsEthiopic", qMakePair(0x1200, 0x137F)); + categoriesRangeMap.insert("IsEthiopicSupplement", qMakePair(0x1380, 0x139F)); + categoriesRangeMap.insert("IsCherokee", qMakePair(0x13A0, 0x13FF)); + categoriesRangeMap.insert("IsUnifiedCanadianAboriginalSyllabics", qMakePair(0x1400, 0x167F)); + categoriesRangeMap.insert("IsOgham", qMakePair(0x1680, 0x169F)); + categoriesRangeMap.insert("IsRunic", qMakePair(0x16A0, 0x16FF)); + categoriesRangeMap.insert("IsTagalog", qMakePair(0x1700, 0x171F)); + categoriesRangeMap.insert("IsHanunoo", qMakePair(0x1720, 0x173F)); + categoriesRangeMap.insert("IsBuhid", qMakePair(0x1740, 0x175F)); + categoriesRangeMap.insert("IsTagbanwa", qMakePair(0x1760, 0x177F)); + categoriesRangeMap.insert("IsKhmer", qMakePair(0x1780, 0x17FF)); + categoriesRangeMap.insert("IsMongolian", qMakePair(0x1800, 0x18AF)); + categoriesRangeMap.insert("IsLimbu", qMakePair(0x1900, 0x194F)); + categoriesRangeMap.insert("IsTaiLe", qMakePair(0x1950, 0x197F)); + categoriesRangeMap.insert("IsNewTaiLue", qMakePair(0x1980, 0x19DF)); + categoriesRangeMap.insert("IsKhmerSymbols", qMakePair(0x19E0, 0x19FF)); + categoriesRangeMap.insert("IsBuginese", qMakePair(0x1A00, 0x1A1F)); + categoriesRangeMap.insert("IsPhoneticExtensions", qMakePair(0x1D00, 0x1D7F)); + categoriesRangeMap.insert("IsPhoneticExtensionsSupplement", qMakePair(0x1D80, 0x1DBF)); + categoriesRangeMap.insert("IsCombiningDiacriticalMarksSupplement", qMakePair(0x1DC0, 0x1DFF)); + categoriesRangeMap.insert("IsLatinExtendedAdditional", qMakePair(0x1E00, 0x1EFF)); + categoriesRangeMap.insert("IsGreekExtended", qMakePair(0x1F00, 0x1FFF)); + categoriesRangeMap.insert("IsGeneralPunctuation", qMakePair(0x2000, 0x206F)); + categoriesRangeMap.insert("IsSuperscriptsandSubscripts", qMakePair(0x2070, 0x209F)); + categoriesRangeMap.insert("IsCurrencySymbols", qMakePair(0x20A0, 0x20CF)); + categoriesRangeMap.insert("IsCombiningMarksforSymbols", qMakePair(0x20D0, 0x20FF)); + categoriesRangeMap.insert("IsLetterlikeSymbols", qMakePair(0x2100, 0x214F)); + categoriesRangeMap.insert("IsNumberForms", qMakePair(0x2150, 0x218F)); + categoriesRangeMap.insert("IsArrows", qMakePair(0x2190, 0x21FF)); + categoriesRangeMap.insert("IsMathematicalOperators", qMakePair(0x2200, 0x22FF)); + categoriesRangeMap.insert("IsMiscellaneousTechnical", qMakePair(0x2300, 0x23FF)); + categoriesRangeMap.insert("IsControlPictures", qMakePair(0x2400, 0x243F)); + categoriesRangeMap.insert("IsOpticalCharacterRecognition", qMakePair(0x2440, 0x245F)); + categoriesRangeMap.insert("IsEnclosedAlphanumerics", qMakePair(0x2460, 0x24FF)); + categoriesRangeMap.insert("IsBoxDrawing", qMakePair(0x2500, 0x257F)); + categoriesRangeMap.insert("IsBlockElements", qMakePair(0x2580, 0x259F)); + categoriesRangeMap.insert("IsGeometricShapes", qMakePair(0x25A0, 0x25FF)); + categoriesRangeMap.insert("IsMiscellaneousSymbols", qMakePair(0x2600, 0x26FF)); + categoriesRangeMap.insert("IsDingbats", qMakePair(0x2700, 0x27BF)); + categoriesRangeMap.insert("IsMiscellaneousMathematicalSymbols-A", qMakePair(0x27C0, 0x27EF)); + categoriesRangeMap.insert("IsSupplementalArrows-A", qMakePair(0x27F0, 0x27FF)); + categoriesRangeMap.insert("IsBraillePatterns", qMakePair(0x2800, 0x28FF)); + categoriesRangeMap.insert("IsSupplementalArrows-B", qMakePair(0x2900, 0x297F)); + categoriesRangeMap.insert("IsMiscellaneousMathematicalSymbols-B", qMakePair(0x2980, 0x29FF)); + categoriesRangeMap.insert("IsSupplementalMathematicalOperators", qMakePair(0x2A00, 0x2AFF)); + categoriesRangeMap.insert("IsMiscellaneousSymbolsandArrows", qMakePair(0x2B00, 0x2BFF)); + categoriesRangeMap.insert("IsGlagolitic", qMakePair(0x2C00, 0x2C5F)); + categoriesRangeMap.insert("IsCoptic", qMakePair(0x2C80, 0x2CFF)); + categoriesRangeMap.insert("IsGeorgianSupplement", qMakePair(0x2D00, 0x2D2F)); + categoriesRangeMap.insert("IsTifinagh", qMakePair(0x2D30, 0x2D7F)); + categoriesRangeMap.insert("IsEthiopicExtended", qMakePair(0x2D80, 0x2DDF)); + categoriesRangeMap.insert("IsSupplementalPunctuation", qMakePair(0x2E00, 0x2E7F)); + categoriesRangeMap.insert("IsCJKRadicalsSupplement", qMakePair(0x2E80, 0x2EFF)); + categoriesRangeMap.insert("IsKangxiRadicals", qMakePair(0x2F00, 0x2FDF)); + categoriesRangeMap.insert("IsIdeographicDescriptionCharacters", qMakePair(0x2FF0, 0x2FFF)); + categoriesRangeMap.insert("IsCJKSymbolsandPunctuation", qMakePair(0x3000, 0x303F)); + categoriesRangeMap.insert("IsHiragana", qMakePair(0x3040, 0x309F)); + categoriesRangeMap.insert("IsKatakana", qMakePair(0x30A0, 0x30FF)); + categoriesRangeMap.insert("IsBopomofo", qMakePair(0x3100, 0x312F)); + categoriesRangeMap.insert("IsHangulCompatibilityJamo", qMakePair(0x3130, 0x318F)); + categoriesRangeMap.insert("IsKanbun", qMakePair(0x3190, 0x319F)); + categoriesRangeMap.insert("IsBopomofoExtended", qMakePair(0x31A0, 0x31BF)); + categoriesRangeMap.insert("IsCJKStrokes", qMakePair(0x31C0, 0x31EF)); + categoriesRangeMap.insert("IsKatakanaPhoneticExtensions", qMakePair(0x31F0, 0x31FF)); + categoriesRangeMap.insert("IsEnclosedCJKLettersandMonths", qMakePair(0x3200, 0x32FF)); + categoriesRangeMap.insert("IsCJKCompatibility", qMakePair(0x3300, 0x33FF)); + categoriesRangeMap.insert("IsCJKUnifiedIdeographsExtensionA", qMakePair(0x3400, 0x4DB5)); + categoriesRangeMap.insert("IsYijingHexagramSymbols", qMakePair(0x4DC0, 0x4DFF)); + categoriesRangeMap.insert("IsCJKUnifiedIdeographs", qMakePair(0x4E00, 0x9FFF)); + categoriesRangeMap.insert("IsYiSyllables", qMakePair(0xA000, 0xA48F)); + categoriesRangeMap.insert("IsYiRadicals", qMakePair(0xA490, 0xA4CF)); + categoriesRangeMap.insert("IsModifierToneLetters", qMakePair(0xA700, 0xA71F)); + categoriesRangeMap.insert("IsSylotiNagri", qMakePair(0xA800, 0xA82F)); + categoriesRangeMap.insert("IsHangulSyllables", qMakePair(0xAC00, 0xD7A3)); + categoriesRangeMap.insert("IsPrivateUse", qMakePair(0xE000, 0xF8FF)); + categoriesRangeMap.insert("IsCJKCompatibilityIdeographs", qMakePair(0xF900, 0xFAFF)); + categoriesRangeMap.insert("IsAlphabeticPresentationForms", qMakePair(0xFB00, 0xFB4F)); + categoriesRangeMap.insert("IsArabicPresentationForms-A", qMakePair(0xFB50, 0xFDFF)); + categoriesRangeMap.insert("IsVariationSelectors", qMakePair(0xFE00, 0xFE0F)); + categoriesRangeMap.insert("IsVerticalForms", qMakePair(0xFE10, 0xFE1F)); + categoriesRangeMap.insert("IsCombiningHalfMarks", qMakePair(0xFE20, 0xFE2F)); + categoriesRangeMap.insert("IsCJKCompatibilityForms", qMakePair(0xFE30, 0xFE4F)); + categoriesRangeMap.insert("IsSmallFormVariants", qMakePair(0xFE50, 0xFE6F)); + categoriesRangeMap.insert("IsArabicPresentationForms-B", qMakePair(0xFE70, 0xFEFF)); + categoriesRangeMap.insert("IsHalfwidthandFullwidthForms", qMakePair(0xFF00, 0xFFEF)); + categoriesRangeMap.insert("IsSpecials", qMakePair(0xFFF0, 0xFFFF)); + categoriesRangeMap.insert("IsLinearBSyllabary", qMakePair(0x10000, 0x1007F)); + categoriesRangeMap.insert("IsLinearBIdeograms", qMakePair(0x10080, 0x100FF)); + categoriesRangeMap.insert("IsAegeanNumbers", qMakePair(0x10100, 0x1013F)); + categoriesRangeMap.insert("IsAncientGreekNumbers", qMakePair(0x10140, 0x1018F)); + categoriesRangeMap.insert("IsOldItalic", qMakePair(0x10300, 0x1032F)); + categoriesRangeMap.insert("IsGothic", qMakePair(0x10330, 0x1034F)); + categoriesRangeMap.insert("IsUgaritic", qMakePair(0x10380, 0x1039F)); + categoriesRangeMap.insert("IsOldPersian", qMakePair(0x103A0, 0x103DF)); + categoriesRangeMap.insert("IsDeseret", qMakePair(0x10400, 0x1044F)); + categoriesRangeMap.insert("IsShavian", qMakePair(0x10450, 0x1047F)); + categoriesRangeMap.insert("IsOsmanya", qMakePair(0x10480, 0x104AF)); + categoriesRangeMap.insert("IsCypriotSyllabary", qMakePair(0x10800, 0x1083F)); + categoriesRangeMap.insert("IsKharoshthi", qMakePair(0x10A00, 0x10A5F)); + categoriesRangeMap.insert("IsByzantineMusicalSymbols", qMakePair(0x1D000, 0x1D0FF)); + categoriesRangeMap.insert("IsMusicalSymbols", qMakePair(0x1D100, 0x1D1FF)); + categoriesRangeMap.insert("IsAncientGreekMusicalNotation", qMakePair(0x1D200, 0x1D24F)); + categoriesRangeMap.insert("IsTaiXuanJingSymbols", qMakePair(0x1D300, 0x1D35F)); + categoriesRangeMap.insert("IsMathematicalAlphanumericSymbols", qMakePair(0x1D400, 0x1D7FF)); + categoriesRangeMap.insert("IsCJKUnifiedIdeographsExtensionB", qMakePair(0x20000, 0x2A6DF)); + categoriesRangeMap.insert("IsCJKCompatibilityIdeographsSupplement", qMakePair(0x2F800, 0x2FA1F)); + categoriesRangeMap.insert("IsTags", qMakePair(0xE0000, 0xE007F)); + categoriesRangeMap.insert("IsVariationSelectorsSupplement", qMakePair(0xE0100, 0xE01EF)); + categoriesRangeMap.insert("IsSupplementaryPrivateUseArea-A", qMakePair(0xF0000, 0xFFFFF)); + categoriesRangeMap.insert("IsSupplementaryPrivateUseArea-B", qMakePair(0x100000, 0x10FFFF)); +} + int QRegExpEngine::getChar() { return (yyPos == yyLen) ? EOS : yyIn[yyPos++].unicode(); @@ -2713,6 +2868,177 @@ int QRegExpEngine::getEscape() yyCharClass->addCategories(0x000f807e); yyCharClass->addSingleton(0x005f); // '_' return Tok_CharClass; + case 'I': + if (xmlSchemaExtensions) { + yyCharClass->setNegative(!yyCharClass->negative()); + // fall through + } + case 'i': + if (xmlSchemaExtensions) { + yyCharClass->addCategories(0x000f807e); + yyCharClass->addSingleton(0x003a); // ':' + yyCharClass->addSingleton(0x005f); // '_' + yyCharClass->addRange(0x0041, 0x005a); // [A-Z] + yyCharClass->addRange(0x0061, 0x007a); // [a-z] + yyCharClass->addRange(0xc0, 0xd6); + yyCharClass->addRange(0xd8, 0xf6); + yyCharClass->addRange(0xf8, 0x2ff); + yyCharClass->addRange(0x370, 0x37d); + yyCharClass->addRange(0x37f, 0x1fff); + yyCharClass->addRange(0x200c, 0x200d); + yyCharClass->addRange(0x2070, 0x218f); + yyCharClass->addRange(0x2c00, 0x2fef); + yyCharClass->addRange(0x3001, 0xd7ff); + yyCharClass->addRange(0xf900, 0xfdcf); + yyCharClass->addRange(0xfdf0, 0xfffd); + yyCharClass->addRange((ushort)0x10000, (ushort)0xeffff); + } + return Tok_CharClass; + case 'C': + if (xmlSchemaExtensions) { + yyCharClass->setNegative(!yyCharClass->negative()); + // fall through + } + case 'c': + if (xmlSchemaExtensions) { + yyCharClass->addCategories(0x000f807e); + yyCharClass->addSingleton(0x002d); // '-' + yyCharClass->addSingleton(0x002e); // '.' + yyCharClass->addSingleton(0x003a); // ':' + yyCharClass->addSingleton(0x005f); // '_' + yyCharClass->addSingleton(0xb7); + yyCharClass->addRange(0x0030, 0x0039); // [0-9] + yyCharClass->addRange(0x0041, 0x005a); // [A-Z] + yyCharClass->addRange(0x0061, 0x007a); // [a-z] + yyCharClass->addRange(0xc0, 0xd6); + yyCharClass->addRange(0xd8, 0xf6); + yyCharClass->addRange(0xf8, 0x2ff); + yyCharClass->addRange(0x370, 0x37d); + yyCharClass->addRange(0x37f, 0x1fff); + yyCharClass->addRange(0x200c, 0x200d); + yyCharClass->addRange(0x2070, 0x218f); + yyCharClass->addRange(0x2c00, 0x2fef); + yyCharClass->addRange(0x3001, 0xd7ff); + yyCharClass->addRange(0xf900, 0xfdcf); + yyCharClass->addRange(0xfdf0, 0xfffd); + yyCharClass->addRange((ushort)0x10000, (ushort)0xeffff); + yyCharClass->addRange(0x0300, 0x036f); + yyCharClass->addRange(0x203f, 0x2040); + } + return Tok_CharClass; + case 'P': + if (xmlSchemaExtensions) { + yyCharClass->setNegative(!yyCharClass->negative()); + // fall through + } + case 'p': + if (xmlSchemaExtensions) { + if (yyCh != '{') { + error(RXERR_CHARCLASS); + return Tok_CharClass; + } + + QByteArray category; + yyCh = getChar(); + while (yyCh != '}') { + if (yyCh == EOS) { + error(RXERR_END); + return Tok_CharClass; + } + category.append(yyCh); + yyCh = getChar(); + } + yyCh = getChar(); // skip closing '}' + + if (category == "M") { + yyCharClass->addCategories(0x0000000e); + } else if (category == "Mn") { + yyCharClass->addCategories(0x00000002); + } else if (category == "Mc") { + yyCharClass->addCategories(0x00000004); + } else if (category == "Me") { + yyCharClass->addCategories(0x00000008); + } else if (category == "N") { + yyCharClass->addCategories(0x00000070); + } else if (category == "Nd") { + yyCharClass->addCategories(0x00000010); + } else if (category == "Nl") { + yyCharClass->addCategories(0x00000020); + } else if (category == "No") { + yyCharClass->addCategories(0x00000040); + } else if (category == "Z") { + yyCharClass->addCategories(0x00000380); + } else if (category == "Zs") { + yyCharClass->addCategories(0x00000080); + } else if (category == "Zl") { + yyCharClass->addCategories(0x00000100); + } else if (category == "Zp") { + yyCharClass->addCategories(0x00000200); + } else if (category == "C") { + yyCharClass->addCategories(0x00006c00); + } else if (category == "Cc") { + yyCharClass->addCategories(0x00000400); + } else if (category == "Cf") { + yyCharClass->addCategories(0x00000800); + } else if (category == "Cs") { + yyCharClass->addCategories(0x00001000); + } else if (category == "Co") { + yyCharClass->addCategories(0x00002000); + } else if (category == "Cn") { + yyCharClass->addCategories(0x00004000); + } else if (category == "L") { + yyCharClass->addCategories(0x000f8000); + } else if (category == "Lu") { + yyCharClass->addCategories(0x00008000); + } else if (category == "Ll") { + yyCharClass->addCategories(0x00010000); + } else if (category == "Lt") { + yyCharClass->addCategories(0x00020000); + } else if (category == "Lm") { + yyCharClass->addCategories(0x00040000); + } else if (category == "Lo") { + yyCharClass->addCategories(0x00080000); + } else if (category == "P") { + yyCharClass->addCategories(0x4f580780); + } else if (category == "Pc") { + yyCharClass->addCategories(0x00100000); + } else if (category == "Pd") { + yyCharClass->addCategories(0x00200000); + } else if (category == "Ps") { + yyCharClass->addCategories(0x00400000); + } else if (category == "Pe") { + yyCharClass->addCategories(0x00800000); + } else if (category == "Pi") { + yyCharClass->addCategories(0x01000000); + } else if (category == "Pf") { + yyCharClass->addCategories(0x02000000); + } else if (category == "Po") { + yyCharClass->addCategories(0x04000000); + } else if (category == "S") { + yyCharClass->addCategories(0x78000000); + } else if (category == "Sm") { + yyCharClass->addCategories(0x08000000); + } else if (category == "Sc") { + yyCharClass->addCategories(0x10000000); + } else if (category == "Sk") { + yyCharClass->addCategories(0x20000000); + } else if (category == "So") { + yyCharClass->addCategories(0x40000000); + } else if (category.startsWith("Is")) { + if (categoriesRangeMap.isEmpty()) + setupCategoriesRangeMap(); + + if (categoriesRangeMap.contains(category)) { + const QPair range = categoriesRangeMap.value(category); + yyCharClass->addRange(range.first, range.second); + } else { + error(RXERR_CATEGORY); + } + } else { + error(RXERR_CATEGORY); + } + } + return Tok_CharClass; #endif #ifndef QT_NO_REGEXP_ESCAPE case 'x': @@ -2934,7 +3260,7 @@ int QRegExpEngine::getToken() yyMaxRep = getRep(InftyRep); } if (yyMaxRep < yyMinRep) - qSwap(yyMinRep, yyMaxRep); + error(RXERR_INTERVAL); if (yyCh != '}') error(RXERR_REPETITION); yyCh = getChar(); diff --git a/src/corelib/tools/qregexp.h b/src/corelib/tools/qregexp.h index b387e23..f2e3d3b 100644 --- a/src/corelib/tools/qregexp.h +++ b/src/corelib/tools/qregexp.h @@ -61,7 +61,7 @@ class QStringList; class Q_CORE_EXPORT QRegExp { public: - enum PatternSyntax { RegExp, Wildcard, FixedString, RegExp2 }; + enum PatternSyntax { RegExp, Wildcard, FixedString, RegExp2, W3CXmlSchema11 }; enum CaretMode { CaretAtZero, CaretAtOffset, CaretWontMatch }; QRegExp(); -- cgit v0.12 From 135a028d9dc9a28a0a072665a7dc43b7e9e187be Mon Sep 17 00:00:00 2001 From: Tobias Koenig Date: Sat, 16 May 2009 12:19:10 +0200 Subject: Add W3C XML Schema validation support This was done by Tobias Koenig, as part of an internship at Trolltech/Qt Software, started at Wed Oct 1 18:32:43 2008 +0200, and the last commit being part of this commit dating Tue Feb 24 11:03:36 2009 +0100. This is work consisting of about 650 commits squashed into one, where the first commit was 61b280386c1905a15690fdd917dcbc8eb09b6283, in the repository before Qt's history cut. --- examples/tools/regexp/regexpdialog.cpp | 1 + examples/xmlpatterns/schema/main.cpp | 24 + examples/xmlpatterns/schema/mainwindow.cpp | 175 + examples/xmlpatterns/schema/mainwindow.h | 38 + examples/xmlpatterns/schema/schema.pro | 11 + examples/xmlpatterns/schema/schema.qrc | 13 + examples/xmlpatterns/schema/schema.ui | 71 + examples/xmlpatterns/xmlpatterns.pro | 3 +- src/xmlpatterns/Doxyfile | 2 +- src/xmlpatterns/acceltree/qacceltree.cpp | 43 + src/xmlpatterns/acceltree/qacceltree_p.h | 17 +- src/xmlpatterns/acceltree/qacceltreebuilder.cpp | 31 +- src/xmlpatterns/acceltree/qacceltreebuilder_p.h | 19 +- .../acceltree/qacceltreeresourceloader.cpp | 60 +- .../acceltree/qacceltreeresourceloader_p.h | 27 +- src/xmlpatterns/api/api.pri | 11 + src/xmlpatterns/api/qabstractxmlnodemodel.cpp | 16 + src/xmlpatterns/api/qabstractxmlnodemodel.h | 5 + src/xmlpatterns/api/qabstractxmlnodemodel_p.h | 10 + src/xmlpatterns/api/qabstractxmlpullprovider.cpp | 147 + src/xmlpatterns/api/qabstractxmlpullprovider_p.h | 83 + src/xmlpatterns/api/qpullbridge.cpp | 202 + src/xmlpatterns/api/qpullbridge_p.h | 73 + src/xmlpatterns/api/qresourcedelegator.cpp | 8 - src/xmlpatterns/api/qxmlnamepool.cpp | 4 + src/xmlpatterns/api/qxmlnamepool.h | 7 + src/xmlpatterns/api/qxmlquery.cpp | 12 + src/xmlpatterns/api/qxmlquery.h | 11 +- src/xmlpatterns/api/qxmlquery_p.h | 24 +- src/xmlpatterns/api/qxmlschema.cpp | 229 + src/xmlpatterns/api/qxmlschema.h | 66 + src/xmlpatterns/api/qxmlschema_p.cpp | 169 + src/xmlpatterns/api/qxmlschema_p.h | 79 + src/xmlpatterns/api/qxmlschemavalidator.cpp | 264 + src/xmlpatterns/api/qxmlschemavalidator.h | 64 + src/xmlpatterns/api/qxmlschemavalidator_p.h | 98 + src/xmlpatterns/common.pri | 1 + src/xmlpatterns/data/data.pri | 20 +- src/xmlpatterns/data/qcomparisonfactory.cpp | 124 + src/xmlpatterns/data/qcomparisonfactory_p.h | 91 + src/xmlpatterns/data/qitem_p.h | 5 + src/xmlpatterns/data/qvaluefactory.cpp | 76 + src/xmlpatterns/data/qvaluefactory_p.h | 68 + .../environment/createReportContext.xsl | 5 + src/xmlpatterns/environment/qreportcontext.cpp | 1 + src/xmlpatterns/environment/qreportcontext_p.h | 4 + src/xmlpatterns/expr/qcastingplatform.cpp | 22 +- src/xmlpatterns/expr/qcastingplatform_p.h | 23 +- src/xmlpatterns/expr/qexpressionfactory.cpp | 27 +- src/xmlpatterns/functions/qpatternplatform.cpp | 21 +- src/xmlpatterns/functions/qpatternplatform_p.h | 18 +- src/xmlpatterns/parser/qquerytransformparser.cpp | 944 +-- src/xmlpatterns/parser/qquerytransformparser_p.h | 40 + src/xmlpatterns/parser/querytransformparser.ypp | 174 +- src/xmlpatterns/schema/.gitignore | 1 + src/xmlpatterns/schema/builtinschemas.qrc | 5 + src/xmlpatterns/schema/doc/All_diagram.dot | 13 + src/xmlpatterns/schema/doc/Alternative_diagram.dot | 11 + src/xmlpatterns/schema/doc/Annotation_diagram.dot | 9 + .../schema/doc/AnyAttribute_diagram.dot | 6 + src/xmlpatterns/schema/doc/Any_diagram.dot | 6 + src/xmlpatterns/schema/doc/Assert_diagram.dot | 6 + src/xmlpatterns/schema/doc/Choice_diagram.dot | 22 + .../schema/doc/ComplexContentExtension_diagram.dot | 47 + .../doc/ComplexContentRestriction_diagram.dot | 47 + .../schema/doc/ComplexContent_diagram.dot | 11 + .../schema/doc/DefaultOpenContent_diagram.dot | 9 + .../schema/doc/EnumerationFacet_diagram.dot | 6 + src/xmlpatterns/schema/doc/Field_diagram.dot | 6 + .../schema/doc/FractionDigitsFacet_diagram.dot | 6 + .../schema/doc/GlobalAttribute_diagram.dot | 9 + .../schema/doc/GlobalComplexType_diagram.dot | 52 + .../schema/doc/GlobalElement_diagram.dot | 32 + .../schema/doc/GlobalSimpleType_diagram.dot | 13 + src/xmlpatterns/schema/doc/Import_diagram.dot | 6 + src/xmlpatterns/schema/doc/Include_diagram.dot | 6 + src/xmlpatterns/schema/doc/KeyRef_diagram.dot | 12 + src/xmlpatterns/schema/doc/Key_diagram.dot | 12 + src/xmlpatterns/schema/doc/LengthFacet_diagram.dot | 6 + src/xmlpatterns/schema/doc/List_diagram.dot | 9 + src/xmlpatterns/schema/doc/LocalAll_diagram.dot | 13 + .../schema/doc/LocalAttribute_diagram.dot | 9 + src/xmlpatterns/schema/doc/LocalChoice_diagram.dot | 22 + .../schema/doc/LocalComplexType_diagram.dot | 52 + .../schema/doc/LocalElement_diagram.dot | 32 + .../schema/doc/LocalSequence_diagram.dot | 22 + .../schema/doc/LocalSimpleType_diagram.dot | 13 + .../schema/doc/MaxExclusiveFacet_diagram.dot | 6 + .../schema/doc/MaxInclusiveFacet_diagram.dot | 6 + .../schema/doc/MaxLengthFacet_diagram.dot | 6 + .../schema/doc/MinExclusiveFacet_diagram.dot | 6 + .../schema/doc/MinInclusiveFacet_diagram.dot | 6 + .../schema/doc/MinLengthFacet_diagram.dot | 6 + .../schema/doc/NamedAttributeGroup_diagram.dot | 17 + src/xmlpatterns/schema/doc/NamedGroup_diagram.dot | 13 + src/xmlpatterns/schema/doc/Notation_diagram.dot | 6 + src/xmlpatterns/schema/doc/Override_diagram.dot | 21 + .../schema/doc/PatternFacet_diagram.dot | 6 + src/xmlpatterns/schema/doc/Redefine_diagram.dot | 15 + .../schema/doc/ReferredAttributeGroup_diagram.dot | 6 + .../schema/doc/ReferredGroup_diagram.dot | 13 + src/xmlpatterns/schema/doc/Schema_diagram.dot | 66 + src/xmlpatterns/schema/doc/Selector_diagram.dot | 6 + src/xmlpatterns/schema/doc/Sequence_diagram.dot | 22 + .../schema/doc/SimpleContentExtension_diagram.dot | 23 + .../doc/SimpleContentRestriction_diagram.dot | 87 + .../schema/doc/SimpleContent_diagram.dot | 11 + .../schema/doc/SimpleRestriction_diagram.dot | 62 + .../schema/doc/TotalDigitsFacet_diagram.dot | 6 + src/xmlpatterns/schema/doc/Union_diagram.dot | 10 + src/xmlpatterns/schema/doc/Unique_diagram.dot | 12 + .../schema/doc/WhiteSpaceFacet_diagram.dot | 6 + src/xmlpatterns/schema/doc/legend.dot | 7 + src/xmlpatterns/schema/qnamespacesupport.cpp | 132 + src/xmlpatterns/schema/qnamespacesupport_p.h | 143 + src/xmlpatterns/schema/qxsdalternative.cpp | 38 + src/xmlpatterns/schema/qxsdalternative_p.h | 84 + src/xmlpatterns/schema/qxsdannotated.cpp | 33 + src/xmlpatterns/schema/qxsdannotated_p.h | 66 + src/xmlpatterns/schema/qxsdannotation.cpp | 48 + src/xmlpatterns/schema/qxsdannotation_p.h | 97 + .../schema/qxsdapplicationinformation.cpp | 38 + .../schema/qxsdapplicationinformation_p.h | 85 + src/xmlpatterns/schema/qxsdassertion.cpp | 28 + src/xmlpatterns/schema/qxsdassertion_p.h | 71 + src/xmlpatterns/schema/qxsdattribute.cpp | 100 + src/xmlpatterns/schema/qxsdattribute_p.h | 216 + src/xmlpatterns/schema/qxsdattributegroup.cpp | 43 + src/xmlpatterns/schema/qxsdattributegroup_p.h | 92 + src/xmlpatterns/schema/qxsdattributereference.cpp | 58 + src/xmlpatterns/schema/qxsdattributereference_p.h | 117 + src/xmlpatterns/schema/qxsdattributeterm.cpp | 28 + src/xmlpatterns/schema/qxsdattributeterm_p.h | 66 + src/xmlpatterns/schema/qxsdattributeuse.cpp | 106 + src/xmlpatterns/schema/qxsdattributeuse_p.h | 194 + src/xmlpatterns/schema/qxsdcomplextype.cpp | 201 + src/xmlpatterns/schema/qxsdcomplextype_p.h | 374 ++ src/xmlpatterns/schema/qxsddocumentation.cpp | 56 + src/xmlpatterns/schema/qxsddocumentation_p.h | 107 + src/xmlpatterns/schema/qxsdelement.cpp | 214 + src/xmlpatterns/schema/qxsdelement_p.h | 373 ++ src/xmlpatterns/schema/qxsdfacet.cpp | 94 + src/xmlpatterns/schema/qxsdfacet_p.h | 183 + src/xmlpatterns/schema/qxsdidcache.cpp | 36 + src/xmlpatterns/schema/qxsdidcache_p.h | 69 + src/xmlpatterns/schema/qxsdidchelper.cpp | 107 + src/xmlpatterns/schema/qxsdidchelper_p.h | 156 + src/xmlpatterns/schema/qxsdidentityconstraint.cpp | 63 + src/xmlpatterns/schema/qxsdidentityconstraint_p.h | 143 + src/xmlpatterns/schema/qxsdinstancereader.cpp | 166 + src/xmlpatterns/schema/qxsdinstancereader_p.h | 159 + src/xmlpatterns/schema/qxsdmodelgroup.cpp | 48 + src/xmlpatterns/schema/qxsdmodelgroup_p.h | 109 + src/xmlpatterns/schema/qxsdnotation.cpp | 38 + src/xmlpatterns/schema/qxsdnotation_p.h | 89 + src/xmlpatterns/schema/qxsdparticle.cpp | 65 + src/xmlpatterns/schema/qxsdparticle_p.h | 124 + src/xmlpatterns/schema/qxsdparticlechecker.cpp | 510 ++ src/xmlpatterns/schema/qxsdparticlechecker_p.h | 69 + src/xmlpatterns/schema/qxsdreference.cpp | 53 + src/xmlpatterns/schema/qxsdreference_p.h | 115 + src/xmlpatterns/schema/qxsdschema.cpp | 242 + src/xmlpatterns/schema/qxsdschema_p.h | 271 + src/xmlpatterns/schema/qxsdschemachecker.cpp | 2031 +++++++ .../schema/qxsdschemachecker_helper.cpp | 276 + src/xmlpatterns/schema/qxsdschemachecker_p.h | 254 + src/xmlpatterns/schema/qxsdschemachecker_setup.cpp | 287 + src/xmlpatterns/schema/qxsdschemacontext.cpp | 498 ++ src/xmlpatterns/schema/qxsdschemacontext_p.h | 157 + src/xmlpatterns/schema/qxsdschemadebugger.cpp | 196 + src/xmlpatterns/schema/qxsdschemadebugger_p.h | 97 + src/xmlpatterns/schema/qxsdschemahelper.cpp | 791 +++ src/xmlpatterns/schema/qxsdschemahelper_p.h | 156 + src/xmlpatterns/schema/qxsdschemamerger.cpp | 127 + src/xmlpatterns/schema/qxsdschemamerger_p.h | 69 + src/xmlpatterns/schema/qxsdschemaparser.cpp | 6012 ++++++++++++++++++++ src/xmlpatterns/schema/qxsdschemaparser_p.h | 691 +++ src/xmlpatterns/schema/qxsdschemaparser_setup.cpp | 1070 ++++ src/xmlpatterns/schema/qxsdschemaparsercontext.cpp | 573 ++ src/xmlpatterns/schema/qxsdschemaparsercontext_p.h | 201 + src/xmlpatterns/schema/qxsdschemaresolver.cpp | 1706 ++++++ src/xmlpatterns/schema/qxsdschemaresolver_p.h | 548 ++ src/xmlpatterns/schema/qxsdschematoken.cpp | 2951 ++++++++++ src/xmlpatterns/schema/qxsdschematoken_p.h | 168 + src/xmlpatterns/schema/qxsdschematypesfactory.cpp | 96 + src/xmlpatterns/schema/qxsdschematypesfactory_p.h | 79 + src/xmlpatterns/schema/qxsdsimpletype.cpp | 118 + src/xmlpatterns/schema/qxsdsimpletype_p.h | 189 + src/xmlpatterns/schema/qxsdstatemachine.cpp | 433 ++ src/xmlpatterns/schema/qxsdstatemachine_p.h | 209 + src/xmlpatterns/schema/qxsdstatemachinebuilder.cpp | 230 + src/xmlpatterns/schema/qxsdstatemachinebuilder_p.h | 111 + src/xmlpatterns/schema/qxsdterm.cpp | 38 + src/xmlpatterns/schema/qxsdterm_p.h | 84 + src/xmlpatterns/schema/qxsdtypechecker.cpp | 1308 +++++ src/xmlpatterns/schema/qxsdtypechecker_p.h | 159 + src/xmlpatterns/schema/qxsduserschematype.cpp | 45 + src/xmlpatterns/schema/qxsduserschematype_p.h | 94 + .../schema/qxsdvalidatedxmlnodemodel.cpp | 185 + .../schema/qxsdvalidatedxmlnodemodel_p.h | 149 + .../schema/qxsdvalidatinginstancereader.cpp | 1245 ++++ .../schema/qxsdvalidatinginstancereader_p.h | 266 + src/xmlpatterns/schema/qxsdwildcard.cpp | 85 + src/xmlpatterns/schema/qxsdwildcard_p.h | 169 + src/xmlpatterns/schema/qxsdxpathexpression.cpp | 58 + src/xmlpatterns/schema/qxsdxpathexpression_p.h | 113 + src/xmlpatterns/schema/schema.pri | 93 + src/xmlpatterns/schema/schemas/xml.xsd | 145 + src/xmlpatterns/schema/tokens.xml | 125 + src/xmlpatterns/type/qanysimpletype.cpp | 10 + src/xmlpatterns/type/qanysimpletype_p.h | 12 + src/xmlpatterns/type/qanytype.cpp | 12 +- src/xmlpatterns/type/qanytype_p.h | 10 + src/xmlpatterns/type/qnamedschemacomponent.cpp | 41 + src/xmlpatterns/type/qnamedschemacomponent_p.h | 97 + src/xmlpatterns/type/qprimitives_p.h | 13 + src/xmlpatterns/type/qschematype.cpp | 5 + src/xmlpatterns/type/qschematype_p.h | 30 +- src/xmlpatterns/type/type.pri | 2 + src/xmlpatterns/utils/qpatternistlocale_p.h | 10 + src/xmlpatterns/xmlpatterns.pro | 2 + tests/auto/auto.pro | 5 + .../tst_qabstractxmlnodemodel.cpp | 8 + tests/auto/qxmlquery/tst_qxmlquery.cpp | 158 + tests/auto/qxmlschema/.gitignore | 1 + tests/auto/qxmlschema/qxmlschema.pro | 4 + tests/auto/qxmlschema/tst_qxmlschema.cpp | 231 + tests/auto/qxmlschemavalidator/.gitignore | 1 + .../qxmlschemavalidator/qxmlschemavalidator.pro | 4 + .../tst_qxmlschemavalidator.cpp | 308 + tests/auto/runQtXmlPatternsTests.sh | 2 + tests/auto/xmlpatterns.pri | 14 + .../test/tst_xmlpatternsdiagnosticsts.cpp | 2 +- tests/auto/xmlpatternsschema/.gitignore | 1 + .../xmlpatternsschema/tst_xmlpatternsschema.cpp | 988 ++++ tests/auto/xmlpatternsschema/xmlpatternsschema.pro | 6 + tests/auto/xmlpatternsschemats/.gitignore | 4 + tests/auto/xmlpatternsschemats/Baseline.xml | 2 + .../auto/xmlpatternsschemats/TESTSUITE/.gitignore | 3 + .../xmlpatternsschemats/TESTSUITE/unifyCatalog.xsl | 21 + .../xmlpatternsschemats/TESTSUITE/updateSuite.sh | 20 + .../tst_xmlpatternsschemats.cpp | 44 + .../xmlpatternsschemats/xmlpatternsschemats.pro | 23 + tests/auto/xmlpatternsvalidator/files/instance.xml | 3 + .../xmlpatternsvalidator/files/invalid_schema.xsd | 12 + .../files/other_valid_schema.xsd | 12 + .../files/sa_invalid_instance.xml | 3 + .../files/sa_valid_instance.xml | 3 + .../xmlpatternsvalidator/files/valid_schema.xsd | 12 + .../tst_xmlpatternsvalidator.cpp | 174 + .../xmlpatternsvalidator/xmlpatternsvalidator.pro | 5 + tests/auto/xmlpatternsview/view/MainWindow.cpp | 32 +- tests/auto/xmlpatternsview/view/MainWindow.h | 6 +- tests/auto/xmlpatternsview/view/ui_MainWindow.ui | 9 + tests/auto/xmlpatternsxqts/lib/TestBaseLine.cpp | 7 + tests/auto/xmlpatternsxqts/lib/TestBaseLine.h | 9 +- tests/auto/xmlpatternsxqts/lib/TestGroup.cpp | 6 +- tests/auto/xmlpatternsxqts/lib/TestSuite.cpp | 26 +- tests/auto/xmlpatternsxqts/lib/TestSuite.h | 14 +- tests/auto/xmlpatternsxqts/lib/TreeModel.cpp | 9 +- tests/auto/xmlpatternsxqts/lib/XSDTSTestCase.cpp | 346 ++ tests/auto/xmlpatternsxqts/lib/XSDTSTestCase.h | 130 + .../xmlpatternsxqts/lib/XSDTestSuiteHandler.cpp | 881 +++ .../auto/xmlpatternsxqts/lib/XSDTestSuiteHandler.h | 90 + tests/auto/xmlpatternsxqts/lib/lib.pro | 4 + tests/auto/xmlpatternsxqts/test/tst_suitetest.cpp | 15 +- tests/auto/xmlpatternsxqts/test/tst_suitetest.h | 14 +- .../xmlpatternsxqts/test/tst_xmlpatternsxqts.cpp | 2 +- .../auto/xmlpatternsxslts/tst_xmlpatternsxslts.cpp | 2 +- tools/tools.pro | 2 +- tools/xmlpatternsvalidator/main.cpp | 96 + tools/xmlpatternsvalidator/main.h | 46 + .../xmlpatternsvalidator/xmlpatternsvalidator.pro | 19 + 273 files changed, 39053 insertions(+), 595 deletions(-) create mode 100644 examples/xmlpatterns/schema/main.cpp create mode 100644 examples/xmlpatterns/schema/mainwindow.cpp create mode 100644 examples/xmlpatterns/schema/mainwindow.h create mode 100644 examples/xmlpatterns/schema/schema.pro create mode 100644 examples/xmlpatterns/schema/schema.qrc create mode 100644 examples/xmlpatterns/schema/schema.ui create mode 100644 src/xmlpatterns/api/qabstractxmlpullprovider.cpp create mode 100644 src/xmlpatterns/api/qabstractxmlpullprovider_p.h create mode 100644 src/xmlpatterns/api/qpullbridge.cpp create mode 100644 src/xmlpatterns/api/qpullbridge_p.h create mode 100644 src/xmlpatterns/api/qxmlschema.cpp create mode 100644 src/xmlpatterns/api/qxmlschema.h create mode 100644 src/xmlpatterns/api/qxmlschema_p.cpp create mode 100644 src/xmlpatterns/api/qxmlschema_p.h create mode 100644 src/xmlpatterns/api/qxmlschemavalidator.cpp create mode 100644 src/xmlpatterns/api/qxmlschemavalidator.h create mode 100644 src/xmlpatterns/api/qxmlschemavalidator_p.h create mode 100644 src/xmlpatterns/data/qcomparisonfactory.cpp create mode 100644 src/xmlpatterns/data/qcomparisonfactory_p.h create mode 100644 src/xmlpatterns/data/qvaluefactory.cpp create mode 100644 src/xmlpatterns/data/qvaluefactory_p.h create mode 100644 src/xmlpatterns/schema/.gitignore create mode 100644 src/xmlpatterns/schema/builtinschemas.qrc create mode 100644 src/xmlpatterns/schema/doc/All_diagram.dot create mode 100644 src/xmlpatterns/schema/doc/Alternative_diagram.dot create mode 100644 src/xmlpatterns/schema/doc/Annotation_diagram.dot create mode 100644 src/xmlpatterns/schema/doc/AnyAttribute_diagram.dot create mode 100644 src/xmlpatterns/schema/doc/Any_diagram.dot create mode 100644 src/xmlpatterns/schema/doc/Assert_diagram.dot create mode 100644 src/xmlpatterns/schema/doc/Choice_diagram.dot create mode 100644 src/xmlpatterns/schema/doc/ComplexContentExtension_diagram.dot create mode 100644 src/xmlpatterns/schema/doc/ComplexContentRestriction_diagram.dot create mode 100644 src/xmlpatterns/schema/doc/ComplexContent_diagram.dot create mode 100644 src/xmlpatterns/schema/doc/DefaultOpenContent_diagram.dot create mode 100644 src/xmlpatterns/schema/doc/EnumerationFacet_diagram.dot create mode 100644 src/xmlpatterns/schema/doc/Field_diagram.dot create mode 100644 src/xmlpatterns/schema/doc/FractionDigitsFacet_diagram.dot create mode 100644 src/xmlpatterns/schema/doc/GlobalAttribute_diagram.dot create mode 100644 src/xmlpatterns/schema/doc/GlobalComplexType_diagram.dot create mode 100644 src/xmlpatterns/schema/doc/GlobalElement_diagram.dot create mode 100644 src/xmlpatterns/schema/doc/GlobalSimpleType_diagram.dot create mode 100644 src/xmlpatterns/schema/doc/Import_diagram.dot create mode 100644 src/xmlpatterns/schema/doc/Include_diagram.dot create mode 100644 src/xmlpatterns/schema/doc/KeyRef_diagram.dot create mode 100644 src/xmlpatterns/schema/doc/Key_diagram.dot create mode 100644 src/xmlpatterns/schema/doc/LengthFacet_diagram.dot create mode 100644 src/xmlpatterns/schema/doc/List_diagram.dot create mode 100644 src/xmlpatterns/schema/doc/LocalAll_diagram.dot create mode 100644 src/xmlpatterns/schema/doc/LocalAttribute_diagram.dot create mode 100644 src/xmlpatterns/schema/doc/LocalChoice_diagram.dot create mode 100644 src/xmlpatterns/schema/doc/LocalComplexType_diagram.dot create mode 100644 src/xmlpatterns/schema/doc/LocalElement_diagram.dot create mode 100644 src/xmlpatterns/schema/doc/LocalSequence_diagram.dot create mode 100644 src/xmlpatterns/schema/doc/LocalSimpleType_diagram.dot create mode 100644 src/xmlpatterns/schema/doc/MaxExclusiveFacet_diagram.dot create mode 100644 src/xmlpatterns/schema/doc/MaxInclusiveFacet_diagram.dot create mode 100644 src/xmlpatterns/schema/doc/MaxLengthFacet_diagram.dot create mode 100644 src/xmlpatterns/schema/doc/MinExclusiveFacet_diagram.dot create mode 100644 src/xmlpatterns/schema/doc/MinInclusiveFacet_diagram.dot create mode 100644 src/xmlpatterns/schema/doc/MinLengthFacet_diagram.dot create mode 100644 src/xmlpatterns/schema/doc/NamedAttributeGroup_diagram.dot create mode 100644 src/xmlpatterns/schema/doc/NamedGroup_diagram.dot create mode 100644 src/xmlpatterns/schema/doc/Notation_diagram.dot create mode 100644 src/xmlpatterns/schema/doc/Override_diagram.dot create mode 100644 src/xmlpatterns/schema/doc/PatternFacet_diagram.dot create mode 100644 src/xmlpatterns/schema/doc/Redefine_diagram.dot create mode 100644 src/xmlpatterns/schema/doc/ReferredAttributeGroup_diagram.dot create mode 100644 src/xmlpatterns/schema/doc/ReferredGroup_diagram.dot create mode 100644 src/xmlpatterns/schema/doc/Schema_diagram.dot create mode 100644 src/xmlpatterns/schema/doc/Selector_diagram.dot create mode 100644 src/xmlpatterns/schema/doc/Sequence_diagram.dot create mode 100644 src/xmlpatterns/schema/doc/SimpleContentExtension_diagram.dot create mode 100644 src/xmlpatterns/schema/doc/SimpleContentRestriction_diagram.dot create mode 100644 src/xmlpatterns/schema/doc/SimpleContent_diagram.dot create mode 100644 src/xmlpatterns/schema/doc/SimpleRestriction_diagram.dot create mode 100644 src/xmlpatterns/schema/doc/TotalDigitsFacet_diagram.dot create mode 100644 src/xmlpatterns/schema/doc/Union_diagram.dot create mode 100644 src/xmlpatterns/schema/doc/Unique_diagram.dot create mode 100644 src/xmlpatterns/schema/doc/WhiteSpaceFacet_diagram.dot create mode 100644 src/xmlpatterns/schema/doc/legend.dot create mode 100644 src/xmlpatterns/schema/qnamespacesupport.cpp create mode 100644 src/xmlpatterns/schema/qnamespacesupport_p.h create mode 100644 src/xmlpatterns/schema/qxsdalternative.cpp create mode 100644 src/xmlpatterns/schema/qxsdalternative_p.h create mode 100644 src/xmlpatterns/schema/qxsdannotated.cpp create mode 100644 src/xmlpatterns/schema/qxsdannotated_p.h create mode 100644 src/xmlpatterns/schema/qxsdannotation.cpp create mode 100644 src/xmlpatterns/schema/qxsdannotation_p.h create mode 100644 src/xmlpatterns/schema/qxsdapplicationinformation.cpp create mode 100644 src/xmlpatterns/schema/qxsdapplicationinformation_p.h create mode 100644 src/xmlpatterns/schema/qxsdassertion.cpp create mode 100644 src/xmlpatterns/schema/qxsdassertion_p.h create mode 100644 src/xmlpatterns/schema/qxsdattribute.cpp create mode 100644 src/xmlpatterns/schema/qxsdattribute_p.h create mode 100644 src/xmlpatterns/schema/qxsdattributegroup.cpp create mode 100644 src/xmlpatterns/schema/qxsdattributegroup_p.h create mode 100644 src/xmlpatterns/schema/qxsdattributereference.cpp create mode 100644 src/xmlpatterns/schema/qxsdattributereference_p.h create mode 100644 src/xmlpatterns/schema/qxsdattributeterm.cpp create mode 100644 src/xmlpatterns/schema/qxsdattributeterm_p.h create mode 100644 src/xmlpatterns/schema/qxsdattributeuse.cpp create mode 100644 src/xmlpatterns/schema/qxsdattributeuse_p.h create mode 100644 src/xmlpatterns/schema/qxsdcomplextype.cpp create mode 100644 src/xmlpatterns/schema/qxsdcomplextype_p.h create mode 100644 src/xmlpatterns/schema/qxsddocumentation.cpp create mode 100644 src/xmlpatterns/schema/qxsddocumentation_p.h create mode 100644 src/xmlpatterns/schema/qxsdelement.cpp create mode 100644 src/xmlpatterns/schema/qxsdelement_p.h create mode 100644 src/xmlpatterns/schema/qxsdfacet.cpp create mode 100644 src/xmlpatterns/schema/qxsdfacet_p.h create mode 100644 src/xmlpatterns/schema/qxsdidcache.cpp create mode 100644 src/xmlpatterns/schema/qxsdidcache_p.h create mode 100644 src/xmlpatterns/schema/qxsdidchelper.cpp create mode 100644 src/xmlpatterns/schema/qxsdidchelper_p.h create mode 100644 src/xmlpatterns/schema/qxsdidentityconstraint.cpp create mode 100644 src/xmlpatterns/schema/qxsdidentityconstraint_p.h create mode 100644 src/xmlpatterns/schema/qxsdinstancereader.cpp create mode 100644 src/xmlpatterns/schema/qxsdinstancereader_p.h create mode 100644 src/xmlpatterns/schema/qxsdmodelgroup.cpp create mode 100644 src/xmlpatterns/schema/qxsdmodelgroup_p.h create mode 100644 src/xmlpatterns/schema/qxsdnotation.cpp create mode 100644 src/xmlpatterns/schema/qxsdnotation_p.h create mode 100644 src/xmlpatterns/schema/qxsdparticle.cpp create mode 100644 src/xmlpatterns/schema/qxsdparticle_p.h create mode 100644 src/xmlpatterns/schema/qxsdparticlechecker.cpp create mode 100644 src/xmlpatterns/schema/qxsdparticlechecker_p.h create mode 100644 src/xmlpatterns/schema/qxsdreference.cpp create mode 100644 src/xmlpatterns/schema/qxsdreference_p.h create mode 100644 src/xmlpatterns/schema/qxsdschema.cpp create mode 100644 src/xmlpatterns/schema/qxsdschema_p.h create mode 100644 src/xmlpatterns/schema/qxsdschemachecker.cpp create mode 100644 src/xmlpatterns/schema/qxsdschemachecker_helper.cpp create mode 100644 src/xmlpatterns/schema/qxsdschemachecker_p.h create mode 100644 src/xmlpatterns/schema/qxsdschemachecker_setup.cpp create mode 100644 src/xmlpatterns/schema/qxsdschemacontext.cpp create mode 100644 src/xmlpatterns/schema/qxsdschemacontext_p.h create mode 100644 src/xmlpatterns/schema/qxsdschemadebugger.cpp create mode 100644 src/xmlpatterns/schema/qxsdschemadebugger_p.h create mode 100644 src/xmlpatterns/schema/qxsdschemahelper.cpp create mode 100644 src/xmlpatterns/schema/qxsdschemahelper_p.h create mode 100644 src/xmlpatterns/schema/qxsdschemamerger.cpp create mode 100644 src/xmlpatterns/schema/qxsdschemamerger_p.h create mode 100644 src/xmlpatterns/schema/qxsdschemaparser.cpp create mode 100644 src/xmlpatterns/schema/qxsdschemaparser_p.h create mode 100644 src/xmlpatterns/schema/qxsdschemaparser_setup.cpp create mode 100644 src/xmlpatterns/schema/qxsdschemaparsercontext.cpp create mode 100644 src/xmlpatterns/schema/qxsdschemaparsercontext_p.h create mode 100644 src/xmlpatterns/schema/qxsdschemaresolver.cpp create mode 100644 src/xmlpatterns/schema/qxsdschemaresolver_p.h create mode 100644 src/xmlpatterns/schema/qxsdschematoken.cpp create mode 100644 src/xmlpatterns/schema/qxsdschematoken_p.h create mode 100644 src/xmlpatterns/schema/qxsdschematypesfactory.cpp create mode 100644 src/xmlpatterns/schema/qxsdschematypesfactory_p.h create mode 100644 src/xmlpatterns/schema/qxsdsimpletype.cpp create mode 100644 src/xmlpatterns/schema/qxsdsimpletype_p.h create mode 100644 src/xmlpatterns/schema/qxsdstatemachine.cpp create mode 100644 src/xmlpatterns/schema/qxsdstatemachine_p.h create mode 100644 src/xmlpatterns/schema/qxsdstatemachinebuilder.cpp create mode 100644 src/xmlpatterns/schema/qxsdstatemachinebuilder_p.h create mode 100644 src/xmlpatterns/schema/qxsdterm.cpp create mode 100644 src/xmlpatterns/schema/qxsdterm_p.h create mode 100644 src/xmlpatterns/schema/qxsdtypechecker.cpp create mode 100644 src/xmlpatterns/schema/qxsdtypechecker_p.h create mode 100644 src/xmlpatterns/schema/qxsduserschematype.cpp create mode 100644 src/xmlpatterns/schema/qxsduserschematype_p.h create mode 100644 src/xmlpatterns/schema/qxsdvalidatedxmlnodemodel.cpp create mode 100644 src/xmlpatterns/schema/qxsdvalidatedxmlnodemodel_p.h create mode 100644 src/xmlpatterns/schema/qxsdvalidatinginstancereader.cpp create mode 100644 src/xmlpatterns/schema/qxsdvalidatinginstancereader_p.h create mode 100644 src/xmlpatterns/schema/qxsdwildcard.cpp create mode 100644 src/xmlpatterns/schema/qxsdwildcard_p.h create mode 100644 src/xmlpatterns/schema/qxsdxpathexpression.cpp create mode 100644 src/xmlpatterns/schema/qxsdxpathexpression_p.h create mode 100644 src/xmlpatterns/schema/schema.pri create mode 100644 src/xmlpatterns/schema/schemas/xml.xsd create mode 100644 src/xmlpatterns/schema/tokens.xml create mode 100644 src/xmlpatterns/type/qnamedschemacomponent.cpp create mode 100644 src/xmlpatterns/type/qnamedschemacomponent_p.h create mode 100644 tests/auto/qxmlschema/.gitignore create mode 100644 tests/auto/qxmlschema/qxmlschema.pro create mode 100644 tests/auto/qxmlschema/tst_qxmlschema.cpp create mode 100644 tests/auto/qxmlschemavalidator/.gitignore create mode 100644 tests/auto/qxmlschemavalidator/qxmlschemavalidator.pro create mode 100644 tests/auto/qxmlschemavalidator/tst_qxmlschemavalidator.cpp create mode 100644 tests/auto/xmlpatternsschema/.gitignore create mode 100644 tests/auto/xmlpatternsschema/tst_xmlpatternsschema.cpp create mode 100644 tests/auto/xmlpatternsschema/xmlpatternsschema.pro create mode 100644 tests/auto/xmlpatternsschemats/.gitignore create mode 100644 tests/auto/xmlpatternsschemats/Baseline.xml create mode 100644 tests/auto/xmlpatternsschemats/TESTSUITE/.gitignore create mode 100644 tests/auto/xmlpatternsschemats/TESTSUITE/unifyCatalog.xsl create mode 100755 tests/auto/xmlpatternsschemats/TESTSUITE/updateSuite.sh create mode 100644 tests/auto/xmlpatternsschemats/tst_xmlpatternsschemats.cpp create mode 100644 tests/auto/xmlpatternsschemats/xmlpatternsschemats.pro create mode 100644 tests/auto/xmlpatternsvalidator/files/instance.xml create mode 100644 tests/auto/xmlpatternsvalidator/files/invalid_schema.xsd create mode 100644 tests/auto/xmlpatternsvalidator/files/other_valid_schema.xsd create mode 100644 tests/auto/xmlpatternsvalidator/files/sa_invalid_instance.xml create mode 100644 tests/auto/xmlpatternsvalidator/files/sa_valid_instance.xml create mode 100644 tests/auto/xmlpatternsvalidator/files/valid_schema.xsd create mode 100644 tests/auto/xmlpatternsvalidator/tst_xmlpatternsvalidator.cpp create mode 100644 tests/auto/xmlpatternsvalidator/xmlpatternsvalidator.pro create mode 100644 tests/auto/xmlpatternsxqts/lib/XSDTSTestCase.cpp create mode 100644 tests/auto/xmlpatternsxqts/lib/XSDTSTestCase.h create mode 100644 tests/auto/xmlpatternsxqts/lib/XSDTestSuiteHandler.cpp create mode 100644 tests/auto/xmlpatternsxqts/lib/XSDTestSuiteHandler.h create mode 100644 tools/xmlpatternsvalidator/main.cpp create mode 100644 tools/xmlpatternsvalidator/main.h create mode 100644 tools/xmlpatternsvalidator/xmlpatternsvalidator.pro diff --git a/examples/tools/regexp/regexpdialog.cpp b/examples/tools/regexp/regexpdialog.cpp index 8fe7383..52805c1 100644 --- a/examples/tools/regexp/regexpdialog.cpp +++ b/examples/tools/regexp/regexpdialog.cpp @@ -69,6 +69,7 @@ RegExpDialog::RegExpDialog(QWidget *parent) syntaxComboBox->addItem(tr("Regular expression v2"), QRegExp::RegExp2); syntaxComboBox->addItem(tr("Wildcard"), QRegExp::Wildcard); syntaxComboBox->addItem(tr("Fixed string"), QRegExp::FixedString); + syntaxComboBox->addItem(tr("W3C Xml Schema 1.1"), QRegExp::W3CXmlSchema11); syntaxLabel = new QLabel(tr("&Pattern Syntax:")); syntaxLabel->setBuddy(syntaxComboBox); diff --git a/examples/xmlpatterns/schema/main.cpp b/examples/xmlpatterns/schema/main.cpp new file mode 100644 index 0000000..9537a87 --- /dev/null +++ b/examples/xmlpatterns/schema/main.cpp @@ -0,0 +1,24 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the $MODULE$ of the Qt Toolkit. +** +** $TROLLTECH_DUAL_LICENSE$ +** +****************************************************************************/ + +#include +#include "mainwindow.h" + +//! [0] +int main(int argc, char* argv[]) +{ + Q_INIT_RESOURCE(schema); + QApplication app(argc, argv); + MainWindow* const window = new MainWindow; + window->show(); + return app.exec(); +} +//! [0] diff --git a/examples/xmlpatterns/schema/mainwindow.cpp b/examples/xmlpatterns/schema/mainwindow.cpp new file mode 100644 index 0000000..807a65b --- /dev/null +++ b/examples/xmlpatterns/schema/mainwindow.cpp @@ -0,0 +1,175 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the $MODULE$ of the Qt Toolkit. +** +** $TROLLTECH_DUAL_LICENSE$ +** +****************************************************************************/ + +#include +#include + +#include "mainwindow.h" +#include "xmlsyntaxhighlighter.h" + +class MessageHandler : public QAbstractMessageHandler +{ + public: + MessageHandler() + : QAbstractMessageHandler(0) + { + } + + QString statusMessage() const + { + return m_description; + } + + int line() const + { + return m_sourceLocation.line(); + } + + int column() const + { + return m_sourceLocation.column(); + } + + protected: + virtual void handleMessage(QtMsgType type, const QString &description, const QUrl &identifier, const QSourceLocation &sourceLocation) + { + Q_UNUSED(type); + Q_UNUSED(identifier); + + m_messageType = type; + m_description = description; + m_sourceLocation = sourceLocation; + } + + private: + QtMsgType m_messageType; + QString m_description; + QSourceLocation m_sourceLocation; +}; + +MainWindow::MainWindow() +{ + setupUi(this); + + new XmlSyntaxHighlighter(schemaView->document()); + new XmlSyntaxHighlighter(instanceEdit->document()); + + schemaSelection->addItem(tr("Contact Schema")); + schemaSelection->addItem(tr("Recipe Schema")); + schemaSelection->addItem(tr("Order Schema")); + + instanceSelection->addItem(tr("Valid Contact Instance")); + instanceSelection->addItem(tr("Invalid Contact Instance")); + + connect(schemaSelection, SIGNAL(currentIndexChanged(int)), SLOT(schemaSelected(int))); + connect(instanceSelection, SIGNAL(currentIndexChanged(int)), SLOT(instanceSelected(int))); + connect(validateButton, SIGNAL(clicked()), SLOT(validate())); + connect(instanceEdit, SIGNAL(textChanged()), SLOT(textChanged())); + + validationStatus->setAlignment(Qt::AlignCenter | Qt::AlignVCenter); + + schemaSelected(0); + instanceSelected(0); +} + +void MainWindow::schemaSelected(int index) +{ + instanceSelection->clear(); + if (index == 0) { + instanceSelection->addItem(tr("Valid Contact Instance")); + instanceSelection->addItem(tr("Invalid Contact Instance")); + } else if (index == 1) { + instanceSelection->addItem(tr("Valid Recipe Instance")); + instanceSelection->addItem(tr("Invalid Recipe Instance")); + } else if (index == 2) { + instanceSelection->addItem(tr("Valid Order Instance")); + instanceSelection->addItem(tr("Invalid Order Instance")); + } + textChanged(); + + QFile schemaFile(QString(":/schema_%1.xsd").arg(index)); + schemaFile.open(QIODevice::ReadOnly); + const QString schemaText(QString::fromLatin1(schemaFile.readAll())); + schemaView->setPlainText(schemaText); + + validate(); +} + +void MainWindow::instanceSelected(int index) +{ + QFile instanceFile(QString(":/instance_%1.xml").arg((2*schemaSelection->currentIndex()) + index)); + instanceFile.open(QIODevice::ReadOnly); + const QString instanceText(QString::fromLatin1(instanceFile.readAll())); + instanceEdit->setPlainText(instanceText); + + validate(); +} + +void MainWindow::validate() +{ + const QByteArray schemaData = schemaView->toPlainText().toLatin1(); + const QByteArray instanceData = instanceEdit->toPlainText().toLatin1(); + + MessageHandler messageHandler; + + QXmlSchema schema; + schema.setMessageHandler(&messageHandler); + + schema.load(schemaData, QUrl("http://dummySchemaUrl/")); + + bool errorOccurred = false; + if (!schema.isValid()) { + errorOccurred = true; + } else { + QXmlSchemaValidator validator(schema); + if (!validator.validate(instanceData, QUrl("http://dummyInstanceUrl"))) + errorOccurred = true; + } + + if (errorOccurred) { + validationStatus->setText(messageHandler.statusMessage()); + moveCursor(messageHandler.line(), messageHandler.column()); + } else { + validationStatus->setText(tr("validation successful")); + } + + QString styleSheet = QString("QLabel {background: %1; padding: 3px}").arg(errorOccurred ? QColor(Qt::red).lighter(160).name() : QColor(Qt::green).lighter(160).name()); + validationStatus->setStyleSheet(styleSheet); +} + +void MainWindow::textChanged() +{ + instanceEdit->setExtraSelections(QList()); +} + +void MainWindow::moveCursor(int line, int column) +{ + instanceEdit->moveCursor(QTextCursor::Start); + for (int i = 1; i < line; ++i) + instanceEdit->moveCursor(QTextCursor::Down); + + for (int i = 1; i < column; ++i) + instanceEdit->moveCursor(QTextCursor::Right); + + QList extraSelections; + QTextEdit::ExtraSelection selection; + + const QColor lineColor = QColor(Qt::red).lighter(160); + selection.format.setBackground(lineColor); + selection.format.setProperty(QTextFormat::FullWidthSelection, true); + selection.cursor = instanceEdit->textCursor(); + selection.cursor.clearSelection(); + extraSelections.append(selection); + + instanceEdit->setExtraSelections(extraSelections); + + instanceEdit->setFocus(); +} diff --git a/examples/xmlpatterns/schema/mainwindow.h b/examples/xmlpatterns/schema/mainwindow.h new file mode 100644 index 0000000..e5dc2df --- /dev/null +++ b/examples/xmlpatterns/schema/mainwindow.h @@ -0,0 +1,38 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the $MODULE$ of the Qt Toolkit. +** +** $TROLLTECH_DUAL_LICENSE$ +** +****************************************************************************/ + +#ifndef MAINWINDOW_H +#define MAINWINDOW_H + +#include + +#include "ui_schema.h" + +//! [0] +class MainWindow : public QMainWindow, + private Ui::SchemaMainWindow +{ + Q_OBJECT + + public: + MainWindow(); + + private Q_SLOTS: + void schemaSelected(int index); + void instanceSelected(int index); + void validate(); + void textChanged(); + + private: + void moveCursor(int line, int column); +}; +//! [0] +#endif diff --git a/examples/xmlpatterns/schema/schema.pro b/examples/xmlpatterns/schema/schema.pro new file mode 100644 index 0000000..af32e0a --- /dev/null +++ b/examples/xmlpatterns/schema/schema.pro @@ -0,0 +1,11 @@ +QT += xmlpatterns +FORMS += schema.ui +HEADERS = mainwindow.h ../shared/xmlsyntaxhighlighter.h +RESOURCES = schema.qrc +SOURCES = main.cpp mainwindow.cpp ../shared/xmlsyntaxhighlighter.cpp +INCLUDEPATH += ../shared/ + +target.path = $$[QT_INSTALL_EXAMPLES]/xmlpatterns/schema +sources.files = $$SOURCES $$HEADERS $$RESOURCES *.pro *.xq *.html files +sources.path = $$[QT_INSTALL_EXAMPLES]/xmlpatterns/schema +INSTALLS += target sources diff --git a/examples/xmlpatterns/schema/schema.qrc b/examples/xmlpatterns/schema/schema.qrc new file mode 100644 index 0000000..eb7ddfd --- /dev/null +++ b/examples/xmlpatterns/schema/schema.qrc @@ -0,0 +1,13 @@ + + + files/contact.xsd + files/recipe.xsd + files/order.xsd + files/valid_contact.xml + files/invalid_contact.xml + files/valid_recipe.xml + files/invalid_recipe.xml + files/valid_order.xml + files/invalid_order.xml + + diff --git a/examples/xmlpatterns/schema/schema.ui b/examples/xmlpatterns/schema/schema.ui new file mode 100644 index 0000000..af7020a --- /dev/null +++ b/examples/xmlpatterns/schema/schema.ui @@ -0,0 +1,71 @@ + + + SchemaMainWindow + + + + 0 + 0 + 417 + 594 + + + + MainWindow + + + + + + + XML Schema Document: + + + + + + + + + + + + + XML Instance Document: + + + + + + + + + + + + + Status: + + + + + + + not validated + + + + + + + Validate + + + + + + + + + + diff --git a/examples/xmlpatterns/xmlpatterns.pro b/examples/xmlpatterns/xmlpatterns.pro index 1a57005..3ff3e35 100644 --- a/examples/xmlpatterns/xmlpatterns.pro +++ b/examples/xmlpatterns/xmlpatterns.pro @@ -2,7 +2,8 @@ TEMPLATE = subdirs SUBDIRS = recipes \ trafficinfo \ xquery \ - filetree + filetree \ + schema # This example depends on QtWebkit as well. contains(QT_CONFIG, webkit):SUBDIRS += qobjectxmlmodel diff --git a/src/xmlpatterns/Doxyfile b/src/xmlpatterns/Doxyfile index 60a6c77..83f7062 100644 --- a/src/xmlpatterns/Doxyfile +++ b/src/xmlpatterns/Doxyfile @@ -1157,7 +1157,7 @@ DOT_PATH = # contain dot files that are included in the documentation (see the # \dotfile command). -DOTFILE_DIRS = +DOTFILE_DIRS = schema/doc/ # Set the DOT_TRANSPARENT tag to YES to generate images with a transparent # background. This is disabled by default, which results in a white background. diff --git a/src/xmlpatterns/acceltree/qacceltree.cpp b/src/xmlpatterns/acceltree/qacceltree.cpp index 60e6e27..061021a 100644 --- a/src/xmlpatterns/acceltree/qacceltree.cpp +++ b/src/xmlpatterns/acceltree/qacceltree.cpp @@ -42,6 +42,7 @@ #include #include "qabstractxmlreceiver.h" +#include "qabstractxmlnodemodel_p.h" #include "qacceliterators_p.h" #include "qacceltree_p.h" #include "qatomicstring_p.h" @@ -55,6 +56,37 @@ QT_BEGIN_NAMESPACE using namespace QPatternist; +namespace QPatternist { + + class AccelTreePrivate : public QAbstractXmlNodeModelPrivate + { + public: + AccelTreePrivate(AccelTree *accelTree) + : m_accelTree(accelTree) + { + } + + virtual QSourceLocation sourceLocation(const QXmlNodeModelIndex &index) const + { + return m_accelTree->sourceLocation(index); + } + + private: + AccelTree *m_accelTree; + }; +} + +AccelTree::AccelTree(const QUrl &docURI, const QUrl &bURI) + : QAbstractXmlNodeModel(new AccelTreePrivate(this)) + , m_documentURI(docURI) + , m_baseURI(bURI) +{ + /* Pre-allocate at least a little bit. */ + // TODO. Do it according to what an average 4 KB doc contains. + basicData.reserve(100); + data.reserve(30); +} + void AccelTree::printStats(const NamePool::Ptr &np) const { Q_ASSERT(np); @@ -674,6 +706,17 @@ void AccelTree::copyNodeTo(const QXmlNodeModelIndex &node, } +QSourceLocation AccelTree::sourceLocation(const QXmlNodeModelIndex &index) const +{ + const PreNumber key = toPreNumber(index); + if (sourcePositions.contains(key)) { + const QPair position = sourcePositions.value(key); + return QSourceLocation(m_documentURI, position.first, position.second); + } else { + return QSourceLocation(); + } +} + void AccelTree::copyChildren(const QXmlNodeModelIndex &node, QAbstractXmlReceiver *const receiver, const NodeCopySettings &settings) const diff --git a/src/xmlpatterns/acceltree/qacceltree_p.h b/src/xmlpatterns/acceltree/qacceltree_p.h index 10320ba..4c0d844 100644 --- a/src/xmlpatterns/acceltree/qacceltree_p.h +++ b/src/xmlpatterns/acceltree/qacceltree_p.h @@ -91,6 +91,7 @@ namespace QPatternist */ class AccelTree : public QAbstractXmlNodeModel { + friend class AccelTreePrivate; public: using QAbstractXmlNodeModel::createIndex; @@ -99,15 +100,7 @@ namespace QPatternist typedef PreNumber PostNumber; typedef qint8 Depth; - inline AccelTree(const QUrl &docURI, - const QUrl &bURI) : m_documentURI(docURI), - m_baseURI(bURI) - { - /* Pre-allocate at least a little bit. */ - // TODO. Do it according to what an average 4 KB doc contains. - basicData.reserve(100); - data.reserve(30); - } + AccelTree(const QUrl &docURI, const QUrl &bURI); /** * @short Houses data for a node, and that all node kinds have. @@ -280,6 +273,7 @@ namespace QPatternist QHash data; QVector basicData; + QHash > sourcePositions; inline QUrl documentUri() const { @@ -381,6 +375,11 @@ namespace QPatternist private: /** + * Returns the source location for the object with the given @p index. + */ + QSourceLocation sourceLocation(const QXmlNodeModelIndex &index) const; + + /** * Copies the children of @p node to @p receiver. */ inline void copyChildren(const QXmlNodeModelIndex &node, diff --git a/src/xmlpatterns/acceltree/qacceltreebuilder.cpp b/src/xmlpatterns/acceltree/qacceltreebuilder.cpp index 5b16cc3..ddc118c 100644 --- a/src/xmlpatterns/acceltree/qacceltreebuilder.cpp +++ b/src/xmlpatterns/acceltree/qacceltreebuilder.cpp @@ -49,15 +49,17 @@ template AccelTreeBuilder::AccelTreeBuilder(const QUrl &docURI, const QUrl &baseURI, const NamePool::Ptr &np, - ReportContext *const context) : m_preNumber(-1) - , m_isPreviousAtomic(false) - , m_hasCharacters(false) - , m_isCharactersCompressed(false) - , m_namePool(np) - , m_document(new AccelTree(docURI, baseURI)) - , m_skippedDocumentNodes(0) - , m_documentURI(docURI) - , m_context(context) + ReportContext *const context, + Features features) : m_preNumber(-1) + , m_isPreviousAtomic(false) + , m_hasCharacters(false) + , m_isCharactersCompressed(false) + , m_namePool(np) + , m_document(new AccelTree(docURI, baseURI)) + , m_skippedDocumentNodes(0) + , m_documentURI(docURI) + , m_context(context) + , m_features(features) { Q_ASSERT(m_namePool); @@ -126,9 +128,18 @@ void AccelTreeBuilder::item(const Item &it) template void AccelTreeBuilder::startElement(const QXmlName &name) { + startElement(name, 1, 1); +} + +template +void AccelTreeBuilder::startElement(const QXmlName &name, qint64 line, qint64 column) +{ startStructure(); - m_document->basicData.append(AccelTree::BasicNodeData(currentDepth(), currentParent(), QXmlNodeModelIndex::Element, -1, name)); + AccelTree::BasicNodeData data(currentDepth(), currentParent(), QXmlNodeModelIndex::Element, -1, name); + m_document->basicData.append(data); + if (m_features & SourceLocationsFeature) + m_document->sourcePositions.insert(m_document->maximumPreNumber(), qMakePair(line, column)); ++m_preNumber; m_ancestors.push(m_preNumber); diff --git a/src/xmlpatterns/acceltree/qacceltreebuilder_p.h b/src/xmlpatterns/acceltree/qacceltreebuilder_p.h index 653eb85..91e8d68 100644 --- a/src/xmlpatterns/acceltree/qacceltreebuilder_p.h +++ b/src/xmlpatterns/acceltree/qacceltreebuilder_p.h @@ -90,15 +90,27 @@ namespace QPatternist typedef QExplicitlySharedDataPointer Ptr; /** + * Describes the memory relevant features the builder shall support. + */ + enum Feature + { + NoneFeature, ///< No special features are enabled. + SourceLocationsFeature = 1 ///< The accel tree builder will store source locations for each start element. + }; + Q_DECLARE_FLAGS(Features, Feature) + + /** * @param context may be @c null. */ AccelTreeBuilder(const QUrl &docURI, const QUrl &baseURI, const NamePool::Ptr &np, - ReportContext *const context); + ReportContext *const context, + Features features = NoneFeature); virtual void startDocument(); virtual void endDocument(); virtual void startElement(const QXmlName &name); + void startElement(const QXmlName &name, qint64 line, qint64 column); virtual void endElement(); virtual void attribute(const QXmlName &name, const QStringRef &value); virtual void characters(const QStringRef &ch); @@ -175,8 +187,13 @@ namespace QPatternist * a member. */ ReportContext *const m_context; + + Features m_features; }; + Q_DECLARE_OPERATORS_FOR_FLAGS(AccelTreeBuilder::Features) + Q_DECLARE_OPERATORS_FOR_FLAGS(AccelTreeBuilder::Features) + #include "qacceltreebuilder.cpp" } diff --git a/src/xmlpatterns/acceltree/qacceltreeresourceloader.cpp b/src/xmlpatterns/acceltree/qacceltreeresourceloader.cpp index 4a5c219..7c3d2c0 100644 --- a/src/xmlpatterns/acceltree/qacceltreeresourceloader.cpp +++ b/src/xmlpatterns/acceltree/qacceltreeresourceloader.cpp @@ -46,7 +46,6 @@ #include -#include "qacceltreebuilder_p.h" #include "qatomicstring_p.h" #include "qautoptr_p.h" #include "qcommonsequencetypes_p.h" @@ -57,14 +56,12 @@ QT_BEGIN_NAMESPACE using namespace QPatternist; -static inline uint qHash(const QUrl &uri) -{ - return qHash(uri.toString()); -} - AccelTreeResourceLoader::AccelTreeResourceLoader(const NamePool::Ptr &np, - const NetworkAccessDelegator::Ptr &manager) : m_namePool(np) - , m_networkAccessDelegator(manager) + const NetworkAccessDelegator::Ptr &manager, + AccelTreeBuilder::Features features) + : m_namePool(np) + , m_networkAccessDelegator(manager) + , m_features(features) { Q_ASSERT(m_namePool); Q_ASSERT(m_networkAccessDelegator); @@ -74,7 +71,7 @@ bool AccelTreeResourceLoader::retrieveDocument(const QUrl &uri, const ReportContext::Ptr &context) { Q_ASSERT(uri.isValid()); - AccelTreeBuilder builder(uri, uri, m_namePool, context.data()); + AccelTreeBuilder builder(uri, uri, m_namePool, context.data(), m_features); const AutoPtr reply(load(uri, m_networkAccessDelegator, context)); @@ -88,18 +85,35 @@ bool AccelTreeResourceLoader::retrieveDocument(const QUrl &uri, return success; } +bool AccelTreeResourceLoader::retrieveDocument(QIODevice *source, const QUrl &documentUri, const ReportContext::Ptr &context) +{ + Q_ASSERT(source); + Q_ASSERT(source->isReadable()); + Q_ASSERT(documentUri.isValid()); + + AccelTreeBuilder builder(documentUri, documentUri, m_namePool, context.data(), m_features); + + bool success = false; + success = streamToReceiver(source, &builder, m_namePool, context, documentUri); + + m_loadedDocuments.insert(documentUri, builder.builtDocument()); + + return success; +} + QNetworkReply *AccelTreeResourceLoader::load(const QUrl &uri, const NetworkAccessDelegator::Ptr &networkDelegator, - const ReportContext::Ptr &context) + const ReportContext::Ptr &context, ErrorHandling errorHandling) { return load(uri, networkDelegator->managerFor(uri), - context); + context, errorHandling); } QNetworkReply *AccelTreeResourceLoader::load(const QUrl &uri, QNetworkAccessManager *const networkManager, - const ReportContext::Ptr &context) + const ReportContext::Ptr &context, ErrorHandling errorHandling) + { Q_ASSERT(networkManager); Q_ASSERT(uri.isValid()); @@ -120,7 +134,7 @@ QNetworkReply *AccelTreeResourceLoader::load(const QUrl &uri, const QSourceLocation location(uri); - if(context) + if(context && (errorHandling == FailOnError)) context->error(errorMessage, ReportContext::FODC0002, location); return 0; @@ -130,7 +144,7 @@ QNetworkReply *AccelTreeResourceLoader::load(const QUrl &uri, } bool AccelTreeResourceLoader::streamToReceiver(QIODevice *const dev, - QAbstractXmlReceiver *const receiver, + AccelTreeBuilder *const receiver, const NamePool::Ptr &np, const ReportContext::Ptr &context, const QUrl &uri) @@ -154,7 +168,7 @@ bool AccelTreeResourceLoader::streamToReceiver(QIODevice *const dev, { /* Send the name. */ receiver->startElement(np->allocateQName(reader.namespaceUri().toString(), reader.name().toString(), - reader.prefix().toString())); + reader.prefix().toString()), reader.lineNumber(), reader.columnNumber()); /* Send namespace declarations. */ const QXmlStreamNamespaceDeclarations &nss = reader.namespaceDeclarations(); @@ -263,6 +277,22 @@ Item AccelTreeResourceLoader::openDocument(const QUrl &uri, } } +Item AccelTreeResourceLoader::openDocument(QIODevice *source, const QUrl &documentUri, + const ReportContext::Ptr &context) +{ + const AccelTree::Ptr doc(m_loadedDocuments.value(documentUri)); + + if(doc) + return doc->root(QXmlNodeModelIndex()); /* Pass in dummy object. We know AccelTree doesn't use it. */ + else + { + if(retrieveDocument(source, documentUri, context)) + return m_loadedDocuments.value(documentUri)->root(QXmlNodeModelIndex()); /* Pass in dummy object. We know AccelTree doesn't use it. */ + else + return Item(); + } +} + SequenceType::Ptr AccelTreeResourceLoader::announceDocument(const QUrl &uri, const Usage) { // TODO deal with the usage thingy diff --git a/src/xmlpatterns/acceltree/qacceltreeresourceloader_p.h b/src/xmlpatterns/acceltree/qacceltreeresourceloader_p.h index 863fd65..56f547a 100644 --- a/src/xmlpatterns/acceltree/qacceltreeresourceloader_p.h +++ b/src/xmlpatterns/acceltree/qacceltreeresourceloader_p.h @@ -52,12 +52,12 @@ #ifndef Patternist_AccelTreeResourceLoader_H #define Patternist_AccelTreeResourceLoader_H -#include #include #include #include "qabstractxmlreceiver.h" #include "qacceltree_p.h" +#include "qacceltreebuilder_p.h" #include "qdeviceresourceloader_p.h" #include "qnamepool_p.h" #include "qnetworkaccessdelegator_p.h" @@ -115,13 +115,25 @@ namespace QPatternist { public: /** + * Describes the behaviour of the resource loader in case of an + * error. + */ + enum ErrorHandling + { + FailOnError, ///< The resource loader will report the error via the report context. + ContinueOnError ///< The resource loader will report no error and return an empty QNetworkReply. + }; + + /** * AccelTreeResourceLoader does not own @p context. */ AccelTreeResourceLoader(const NamePool::Ptr &np, - const NetworkAccessDelegator::Ptr &networkDelegator); + const NetworkAccessDelegator::Ptr &networkDelegator, AccelTreeBuilder::Features = AccelTreeBuilder::NoneFeature); virtual Item openDocument(const QUrl &uri, const ReportContext::Ptr &context); + virtual Item openDocument(QIODevice *source, const QUrl &documentUri, + const ReportContext::Ptr &context); virtual SequenceType::Ptr announceDocument(const QUrl &uri, const Usage usageHint); virtual bool isDocumentAvailable(const QUrl &uri); @@ -133,7 +145,6 @@ namespace QPatternist const ReportContext::Ptr &context, const SourceLocationReflection *const where); - /** * @short Helper function that do NetworkAccessDelegator::get(), but * does it blocked. @@ -149,14 +160,14 @@ namespace QPatternist */ static QNetworkReply *load(const QUrl &uri, QNetworkAccessManager *const networkManager, - const ReportContext::Ptr &context); + const ReportContext::Ptr &context, ErrorHandling handling = FailOnError); /** * @overload */ static QNetworkReply *load(const QUrl &uri, const NetworkAccessDelegator::Ptr &networkDelegator, - const ReportContext::Ptr &context); + const ReportContext::Ptr &context, ErrorHandling handling = FailOnError); /** * @short Returns the URIs this AccelTreeResourceLoader has loaded @@ -165,14 +176,17 @@ namespace QPatternist virtual QSet deviceURIs() const; virtual void clear(const QUrl &uri); + private: static bool streamToReceiver(QIODevice *const dev, - QAbstractXmlReceiver *const receiver, + AccelTreeBuilder *const receiver, const NamePool::Ptr &np, const ReportContext::Ptr &context, const QUrl &uri); bool retrieveDocument(const QUrl &uri, const ReportContext::Ptr &context); + bool retrieveDocument(QIODevice *source, const QUrl &documentUri, + const ReportContext::Ptr &context); /** * If @p context is @c null, no error reporting should be done. */ @@ -185,6 +199,7 @@ namespace QPatternist const NamePool::Ptr m_namePool; const NetworkAccessDelegator::Ptr m_networkAccessDelegator; QHash, QString> m_unparsedTexts; + AccelTreeBuilder::Features m_features; }; } diff --git a/src/xmlpatterns/api/api.pri b/src/xmlpatterns/api/api.pri index a0298f2..9fcc2f5 100644 --- a/src/xmlpatterns/api/api.pri +++ b/src/xmlpatterns/api/api.pri @@ -3,11 +3,13 @@ HEADERS += $$PWD/qabstractxmlforwarditerator_p.h \ $$PWD/qabstracturiresolver.h \ $$PWD/qabstractxmlnodemodel.h \ $$PWD/qabstractxmlnodemodel_p.h \ + $$PWD/qabstractxmlpullprovider_p.h \ $$PWD/qabstractxmlreceiver.h \ $$PWD/qabstractxmlreceiver_p.h \ $$PWD/qdeviceresourceloader_p.h \ $$PWD/qiodevicedelegate_p.h \ $$PWD/qnetworkaccessdelegator_p.h \ + $$PWD/qpullbridge_p.h \ $$PWD/qresourcedelegator_p.h \ $$PWD/qsimplexmlnodemodel.h \ $$PWD/qsourcelocation.h \ @@ -20,6 +22,10 @@ HEADERS += $$PWD/qabstractxmlforwarditerator_p.h \ $$PWD/qxmlquery_p.h \ $$PWD/qxmlresultitems.h \ $$PWD/qxmlresultitems_p.h \ + $$PWD/qxmlschema.h \ + $$PWD/qxmlschema_p.h \ + $$PWD/qxmlschemavalidator.h \ + $$PWD/qxmlschemavalidator_p.h \ $$PWD/qxmlserializer.h \ $$PWD/qxmlserializer_p.h \ $$PWD/../../../tools/xmlpatterns/qcoloringmessagehandler_p.h \ @@ -29,9 +35,11 @@ SOURCES += $$PWD/qvariableloader.cpp \ $$PWD/qabstractmessagehandler.cpp \ $$PWD/qabstracturiresolver.cpp \ $$PWD/qabstractxmlnodemodel.cpp \ + $$PWD/qabstractxmlpullprovider.cpp \ $$PWD/qabstractxmlreceiver.cpp \ $$PWD/qiodevicedelegate.cpp \ $$PWD/qnetworkaccessdelegator.cpp \ + $$PWD/qpullbridge.cpp \ $$PWD/qresourcedelegator.cpp \ $$PWD/qsimplexmlnodemodel.cpp \ $$PWD/qsourcelocation.cpp \ @@ -41,6 +49,9 @@ SOURCES += $$PWD/qvariableloader.cpp \ $$PWD/qxmlnamepool.cpp \ $$PWD/qxmlquery.cpp \ $$PWD/qxmlresultitems.cpp \ + $$PWD/qxmlschema.cpp \ + $$PWD/qxmlschema_p.cpp \ + $$PWD/qxmlschemavalidator.cpp \ $$PWD/qxmlserializer.cpp \ $$PWD/../../../tools/xmlpatterns/qcoloringmessagehandler.cpp \ $$PWD/../../../tools/xmlpatterns/qcoloroutput.cpp diff --git a/src/xmlpatterns/api/qabstractxmlnodemodel.cpp b/src/xmlpatterns/api/qabstractxmlnodemodel.cpp index 0caa8c4..f535ec8 100644 --- a/src/xmlpatterns/api/qabstractxmlnodemodel.cpp +++ b/src/xmlpatterns/api/qabstractxmlnodemodel.cpp @@ -1666,4 +1666,20 @@ void QAbstractXmlNodeModel::copyNodeTo(const QXmlNodeModelIndex &node, "This function is not expected to be called."); } +/*! + Returns the source location for the object with the given \a index + or a default constructed QSourceLocation in case no location + information is available. + + \since TODO + */ +QSourceLocation QAbstractXmlNodeModel::sourceLocation(const QXmlNodeModelIndex &index) const +{ + // TODO: make this method virtual in Qt5 to allow source location support in custom models + if (d_ptr) + return d_ptr->sourceLocation(index); + else + return QSourceLocation(); +} + QT_END_NAMESPACE diff --git a/src/xmlpatterns/api/qabstractxmlnodemodel.h b/src/xmlpatterns/api/qabstractxmlnodemodel.h index 6c9574c..1d860a3 100644 --- a/src/xmlpatterns/api/qabstractxmlnodemodel.h +++ b/src/xmlpatterns/api/qabstractxmlnodemodel.h @@ -56,6 +56,7 @@ QT_MODULE(XmlPatterns) class QAbstractXmlNodeModel; class QAbstractXmlNodeModelPrivate; class QAbstractXmlReceiver; +class QSourceLocation; class QUrl; class QXmlName; class QXmlNodeModelIndex; @@ -69,6 +70,7 @@ namespace QPatternist class DynamicContext; class Item; class ItemType; + class XsdValidatedXmlNodeModel; template class ItemMappingIterator; template class SequenceMappingIterator; typedef QExplicitlySharedDataPointer ItemTypePtr; @@ -315,6 +317,8 @@ public: QAbstractXmlReceiver *const receiver, const NodeCopySettings &) const; + QSourceLocation sourceLocation(const QXmlNodeModelIndex &index) const; + protected: virtual QXmlNodeModelIndex nextFromSimpleAxis(SimpleAxis axis, const QXmlNodeModelIndex &origin) const = 0; @@ -343,6 +347,7 @@ protected: private: friend class QPatternist::ItemMappingIterator >; friend class QPatternist::SequenceMappingIterator; + friend class QPatternist::XsdValidatedXmlNodeModel; inline QExplicitlySharedDataPointer > mapToSequence(const QXmlNodeModelIndex &ni, const QExplicitlySharedDataPointer &) const; diff --git a/src/xmlpatterns/api/qabstractxmlnodemodel_p.h b/src/xmlpatterns/api/qabstractxmlnodemodel_p.h index 16ce613..0ab1b26 100644 --- a/src/xmlpatterns/api/qabstractxmlnodemodel_p.h +++ b/src/xmlpatterns/api/qabstractxmlnodemodel_p.h @@ -52,6 +52,9 @@ #ifndef QABSTRACTXMLNODEMODEL_P_H #define QABSTRACTXMLNODEMODEL_P_H +#include "qabstractxmlnodemodel.h" +#include "qsourcelocation.h" + QT_BEGIN_HEADER QT_BEGIN_NAMESPACE @@ -62,6 +65,13 @@ public: virtual ~QAbstractXmlNodeModelPrivate() { } + + virtual QSourceLocation sourceLocation(const QXmlNodeModelIndex &index) const + { + Q_UNUSED(index); + + return QSourceLocation(); + } }; QT_END_NAMESPACE diff --git a/src/xmlpatterns/api/qabstractxmlpullprovider.cpp b/src/xmlpatterns/api/qabstractxmlpullprovider.cpp new file mode 100644 index 0000000..a80604b --- /dev/null +++ b/src/xmlpatterns/api/qabstractxmlpullprovider.cpp @@ -0,0 +1,147 @@ +/**************************************************************************** +** +** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the $MODULE$ of the Qt Toolkit. +** +** $TROLLTECH_DUAL_LICENSE$ +** +****************************************************************************/ + +#include + +#include "qxmlname.h" +#include "qnamepool_p.h" +#include "qabstractxmlpullprovider_p.h" + +QT_BEGIN_NAMESPACE + +using namespace QPatternist; + +// TODO have example where query selects, and the events for the result are indented + +/*! + \internal + \class AbstractXmlPullProvider + \brief The AbstractXmlPullProvider class provides a pull-based stream interface for the XPath Data Model. + \reentrant + \ingroup xml-tools + + AbstractXmlPullProvider allows a stream of items from the XPath Data Model -- essentially XML -- + to be iterated over. The subclass of AbstractXmlPullProvider provides the events, and the + user calling next() and so on, consumes them. AbstractXmlPullProvider can be considered + a forward-only, non-reversible iterator. + + Note that the content the events describes, are not necessarily a well-formed XML document, but + rather an instance of the XPath Data model, to be specific. For instance, maybe a pull provider + returns two atomic values, followed by an element tree, and at the end two document nodes. + + If you are subclassing AbstractXmlPullProvider, be careful to correctly implement + the behaviors, as described for the individual members and events. + + \sa AbstractXmlPullProvider::Event + */ + +/*! + \enum AbstractXmlPullProvider::Event + \value StartOfInput The value AbstractXmlPullProvider::current() returns before the first call to next(). + \value AtomicValue an atomic value such as an \c xs:integer, \c xs:hexBinary, or \c xs:dateTime. Atomic values + can only be top level items. + \value StartDocument Signals the start of a document node. Note that a AbstractXmlPullProvider can provide + a sequence of document nodes. + \value EndDocument Signals the end of a document node. StartDocument and EndDocument are always balanced + and always top-level events. For instance, StartDocument can never appear after any StartElement + events that hasn't been balanced by the corresponding amount of EndElement events. + \value StartElement Signals an element start tag. + \value EndElement Signals the end of an element. StartElement and EndElement events are always balanced. + \value Text Signals a text node. Adjacent text nodes cannot occur. + \value ProcessingInstruction A processing instruction. Its name is returned from name(), and its value in stringValue(). + \value Comment a comment node. Its value can be retrieved with stingValue(). + \value Attribute Signals an attribute node. Attribute events can only appear after Namespace events, or + if no such are sent, after the StartElement. In addition they must appear sequentially, + and each name must be unique. The ordering of attribute events is undefined and insignificant. + \value Namespace Signals a namespace binding. They occur very infrequently and are not needed for attributes + and elements. Namespace events can only appear after the StartElement event. The + ordering of namespace events is undefined and insignificant. + \value EndOfInput When next() is called after the last event, EndOfInput is returned. + + \sa AbstractXmlPullProvider::current() + */ + +/*! + Constucts a AbstractXmlPullProvider instance. + */ +AbstractXmlPullProvider::AbstractXmlPullProvider() +{ +} + +/*! + Destructs this AbstractXmlPullProvider. + */ +AbstractXmlPullProvider::~AbstractXmlPullProvider() +{ +} + +/*! + \fn Event AbstractXmlPullProvider::next() = 0; + Advances this AbstractXmlPullProvider, and returns the new event. + + \sa current() + */ + +/*! + \fn Event AbstractXmlPullProvider::current() const = 0; + Returns the event that next() returned the last time it was called. It doesn't + alter this AbstractXmlPullProvider. + + current() may not modify this AbstractXmlPullProvider's state. Subsequent calls to current() + must return the same value. + + \sa AbstractXmlPullProvider::Event + */ + +/*! + \fn QName AbstractXmlPullProvider::name() const = 0; + If the current event is StartElement, + EndElement, ProcessingInstruction, Attribute, or Namespace, the node's name is returned. + + If the current event is ProcessingInstruction, + the processing instruction target is in in the local name. + + If the current event is Namespace, the name's namespace URI is the namespace, and + the local name is the prefix the name is binding to. + + In all other cases, an invalid QName is returned. + */ + +/*! + \fn QVariant AbstractXmlPullProvider::atomicValue() const = 0; + + If current() event is AtomicValue, the atomic value is returned as a QVariant. + In all other cases, this function returns a null QVariant. + */ + +/*! + \fn QString AbstractXmlPullProvider::stringValue() const = 0; + + If current() is Text, the text node's value is returned. + + If the current() event is Comment, its value is returned. The subclasser guarantees + it does not contain the string "-->". + + If the current() event is ProcessingInstruction, its data is returned. The subclasser + guarantees the data does not contain the string "?>". + + In other cases, it returns a default constructed string. + */ + +/*! + \fn QHash AbstractXmlPullProvider::attributes() = 0; + + If the current() is Element, the attributes of the element are returned, + an empty list of attributes otherwise. + */ + +QT_END_NAMESPACE + diff --git a/src/xmlpatterns/api/qabstractxmlpullprovider_p.h b/src/xmlpatterns/api/qabstractxmlpullprovider_p.h new file mode 100644 index 0000000..d05e649 --- /dev/null +++ b/src/xmlpatterns/api/qabstractxmlpullprovider_p.h @@ -0,0 +1,83 @@ +/**************************************************************************** +** +** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the $MODULE$ of the Qt Toolkit. +** +** $TROLLTECH_DUAL_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 QABSTRACTXMLPULLPROVIDER_H +#define QABSTRACTXMLPULLPROVIDER_H + +#include + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +class QXmlItem; +class QXmlName; +class QString; +class QVariant; +template class QHash; + +namespace QPatternist +{ + class AbstractXmlPullProviderPrivate; + + class AbstractXmlPullProvider + { + public: + AbstractXmlPullProvider(); + virtual ~AbstractXmlPullProvider(); + + enum Event + { + StartOfInput = 1, + AtomicValue = 1 << 1, + StartDocument = 1 << 2, + EndDocument = 1 << 3, + StartElement = 1 << 4, + EndElement = 1 << 5, + Text = 1 << 6, + ProcessingInstruction = 1 << 7, + Comment = 1 << 8, + Attribute = 1 << 9, + Namespace = 1 << 10, + EndOfInput = 1 << 11 + }; + + virtual Event next() = 0; + virtual Event current() const = 0; + virtual QXmlName name() const = 0; + virtual QVariant atomicValue() const = 0; + virtual QString stringValue() const = 0; + + virtual QHash attributes() = 0; + virtual QHash attributeItems() = 0; + + /* *** The functions below are internal. */ + private: + Q_DISABLE_COPY(AbstractXmlPullProvider) + AbstractXmlPullProviderPrivate *d; + }; +} + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif diff --git a/src/xmlpatterns/api/qpullbridge.cpp b/src/xmlpatterns/api/qpullbridge.cpp new file mode 100644 index 0000000..f347339 --- /dev/null +++ b/src/xmlpatterns/api/qpullbridge.cpp @@ -0,0 +1,202 @@ +/**************************************************************************** +** +** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the $MODULE$ of the Qt Toolkit. +** +** $TROLLTECH_DUAL_LICENSE$ +** +****************************************************************************/ + +#include + +#include "qabstractxmlnodemodel_p.h" +#include "qitemmappingiterator_p.h" +#include "qitem_p.h" +#include "qxmlname.h" +#include "qxmlquery_p.h" + +#include "qpullbridge_p.h" + +QT_BEGIN_NAMESPACE + +using namespace QPatternist; + +/*! + \brief Bridges a QPatternist::SequenceIterator to QAbstractXmlPullProvider. + \class QPatternist::PullBridge + \internal + \reentrant + \ingroup xml-tools + + The approach of this class is rather straight forward since QPatternist::SequenceIterator + and QAbstractXmlPullProvider are conceptually similar. While QPatternist::SequenceIterator only + delivers top level items(since it's not an event stream, it's a list of items), PullBridge + needs to recursively iterate the children of nodes too, which is achieved through the + stack m_iterators. + */ + +AbstractXmlPullProvider::Event PullBridge::next() +{ + m_index = m_iterators.top().second->next(); + + if(!m_index.isNull()) + { + Item item(m_index); + + if(item && item.isAtomicValue()) + m_current = AtomicValue; + else + { + Q_ASSERT(item.isNode()); + + switch(m_index.kind()) + { + case QXmlNodeModelIndex::Attribute: + { + m_current = Attribute; + break; + } + case QXmlNodeModelIndex::Comment: + { + m_current = Comment; + break; + } + case QXmlNodeModelIndex::Element: + { + m_iterators.push(qMakePair(StartElement, m_index.iterate(QXmlNodeModelIndex::AxisChild))); + m_current = StartElement; + break; + } + case QXmlNodeModelIndex::Document: + { + m_iterators.push(qMakePair(StartDocument, m_index.iterate(QXmlNodeModelIndex::AxisChild))); + m_current = StartDocument; + break; + } + case QXmlNodeModelIndex::Namespace: + { + m_current = Namespace; + break; + } + case QXmlNodeModelIndex::ProcessingInstruction: + { + m_current = ProcessingInstruction; + break; + } + case QXmlNodeModelIndex::Text: + { + m_current = Text; + break; + } + } + } + } + else + { + if(m_iterators.isEmpty()) + m_current = EndOfInput; + else + { + switch(m_iterators.top().first) + { + case StartOfInput: + { + m_current = EndOfInput; + break; + } + case StartElement: + { + m_current = EndElement; + m_iterators.pop(); + break; + } + case StartDocument: + { + m_current = EndDocument; + m_iterators.pop(); + break; + } + default: + { + Q_ASSERT_X(false, Q_FUNC_INFO, + "Invalid value."); + m_current = EndOfInput; + } + } + } + + } + + return m_current; +} + +AbstractXmlPullProvider::Event PullBridge::current() const +{ + return m_current; +} + +QXmlNodeModelIndex PullBridge::index() const +{ + return m_index; +} + +QSourceLocation PullBridge::sourceLocation() const +{ + return m_index.model()->sourceLocation(m_index); +} + +QXmlName PullBridge::name() const +{ + return m_index.name(); +} + +QVariant PullBridge::atomicValue() const +{ + return QVariant(); +} + +QString PullBridge::stringValue() const +{ + return QString(); +} + +QHash PullBridge::attributes() +{ + Q_ASSERT(m_current == StartElement); + + QHash attributes; + + QXmlNodeModelIndex::Iterator::Ptr it = m_index.iterate(QXmlNodeModelIndex::AxisAttribute); + QXmlNodeModelIndex index = it->next(); + while (!index.isNull()) { + const Item attribute(index); + attributes.insert(index.name(), index.stringValue()); + + index = it->next(); + } + + return attributes; +} + +QHash PullBridge::attributeItems() +{ + Q_ASSERT(m_current == StartElement); + + QHash attributes; + + QXmlNodeModelIndex::Iterator::Ptr it = m_index.iterate(QXmlNodeModelIndex::AxisAttribute); + QXmlNodeModelIndex index = it->next(); + while (!index.isNull()) { + const Item attribute(index); + attributes.insert(index.name(), QXmlItem(index)); + + index = it->next(); + } + + return attributes; +} + +QT_END_NAMESPACE + diff --git a/src/xmlpatterns/api/qpullbridge_p.h b/src/xmlpatterns/api/qpullbridge_p.h new file mode 100644 index 0000000..823d27b --- /dev/null +++ b/src/xmlpatterns/api/qpullbridge_p.h @@ -0,0 +1,73 @@ +/**************************************************************************** +** +** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the $MODULE$ of the Qt Toolkit. +** +** $TROLLTECH_DUAL_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_PULLBRIDGE_P_H +#define PATTERNIST_PULLBRIDGE_P_H + +#include +#include + +#include "qabstractxmlforwarditerator_p.h" +#include "qabstractxmlpullprovider_p.h" +#include "qitem_p.h" + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +namespace QPatternist +{ + class PullBridge : public AbstractXmlPullProvider + { + public: + inline PullBridge(const QXmlNodeModelIndex::Iterator::Ptr &it) : m_current(StartOfInput) + { + Q_ASSERT(it); + m_iterators.push(qMakePair(StartOfInput, it)); + } + + virtual Event next(); + virtual Event current() const; + virtual QXmlName name() const; + /** + * Returns always an empty QVariant. + */ + virtual QVariant atomicValue() const; + virtual QString stringValue() const; + virtual QHash attributes(); + virtual QHash attributeItems(); + + QXmlNodeModelIndex index() const; + QSourceLocation sourceLocation() const; + + private: + typedef QStack > IteratorStack; + IteratorStack m_iterators; + QXmlNodeModelIndex m_index; + Event m_current; + }; +} + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif diff --git a/src/xmlpatterns/api/qresourcedelegator.cpp b/src/xmlpatterns/api/qresourcedelegator.cpp index 9d43419..fceef30 100644 --- a/src/xmlpatterns/api/qresourcedelegator.cpp +++ b/src/xmlpatterns/api/qresourcedelegator.cpp @@ -45,14 +45,6 @@ QT_BEGIN_NAMESPACE using namespace QPatternist; -/** - * Duplicated in qacceltreeresourceloader.cpp. - */ -static inline uint qHash(const QUrl &uri) -{ - return qHash(uri.toString()); -} - bool ResourceDelegator::isUnparsedTextAvailable(const QUrl &uri, const QString &encoding) { diff --git a/src/xmlpatterns/api/qxmlnamepool.cpp b/src/xmlpatterns/api/qxmlnamepool.cpp index 2337f8d..11274ab 100644 --- a/src/xmlpatterns/api/qxmlnamepool.cpp +++ b/src/xmlpatterns/api/qxmlnamepool.cpp @@ -96,6 +96,10 @@ QXmlNamePool::~QXmlNamePool() { } +QXmlNamePool::QXmlNamePool(QPatternist::NamePool *namePool) : d(QExplicitlySharedDataPointer(namePool)) +{ +} + /*! Assigns the \a other name pool to this one. */ diff --git a/src/xmlpatterns/api/qxmlnamepool.h b/src/xmlpatterns/api/qxmlnamepool.h index 3c1e112..87856ee 100644 --- a/src/xmlpatterns/api/qxmlnamepool.h +++ b/src/xmlpatterns/api/qxmlnamepool.h @@ -54,6 +54,8 @@ QT_MODULE(XmlPatterns) namespace QPatternist { class NamePool; + class XsdSchemaParser; + class XsdValidatingInstanceReader; } namespace QPatternistSDK @@ -73,10 +75,15 @@ public: QXmlNamePool &operator=(const QXmlNamePool &other); private: + QXmlNamePool(QPatternist::NamePool *namePool); friend class QXmlQueryPrivate; friend class QXmlQuery; + friend class QXmlSchemaPrivate; + friend class QXmlSchemaValidatorPrivate; friend class QXmlSerializerPrivate; friend class QXmlName; + friend class QPatternist::XsdSchemaParser; + friend class QPatternist::XsdValidatingInstanceReader; friend class QPatternistSDK::Global; QExplicitlySharedDataPointer d; }; diff --git a/src/xmlpatterns/api/qxmlquery.cpp b/src/xmlpatterns/api/qxmlquery.cpp index 5f9d87d..423da3e 100644 --- a/src/xmlpatterns/api/qxmlquery.cpp +++ b/src/xmlpatterns/api/qxmlquery.cpp @@ -231,6 +231,18 @@ QT_BEGIN_NAMESPACE \value XQuery10 XQuery 1.0. \value XSLT20 XSLT 2.0 + \omitvalue XmlSchema11IdentityConstraintSelector The selector, the restricted + XPath pattern found in W3C XML Schema 1.1 for uniqueness + contraints. Apart from restricting the syntax, the type check stage + for the expression assumes a sequence of nodes to be the focus. + \omitvalue XmlSchema11IdentityConstraintField The field, the restricted + XPath pattern found in W3C XML Schema 1.1 for uniqueness + contraints. Apart from restricting the syntax, the type check stage + for the expression assumes a sequence of nodes to be the focus. + \omitvalue XPath20 Signifies XPath 2.0. Has no effect in the public API, it's + used internally. As With XmlSchema11IdentityConstraintSelector and + XmlSchema11IdentityConstraintField, the type check stage + for the expression assumes a sequence of nodes to be the focus. \sa setQuery() */ diff --git a/src/xmlpatterns/api/qxmlquery.h b/src/xmlpatterns/api/qxmlquery.h index 138819c..c9f949e 100644 --- a/src/xmlpatterns/api/qxmlquery.h +++ b/src/xmlpatterns/api/qxmlquery.h @@ -71,6 +71,8 @@ namespace QPatternistSDK namespace QPatternist { + class XsdSchemaParser; + class XsdValidatingInstanceReader; class VariableLoader; }; @@ -79,8 +81,11 @@ class Q_XMLPATTERNS_EXPORT QXmlQuery public: enum QueryLanguage { - XQuery10 = 1, - XSLT20 = 2 + XQuery10 = 1, + XSLT20 = 2, + XmlSchema11IdentityConstraintSelector = 1024, + XmlSchema11IdentityConstraintField = 2048, + XPath20 = 4096 }; QXmlQuery(); @@ -135,6 +140,8 @@ private: friend class QXmlName; friend class QXmlSerializer; friend class QPatternistSDK::TestCase; + friend class QPatternist::XsdSchemaParser; + friend class QPatternist::XsdValidatingInstanceReader; friend class QPatternist::VariableLoader; template friend bool setFocusHelper(QXmlQuery *const queryInstance, const TInputType &focusValue); diff --git a/src/xmlpatterns/api/qxmlquery_p.h b/src/xmlpatterns/api/qxmlquery_p.h index c8ed441..7f58f97 100644 --- a/src/xmlpatterns/api/qxmlquery_p.h +++ b/src/xmlpatterns/api/qxmlquery_p.h @@ -142,13 +142,10 @@ public: if(!m_functionFactory) { - if(queryLanguage == QXmlQuery::XQuery10) - m_functionFactory = QPatternist::FunctionFactoryCollection::xpath20Factory(namePool.d); - else - { - Q_ASSERT(queryLanguage == QXmlQuery::XSLT20); + if(queryLanguage == QXmlQuery::XSLT20) m_functionFactory = QPatternist::FunctionFactoryCollection::xslt20Factory(namePool.d); - } + else + m_functionFactory = QPatternist::FunctionFactoryCollection::xpath20Factory(namePool.d); } const QPatternist::GenericStaticContext::Ptr genericStaticContext(new QPatternist::GenericStaticContext(namePool.d, @@ -164,6 +161,14 @@ public: if(!contextItem.isNull()) m_staticContext = QPatternist::StaticContext::Ptr(new QPatternist::StaticFocusContext(QPatternist::AtomicValue::qtToXDMType(contextItem), m_staticContext)); + else if( queryLanguage == QXmlQuery::XmlSchema11IdentityConstraintField + || queryLanguage == QXmlQuery::XmlSchema11IdentityConstraintSelector + || queryLanguage == QXmlQuery::XPath20) + m_staticContext = QPatternist::StaticContext::Ptr(new QPatternist::StaticFocusContext(QPatternist::BuiltinTypes::node, m_staticContext)); + + for (int i = 0; i < m_additionalNamespaceBindings.count(); ++i) { + m_staticContext->namespaceBindings()->addBinding(m_additionalNamespaceBindings.at(i)); + } return m_staticContext; } @@ -278,6 +283,11 @@ public: return m_expr; } + inline void addAdditionalNamespaceBinding(const QXmlName &binding) + { + m_additionalNamespaceBindings.append(binding); + } + QXmlNamePool namePool; QPointer messageHandler; /** @@ -321,6 +331,8 @@ public: QPatternist::SequenceType::Ptr m_requiredType; QPatternist::FunctionFactory::Ptr m_functionFactory; QPatternist::NetworkAccessDelegator::Ptr m_networkAccessDelegator; + + QList m_additionalNamespaceBindings; }; QT_END_NAMESPACE diff --git a/src/xmlpatterns/api/qxmlschema.cpp b/src/xmlpatterns/api/qxmlschema.cpp new file mode 100644 index 0000000..55b96cd --- /dev/null +++ b/src/xmlpatterns/api/qxmlschema.cpp @@ -0,0 +1,229 @@ +/**************************************************************************** +** +** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the $MODULE$ of the Qt Toolkit. +** +** $TROLLTECH_DUAL_LICENSE$ +** +****************************************************************************/ + +#include "qxmlschema.h" +#include "qxmlschema_p.h" + +#include +#include + +/*! + \class QXmlSchema + + \brief The QXmlSchema class provides loading and validation of a W3C XML Schema. + + \reentrant + \since 4.X + \ingroup xml-tools + + The QXmlSchema class loads, compiles and validates W3C XML Schema files + that can be used further for validation of XML instance documents via + \l{QXmlSchemaValidator}. +*/ + +/*! + Constructs an invalid, empty schema that cannot be used until + setSchema() is called. + */ +QXmlSchema::QXmlSchema() + : d(new QXmlSchemaPrivate(QXmlNamePool())) +{ +} + +/*! + Constructs a QXmlSchema that is a copy of \a other. The new + instance will share resources with the existing schema + to the extent possible. + */ +QXmlSchema::QXmlSchema(const QXmlSchema &other) + : d(other.d) +{ +} + +/*! + Destroys this QXmlSchema. + */ +QXmlSchema::~QXmlSchema() +{ +} + +/*! + Sets this QXmlSchema to a schema loaded from the \a source + URI. + */ +void QXmlSchema::load(const QUrl &source) +{ + d->load(source, QString()); +} + +/*! + Sets this QXmlSchema to a schema read from the \a source + device. The device must have been opened with at least + QIODevice::ReadOnly. + + \a documentUri represents the schema obtained from the \a source + device. It is the base URI of the schema, that is used + internally to resolve relative URIs that appear in the schema, and + for message reporting. + + If \a source is \c null or not readable, or if \a documentUri is not + a valid URI, behavior is undefined. + \sa isValid() + */ +void QXmlSchema::load(QIODevice *source, const QUrl &documentUri) +{ + d->load(source, documentUri, QString()); +} + +/*! + Sets this QXmlSchema to a schema read from the \a data + + \a documentUri represents the schema obtained from the \a data. + It is the base URI of the schema, that is used internally to + resolve relative URIs that appear in the schema, and + for message reporting. + + If \a documentUri is not a valid URI, behavior is undefined. + \sa isValid() + */ +void QXmlSchema::load(const QByteArray &data, const QUrl &documentUri) +{ + d->load(data, documentUri, QString()); +} + +/*! + Returns true if this schema is valid. Examples of invalid schemas + are ones that contain syntax errors or that do not conform the + W3C XML Schema specification. + */ +bool QXmlSchema::isValid() const +{ + return d->isValid(); +} + +/*! + Returns the name pool used by this QXmlSchema for constructing \l + {QXmlName} {names}. There is no setter for the name pool, because + mixing name pools causes errors due to name confusion. + */ +QXmlNamePool QXmlSchema::namePool() const +{ + return d->namePool(); +} + +/*! + Returns the document URI of the schema or an empty URI if no + schema has been set. + */ +QUrl QXmlSchema::documentUri() const +{ + return d->documentUri(); +} + +/*! + Changes the \l {QAbstractMessageHandler}{message handler} for this + QXmlSchema to \a handler. The schema sends all compile and + validation messages to this message handler. QXmlSchema does not take + ownership of \a handler. + + Normally, the default message handler is sufficient. It writes + compile and validation messages to \e stderr. The default message + handler includes color codes if \e stderr can render colors. + + When QXmlSchema calls QAbstractMessageHandler::message(), + the arguments are as follows: + + \table + \header + \o message() argument + \o Semantics + \row + \o QtMsgType type + \o Only QtWarningMsg and QtFatalMsg are used. The former + identifies a warning, while the latter identifies an error. + \row + \o const QString & description + \o An XHTML document which is the actual message. It is translated + into the current language. + \row + \o const QUrl &identifier + \o Identifies the error with a URI, where the fragment is + the error code, and the rest of the URI is the error namespace. + \row + \o const QSourceLocation & sourceLocation + \o Identifies where the error occurred. + \endtable + + */ +void QXmlSchema::setMessageHandler(QAbstractMessageHandler *handler) +{ + d->setMessageHandler(handler); +} + +/*! + Returns the message handler that handles compile and validation + messages for this QXmlSchema. + */ +QAbstractMessageHandler *QXmlSchema::messageHandler() const +{ + return d->messageHandler(); +} + +/*! + Sets the URI resolver to \a resolver. QXmlSchema does not take + ownership of \a resolver. + + \sa uriResolver() + */ +void QXmlSchema::setUriResolver(QAbstractUriResolver *resolver) +{ + d->setUriResolver(resolver); +} + +/*! + Returns the schema's URI resolver. If no URI resolver has been set, + QtXmlPatterns will use the URIs in queries as they are. + + The URI resolver provides a level of abstraction, or \e{polymorphic + URIs}. A resolver can rewrite \e{logical} URIs to physical ones, or + it can translate obsolete or invalid URIs to valid ones. + + When QtXmlPatterns calls QAbstractUriResolver::resolve() the + absolute URI is the URI mandated by the schema specification, and the + relative URI is the URI specified by the user. + + \sa setUriResolver() + */ +QAbstractUriResolver *QXmlSchema::uriResolver() const +{ + return d->uriResolver(); +} + +/*! + Sets the network manager to \a manager. + QXmlSchema does not take ownership of \a manager. + + \sa networkAccessManager() + */ +void QXmlSchema::setNetworkAccessManager(QNetworkAccessManager *manager) +{ + d->setNetworkAccessManager(manager); +} + +/*! + Returns the network manager, or 0 if it has not been set. + + \sa setNetworkAccessManager() + */ +QNetworkAccessManager *QXmlSchema::networkAccessManager() const +{ + return d->networkAccessManager(); +} diff --git a/src/xmlpatterns/api/qxmlschema.h b/src/xmlpatterns/api/qxmlschema.h new file mode 100644 index 0000000..225cce2 --- /dev/null +++ b/src/xmlpatterns/api/qxmlschema.h @@ -0,0 +1,66 @@ +/**************************************************************************** +** +** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the $MODULE$ of the Qt Toolkit. +** +** $TROLLTECH_DUAL_LICENSE$ +** +****************************************************************************/ + +#ifndef QXMLSCHEMA_H +#define QXMLSCHEMA_H + +#include +#include + +QT_BEGIN_HEADER +QT_BEGIN_NAMESPACE + +QT_MODULE(XmlPatterns) + +class QAbstractMessageHandler; +class QAbstractUriResolver; +class QIODevice; +class QNetworkAccessManager; +class QUrl; +class QXmlNamePool; +class QXmlSchemaPrivate; + +class Q_XMLPATTERNS_EXPORT QXmlSchema +{ + friend class QXmlSchemaValidatorPrivate; + + public: + QXmlSchema(); + QXmlSchema(const QXmlSchema &other); + ~QXmlSchema(); + + void load(const QUrl &source); + void load(QIODevice *source, const QUrl &documentUri); + void load(const QByteArray &data, const QUrl &documentUri); + + bool isValid() const; + + QXmlNamePool namePool() const; + QUrl documentUri() const; + + void setMessageHandler(QAbstractMessageHandler *handler); + QAbstractMessageHandler *messageHandler() const; + + void setUriResolver(QAbstractUriResolver *resolver); + QAbstractUriResolver *uriResolver() const; + + void setNetworkAccessManager(QNetworkAccessManager *networkmanager); + QNetworkAccessManager *networkAccessManager() const; + + private: + QSharedDataPointer d; +}; + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif diff --git a/src/xmlpatterns/api/qxmlschema_p.cpp b/src/xmlpatterns/api/qxmlschema_p.cpp new file mode 100644 index 0000000..ebcccee --- /dev/null +++ b/src/xmlpatterns/api/qxmlschema_p.cpp @@ -0,0 +1,169 @@ +/**************************************************************************** +** +** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the $MODULE$ of the Qt Toolkit. +** +** $TROLLTECH_DUAL_LICENSE$ +** +****************************************************************************/ + +#include "qacceltreeresourceloader_p.h" +#include "qxmlschema.h" +#include "qxmlschema_p.h" + +#include +#include +#include + +QXmlSchemaPrivate::QXmlSchemaPrivate(const QXmlNamePool &namePool) + : m_namePool(namePool) + , m_userMessageHandler(0) + , m_uriResolver(0) + , m_userNetworkAccessManager(0) + , m_schemaContext(new QPatternist::XsdSchemaContext(m_namePool.d)) + , m_schemaParserContext(new QPatternist::XsdSchemaParserContext(m_namePool.d, m_schemaContext)) + , m_schemaIsValid(false) +{ + m_networkAccessManager = new QPatternist::ReferenceCountedValue(new QNetworkAccessManager()); + m_messageHandler = new QPatternist::ReferenceCountedValue(new QPatternist::ColoringMessageHandler()); +} + +QXmlSchemaPrivate::QXmlSchemaPrivate(const QPatternist::XsdSchemaContext::Ptr &schemaContext) + : m_namePool(QXmlNamePool(schemaContext->namePool().data())) + , m_userMessageHandler(0) + , m_uriResolver(0) + , m_userNetworkAccessManager(0) + , m_schemaContext(schemaContext) + , m_schemaParserContext(new QPatternist::XsdSchemaParserContext(m_namePool.d, m_schemaContext)) + , m_schemaIsValid(false) +{ + m_networkAccessManager = new QPatternist::ReferenceCountedValue(new QNetworkAccessManager()); + m_messageHandler = new QPatternist::ReferenceCountedValue(new QPatternist::ColoringMessageHandler()); +} + +QXmlSchemaPrivate::QXmlSchemaPrivate(const QXmlSchemaPrivate &other) + : QSharedData(other) +{ + m_namePool = other.m_namePool; + m_userMessageHandler = other.m_userMessageHandler; + m_uriResolver = other.m_uriResolver; + m_userNetworkAccessManager = other.m_userNetworkAccessManager; + m_messageHandler = other.m_messageHandler; + m_networkAccessManager = other.m_networkAccessManager; + + m_schemaContext = other.m_schemaContext; + m_schemaParserContext = other.m_schemaParserContext; + m_schemaIsValid = other.m_schemaIsValid; + m_documentUri = other.m_documentUri; +} + +void QXmlSchemaPrivate::load(const QUrl &source, const QString &targetNamespace) +{ + m_documentUri = source; + + m_schemaContext->setMessageHandler(messageHandler()); + m_schemaContext->setUriResolver(uriResolver()); + m_schemaContext->setNetworkAccessManager(networkAccessManager()); + + const QPatternist::AutoPtr reply(QPatternist::AccelTreeResourceLoader::load(source, m_schemaContext->networkAccessManager(), + m_schemaContext, QPatternist::AccelTreeResourceLoader::ContinueOnError)); + if (reply) + load(reply.data(), source, targetNamespace); +} + +void QXmlSchemaPrivate::load(const QByteArray &data, const QUrl &documentUri, const QString &targetNamespace) +{ + QByteArray localData(data); + + QBuffer buffer(&localData); + buffer.open(QIODevice::ReadOnly); + + load(&buffer, documentUri, targetNamespace); +} + +void QXmlSchemaPrivate::load(QIODevice *source, const QUrl &documentUri, const QString &targetNamespace) +{ + m_schemaParserContext = QPatternist::XsdSchemaParserContext::Ptr(new QPatternist::XsdSchemaParserContext(m_namePool.d, m_schemaContext)); + m_schemaIsValid = false; + + if (!source) { + qWarning("A null QIODevice pointer cannot be passed."); + return; + } + + if (!source->isReadable()) { + qWarning("The device must be readable."); + return; + } + + m_documentUri = documentUri; + m_schemaContext->setMessageHandler(messageHandler()); + m_schemaContext->setUriResolver(uriResolver()); + m_schemaContext->setNetworkAccessManager(networkAccessManager()); + + QPatternist::XsdSchemaParser parser(m_schemaContext, m_schemaParserContext, source); + parser.setDocumentURI(documentUri); + parser.setTargetNamespace(targetNamespace); + + try { + parser.parse(); + m_schemaParserContext->resolver()->resolve(); + + m_schemaIsValid = true; + } catch (QPatternist::Exception exception) { + m_schemaIsValid = false; + } +} + +bool QXmlSchemaPrivate::isValid() const +{ + return m_schemaIsValid; +} + +QXmlNamePool QXmlSchemaPrivate::namePool() const +{ + return m_namePool; +} + +QUrl QXmlSchemaPrivate::documentUri() const +{ + return m_documentUri; +} + +void QXmlSchemaPrivate::setMessageHandler(QAbstractMessageHandler *handler) +{ + m_userMessageHandler = handler; +} + +QAbstractMessageHandler *QXmlSchemaPrivate::messageHandler() const +{ + if (m_userMessageHandler) + return m_userMessageHandler; + + return m_messageHandler.data()->value; +} + +void QXmlSchemaPrivate::setUriResolver(QAbstractUriResolver *resolver) +{ + m_uriResolver = resolver; +} + +QAbstractUriResolver *QXmlSchemaPrivate::uriResolver() const +{ + return m_uriResolver; +} + +void QXmlSchemaPrivate::setNetworkAccessManager(QNetworkAccessManager *networkmanager) +{ + m_userNetworkAccessManager = networkmanager; +} + +QNetworkAccessManager *QXmlSchemaPrivate::networkAccessManager() const +{ + if (m_userNetworkAccessManager) + return m_userNetworkAccessManager; + + return m_networkAccessManager.data()->value; +} diff --git a/src/xmlpatterns/api/qxmlschema_p.h b/src/xmlpatterns/api/qxmlschema_p.h new file mode 100644 index 0000000..e625f1e --- /dev/null +++ b/src/xmlpatterns/api/qxmlschema_p.h @@ -0,0 +1,79 @@ +/**************************************************************************** +** +** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the $MODULE$ of the Qt Toolkit. +** +** $TROLLTECH_DUAL_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 QXMLSCHEMA_P_H +#define QXMLSCHEMA_P_H + +#include "qabstractmessagehandler.h" +#include "qabstracturiresolver.h" +#include "qautoptr_p.h" +#include "qcoloringmessagehandler_p.h" +#include "qreferencecountedvalue_p.h" + +#include "qxsdschemacontext_p.h" +#include "qxsdschemaparser_p.h" +#include "qxsdschemaparsercontext_p.h" + +#include +#include + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +class QXmlSchemaPrivate : public QSharedData +{ + public: + QXmlSchemaPrivate(const QXmlNamePool &namePool); + QXmlSchemaPrivate(const QPatternist::XsdSchemaContext::Ptr &schemaContext); + QXmlSchemaPrivate(const QXmlSchemaPrivate &other); + + void load(const QUrl &source, const QString &targetNamespace); + void load(QIODevice *source, const QUrl &documentUri, const QString &targetNamespace); + void load(const QByteArray &data, const QUrl &documentUri, const QString &targetNamespace); + bool isValid() const; + QXmlNamePool namePool() const; + QUrl documentUri() const; + void setMessageHandler(QAbstractMessageHandler *handler); + QAbstractMessageHandler *messageHandler() const; + void setUriResolver(QAbstractUriResolver *resolver); + QAbstractUriResolver *uriResolver() const; + void setNetworkAccessManager(QNetworkAccessManager *networkmanager); + QNetworkAccessManager *networkAccessManager() const; + + QXmlNamePool m_namePool; + QAbstractMessageHandler* m_userMessageHandler; + QAbstractUriResolver* m_uriResolver; + QNetworkAccessManager* m_userNetworkAccessManager; + QPatternist::ReferenceCountedValue::Ptr m_messageHandler; + QPatternist::ReferenceCountedValue::Ptr m_networkAccessManager; + + QPatternist::XsdSchemaContext::Ptr m_schemaContext; + QPatternist::XsdSchemaParserContext::Ptr m_schemaParserContext; + bool m_schemaIsValid; + QUrl m_documentUri; +}; + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif diff --git a/src/xmlpatterns/api/qxmlschemavalidator.cpp b/src/xmlpatterns/api/qxmlschemavalidator.cpp new file mode 100644 index 0000000..aa80537 --- /dev/null +++ b/src/xmlpatterns/api/qxmlschemavalidator.cpp @@ -0,0 +1,264 @@ +/**************************************************************************** +** +** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the $MODULE$ of the Qt Toolkit. +** +** $TROLLTECH_DUAL_LICENSE$ +** +****************************************************************************/ + +#include "qxmlschemavalidator.h" +#include "qxmlschemavalidator_p.h" + +#include "qacceltreeresourceloader_p.h" +#include "qxmlschema.h" +#include "qxmlschema_p.h" +#include "qxsdvalidatinginstancereader_p.h" + +#include +#include +#include + +/*! + \class QXmlSchemaValidator + + \brief The QXmlSchemaValidator class validates XML instance documents against a W3C XML Schema. + + \reentrant + \since 4.X + \ingroup xml-tools + + The QXmlSchemaValidator class loads, parses an XML instance document and validates it + against a W3C XML Schema that has been compiled with \l{QXmlSchema}. +*/ + +/*! + Constructs a schema validator that will use \a schema for validation. + */ +QXmlSchemaValidator::QXmlSchemaValidator(const QXmlSchema &schema) + : d(new QXmlSchemaValidatorPrivate(schema)) +{ +} + +/*! + Destroys this QXmlSchemaValidator. + */ +QXmlSchemaValidator::~QXmlSchemaValidator() +{ + delete d; +} + +/*! + Sets the \a schema that shall be used for further validation. + */ +void QXmlSchemaValidator::setSchema(const QXmlSchema &schema) +{ + d->setSchema(schema); +} + +/*! + Validates the XML instance document read from \a data with the + given \a documentUri against the schema. + + Returns \c true if the XML instance document is valid according the + schema, \c false otherwise. + */ +bool QXmlSchemaValidator::validate(const QByteArray &data, const QUrl &documentUri) +{ + QByteArray localData(data); + + QBuffer buffer(&localData); + buffer.open(QIODevice::ReadOnly); + + return validate(&buffer, documentUri); +} + +/*! + Validates the XML instance document read from \a source against the schema. + + Returns \c true if the XML instance document is valid according the + schema, \c false otherwise. + */ +bool QXmlSchemaValidator::validate(const QUrl &source) +{ + d->m_context->setMessageHandler(messageHandler()); + d->m_context->setUriResolver(uriResolver()); + d->m_context->setNetworkAccessManager(networkAccessManager()); + + const QPatternist::AutoPtr reply(QPatternist::AccelTreeResourceLoader::load(source, d->m_context->networkAccessManager(), + d->m_context, QPatternist::AccelTreeResourceLoader::ContinueOnError)); + if (reply) + return validate(reply.data(), source); + else + return false; +} + +/*! + Validates the XML instance document read from \a source with the + given \a documentUri against the schema. + + Returns \c true if the XML instance document is valid according the + schema, \c false otherwise. + */ +bool QXmlSchemaValidator::validate(QIODevice *source, const QUrl &documentUri) +{ + if (!source) { + qWarning("A null QIODevice pointer cannot be passed."); + return false; + } + + if (!source->isReadable()) { + qWarning("The device must be readable."); + return false; + } + + d->m_context->setMessageHandler(messageHandler()); + d->m_context->setUriResolver(uriResolver()); + d->m_context->setNetworkAccessManager(networkAccessManager()); + + QPatternist::NetworkAccessDelegator::Ptr delegator(new QPatternist::NetworkAccessDelegator(d->m_context->networkAccessManager(), + d->m_context->networkAccessManager())); + + QPatternist::AccelTreeResourceLoader loader(d->m_context->namePool(), delegator, QPatternist::AccelTreeBuilder::SourceLocationsFeature); + + QPatternist::Item item; + try { + item = loader.openDocument(source, documentUri, d->m_context); + } catch (QPatternist::Exception exception) { + return false; + } + + QXmlNodeModelIndex index = item.asNode(); + const QAbstractXmlNodeModel *model = item.asNode().model(); + + QPatternist::XsdValidatedXmlNodeModel *validatedModel = new QPatternist::XsdValidatedXmlNodeModel(model); + + QPatternist::XsdValidatingInstanceReader reader(validatedModel, documentUri, d->m_context); + if (d->m_schema) + reader.addSchema(d->m_schema, d->m_schemaDocumentUri); + try { + reader.read(); + } catch (QPatternist::Exception exception) { + return false; + } + + return true; +} + +/*! + Returns the name pool used by this QXmlSchemaValidator for constructing \l + {QXmlName} {names}. There is no setter for the name pool, because + mixing name pools causes errors due to name confusion. + */ +QXmlNamePool QXmlSchemaValidator::namePool() const +{ + return d->m_namePool; +} + +/*! + Changes the \l {QAbstractMessageHandler}{message handler} for this + QXmlSchemaValidator to \a handler. The schema validator sends all parsing and + validation messages to this message handler. QXmlSchemaValidator does not take + ownership of \a handler. + + Normally, the default message handler is sufficient. It writes + compile and validation messages to \e stderr. The default message + handler includes color codes if \e stderr can render colors. + + When QXmlSchemaValidator calls QAbstractMessageHandler::message(), + the arguments are as follows: + + \table + \header + \o message() argument + \o Semantics + \row + \o QtMsgType type + \o Only QtWarningMsg and QtFatalMsg are used. The former + identifies a warning, while the latter identifies an error. + \row + \o const QString & description + \o An XHTML document which is the actual message. It is translated + into the current language. + \row + \o const QUrl &identifier + \o Identifies the error with a URI, where the fragment is + the error code, and the rest of the URI is the error namespace. + \row + \o const QSourceLocation & sourceLocation + \o Identifies where the error occurred. + \endtable + + */ +void QXmlSchemaValidator::setMessageHandler(QAbstractMessageHandler *handler) +{ + d->m_userMessageHandler = handler; +} + +/*! + Returns the message handler that handles parsing and validation + messages for this QXmlSchemaValidator. + */ +QAbstractMessageHandler *QXmlSchemaValidator::messageHandler() const +{ + if (d->m_userMessageHandler) + return d->m_userMessageHandler; + + return d->m_messageHandler.data()->value; +} + +/*! + Sets the URI resolver to \a resolver. QXmlSchemaValidator does not take + ownership of \a resolver. + + \sa uriResolver() + */ +void QXmlSchemaValidator::setUriResolver(QAbstractUriResolver *resolver) +{ + d->m_uriResolver = resolver; +} + +/*! + Returns the schema's URI resolver. If no URI resolver has been set, + QtXmlPatterns will use the URIs in queries as they are. + + The URI resolver provides a level of abstraction, or \e{polymorphic + URIs}. A resolver can rewrite \e{logical} URIs to physical ones, or + it can translate obsolete or invalid URIs to valid ones. + + When QtXmlPatterns calls QAbstractUriResolver::resolve() the + absolute URI is the URI mandated by the schema specification, and the + relative URI is the URI specified by the user. + + \sa setUriResolver() + */ +QAbstractUriResolver *QXmlSchemaValidator::uriResolver() const +{ + return d->m_uriResolver; +} + +/*! + Sets the network manager to \a manager. + QXmlSchemaValidator does not take ownership of \a manager. + + \sa networkAccessManager() + */ +void QXmlSchemaValidator::setNetworkAccessManager(QNetworkAccessManager *manager) +{ + d->m_userNetworkAccessManager = manager; +} + +/*! + Returns the network manager, or 0 if it has not been set. + + \sa setNetworkAccessManager() + */ +QNetworkAccessManager *QXmlSchemaValidator::networkAccessManager() const +{ + if (d->m_userNetworkAccessManager) + return d->m_userNetworkAccessManager; + + return d->m_networkAccessManager.data()->value; +} diff --git a/src/xmlpatterns/api/qxmlschemavalidator.h b/src/xmlpatterns/api/qxmlschemavalidator.h new file mode 100644 index 0000000..e643995 --- /dev/null +++ b/src/xmlpatterns/api/qxmlschemavalidator.h @@ -0,0 +1,64 @@ +/**************************************************************************** +** +** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the $MODULE$ of the Qt Toolkit. +** +** $TROLLTECH_DUAL_LICENSE$ +** +****************************************************************************/ + +#ifndef QXMLSCHEMAVALIDATOR_H +#define QXMLSCHEMAVALIDATOR_H + +#include + +QT_BEGIN_HEADER +QT_BEGIN_NAMESPACE + +QT_MODULE(XmlPatterns) + +class QAbstractMessageHandler; +class QAbstractUriResolver; +class QIODevice; +class QNetworkAccessManager; +class QUrl; +class QXmlNamePool; +class QXmlSchema; +class QXmlSchemaValidatorPrivate; + +class Q_XMLPATTERNS_EXPORT QXmlSchemaValidator +{ + public: + QXmlSchemaValidator(const QXmlSchema &schema); + ~QXmlSchemaValidator(); + + void setSchema(const QXmlSchema &schema); + + bool validate(const QUrl &source); + bool validate(QIODevice *source, const QUrl &documentUri); + bool validate(const QByteArray &data, const QUrl &documentUri); + + QXmlNamePool namePool() const; + + void setMessageHandler(QAbstractMessageHandler *handler); + QAbstractMessageHandler *messageHandler() const; + + void setUriResolver(QAbstractUriResolver *resolver); + QAbstractUriResolver *uriResolver() const; + + void setNetworkAccessManager(QNetworkAccessManager *networkmanager); + QNetworkAccessManager *networkAccessManager() const; + + private: + QXmlSchemaValidatorPrivate* const d; + + Q_DISABLE_COPY(QXmlSchemaValidator) +}; + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif diff --git a/src/xmlpatterns/api/qxmlschemavalidator_p.h b/src/xmlpatterns/api/qxmlschemavalidator_p.h new file mode 100644 index 0000000..0990f73 --- /dev/null +++ b/src/xmlpatterns/api/qxmlschemavalidator_p.h @@ -0,0 +1,98 @@ +/**************************************************************************** +** +** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the $MODULE$ of the Qt Toolkit. +** +** $TROLLTECH_DUAL_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 QXMLSCHEMAVALIDATOR_P_H +#define QXMLSCHEMAVALIDATOR_P_H + +#include "qabstractmessagehandler.h" +#include "qabstracturiresolver.h" +#include "qautoptr_p.h" +#include "qcoloringmessagehandler_p.h" +#include "qxmlschema.h" +#include "qxmlschema_p.h" + +#include "qxsdschemacontext_p.h" +#include "qxsdschema_p.h" + +#include + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +class QXmlSchemaValidatorPrivate +{ +public: + QXmlSchemaValidatorPrivate(const QXmlSchema &schema) + : m_namePool(schema.namePool()) + , m_userMessageHandler(0) + , m_uriResolver(0) + , m_userNetworkAccessManager(0) + { + setSchema(schema); + + const QXmlSchemaPrivate *p = schema.d; + + // initialize the environment properties with the ones from the schema + + if (p->m_userNetworkAccessManager) // schema has user defined network access manager + m_userNetworkAccessManager = p->m_userNetworkAccessManager; + else + m_networkAccessManager = p->m_networkAccessManager; + + if (p->m_userMessageHandler) // schema has user defined message handler + m_userMessageHandler = p->m_userMessageHandler; + else + m_messageHandler = p->m_messageHandler; + + m_uriResolver = p->m_uriResolver; + } + + void setSchema(const QXmlSchema &schema) + { + // use same name pool as the schema + m_namePool = schema.namePool(); + m_schema = schema.d->m_schemaParserContext->schema(); + m_schemaDocumentUri = schema.documentUri(); + + // create a new schema context + m_context = QPatternist::XsdSchemaContext::Ptr(new QPatternist::XsdSchemaContext(m_namePool.d)); + m_context->m_schemaTypeFactory = schema.d->m_schemaContext->m_schemaTypeFactory; + m_context->m_builtinTypesFacetList = schema.d->m_schemaContext->m_builtinTypesFacetList; + } + + QXmlNamePool m_namePool; + QAbstractMessageHandler* m_userMessageHandler; + QAbstractUriResolver* m_uriResolver; + QNetworkAccessManager* m_userNetworkAccessManager; + QPatternist::ReferenceCountedValue::Ptr m_messageHandler; + QPatternist::ReferenceCountedValue::Ptr m_networkAccessManager; + + QPatternist::XsdSchemaContext::Ptr m_context; + QPatternist::XsdSchema::Ptr m_schema; + QUrl m_schemaDocumentUri; +}; + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif diff --git a/src/xmlpatterns/common.pri b/src/xmlpatterns/common.pri index 2573a26..27253d8 100644 --- a/src/xmlpatterns/common.pri +++ b/src/xmlpatterns/common.pri @@ -10,6 +10,7 @@ INCLUDEPATH += $$PWD/acceltree \ $$PWD/iterators \ $$PWD/janitors \ $$PWD/parser \ + $$PWD/schema \ $$PWD/type \ $$PWD/utils diff --git a/src/xmlpatterns/data/data.pri b/src/xmlpatterns/data/data.pri index 99591d4..ccfed42 100644 --- a/src/xmlpatterns/data/data.pri +++ b/src/xmlpatterns/data/data.pri @@ -1,8 +1,8 @@ HEADERS += $$PWD/qabstractdatetime_p.h \ $$PWD/qabstractduration_p.h \ $$PWD/qabstractfloatcasters_p.h \ - $$PWD/qabstractfloat_p.h \ $$PWD/qabstractfloatmathematician_p.h \ + $$PWD/qabstractfloat_p.h \ $$PWD/qanyuri_p.h \ $$PWD/qatomiccaster_p.h \ $$PWD/qatomiccasters_p.h \ @@ -14,8 +14,8 @@ HEADERS += $$PWD/qabstractdatetime_p.h \ $$PWD/qbase64binary_p.h \ $$PWD/qboolean_p.h \ $$PWD/qcommonvalues_p.h \ + $$PWD/qcomparisonfactory_p.h \ $$PWD/qdate_p.h \ - $$PWD/qschemadatetime_p.h \ $$PWD/qdaytimeduration_p.h \ $$PWD/qdecimal_p.h \ $$PWD/qderivedinteger_p.h \ @@ -24,19 +24,21 @@ HEADERS += $$PWD/qabstractdatetime_p.h \ $$PWD/qgday_p.h \ $$PWD/qgmonthday_p.h \ $$PWD/qgmonth_p.h \ - $$PWD/qgyear_p.h \ $$PWD/qgyearmonth_p.h \ + $$PWD/qgyear_p.h \ $$PWD/qhexbinary_p.h \ $$PWD/qinteger_p.h \ $$PWD/qitem_p.h \ $$PWD/qnodebuilder_p.h \ - $$PWD/qschemanumeric_p.h \ $$PWD/qqnamevalue_p.h \ $$PWD/qresourceloader_p.h \ - $$PWD/qsorttuple.cpp \ + $$PWD/qschemadatetime_p.h \ + $$PWD/qschemanumeric_p.h \ $$PWD/qschematime_p.h \ + $$PWD/qsorttuple.cpp \ $$PWD/quntypedatomic_p.h \ $$PWD/qvalidationerror_p.h \ + $$PWD/qvaluefactory_p.h \ $$PWD/qyearmonthduration_p.h SOURCES += $$PWD/qabstractdatetime.cpp \ @@ -53,8 +55,8 @@ SOURCES += $$PWD/qabstractdatetime.cpp \ $$PWD/qbase64binary.cpp \ $$PWD/qboolean.cpp \ $$PWD/qcommonvalues.cpp \ + $$PWD/qcomparisonfactory.cpp \ $$PWD/qdate.cpp \ - $$PWD/qschemadatetime.cpp \ $$PWD/qdaytimeduration.cpp \ $$PWD/qdecimal.cpp \ $$PWD/qduration.cpp \ @@ -68,11 +70,13 @@ SOURCES += $$PWD/qabstractdatetime.cpp \ $$PWD/qitem.cpp \ $$PWD/qnodebuilder.cpp \ $$PWD/qnodemodel.cpp \ - $$PWD/qschemanumeric.cpp \ $$PWD/qqnamevalue.cpp \ $$PWD/qresourceloader.cpp \ - $$PWD/qsorttuple.cpp \ + $$PWD/qschemadatetime.cpp \ + $$PWD/qschemanumeric.cpp \ $$PWD/qschematime.cpp \ + $$PWD/qsorttuple.cpp \ $$PWD/quntypedatomic.cpp \ $$PWD/qvalidationerror.cpp \ + $$PWD/qvaluefactory.cpp \ $$PWD/qyearmonthduration.cpp diff --git a/src/xmlpatterns/data/qcomparisonfactory.cpp b/src/xmlpatterns/data/qcomparisonfactory.cpp new file mode 100644 index 0000000..7fe298b --- /dev/null +++ b/src/xmlpatterns/data/qcomparisonfactory.cpp @@ -0,0 +1,124 @@ +/**************************************************************************** +** +** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the $MODULE$ of the Qt Toolkit. +** +** $TROLLTECH_DUAL_LICENSE$ +** +****************************************************************************/ + +#include "qatomiccomparators_p.h" +#include "qatomicstring_p.h" +#include "qcomparisonplatform_p.h" +#include "qvaluefactory_p.h" + +#include "qcomparisonfactory_p.h" + +QT_BEGIN_NAMESPACE + +using namespace QPatternist; + +/** + * @short Helper class for ComparisonFactory::fromLexical() which exposes + * CastingPlatform appropriately. + * + * @relates ComparisonFactory + */ +class PerformComparison : public ComparisonPlatform + , public SourceLocationReflection +{ +public: + PerformComparison(const SourceLocationReflection *const sourceLocationReflection, + const AtomicComparator::Operator op) : m_sourceReflection(sourceLocationReflection) + , m_operator(op) + { + Q_ASSERT(m_sourceReflection); + } + + bool operator()(const AtomicValue::Ptr &operand1, + const AtomicValue::Ptr &operand2, + const SchemaType::Ptr &type, + const ReportContext::Ptr &context) + { + const ItemType::Ptr asItemType((AtomicType::Ptr(type))); + + /* One area where the Query Transform world differs from the Schema + * world is that @c xs:duration is not considedered comparable, because + * it's according to Schema is partially comparable. This means + * ComparisonPlatform::fetchComparator() flags it as impossible, and + * hence we need to override that. + * + * SchemaType::wxsTypeMatches() will return true for sub-types of @c + * xs:duration as well, but that's ok since AbstractDurationComparator + * works for them too. */ + if(BuiltinTypes::xsDuration->wxsTypeMatches(type)) + prepareComparison(AtomicComparator::Ptr(new AbstractDurationComparator())); + else if (BuiltinTypes::xsGYear->wxsTypeMatches(type) || + BuiltinTypes::xsGYearMonth->wxsTypeMatches(type) || + BuiltinTypes::xsGMonth->wxsTypeMatches(type) || + BuiltinTypes::xsGMonthDay->wxsTypeMatches(type) || + BuiltinTypes::xsGDay->wxsTypeMatches(type)) + prepareComparison(AtomicComparator::Ptr(new AbstractDateTimeComparator())); + else + prepareComparison(fetchComparator(asItemType, asItemType, context)); + + return flexibleCompare(operand1, operand2, context); + } + + const SourceLocationReflection *actualReflection() const + { + return m_sourceReflection; + } + + AtomicComparator::Operator operatorID() const + { + return m_operator; + } + +private: + const SourceLocationReflection *const m_sourceReflection; + const AtomicComparator::Operator m_operator; +}; + +bool ComparisonFactory::compare(const AtomicValue::Ptr &operand1, + const AtomicComparator::Operator op, + const AtomicValue::Ptr &operand2, + const SchemaType::Ptr &type, + const ReportContext::Ptr &context, + const SourceLocationReflection *const sourceLocationReflection) +{ + Q_ASSERT(operand1); + Q_ASSERT(operand2); + Q_ASSERT(context); + Q_ASSERT(sourceLocationReflection); + Q_ASSERT(type); + Q_ASSERT_X(type->category() == SchemaType::SimpleTypeAtomic, Q_FUNC_INFO, + "We can only compare atomic values."); + + return PerformComparison(sourceLocationReflection, op)(operand1, operand2, type, context); +} + +bool ComparisonFactory::constructAndCompare(const DerivedString::Ptr &operand1, + const AtomicComparator::Operator op, + const DerivedString::Ptr &operand2, + const SchemaType::Ptr &type, + const ReportContext::Ptr &context, + const SourceLocationReflection *const sourceLocationReflection) +{ + Q_ASSERT(operand1); + Q_ASSERT(operand2); + Q_ASSERT(context); + Q_ASSERT(sourceLocationReflection); + Q_ASSERT(type); + Q_ASSERT_X(type->category() == SchemaType::SimpleTypeAtomic, Q_FUNC_INFO, + "We can only compare atomic values."); + + const AtomicValue::Ptr value1 = ValueFactory::fromLexical(operand1->stringValue(), type, context, sourceLocationReflection); + const AtomicValue::Ptr value2 = ValueFactory::fromLexical(operand2->stringValue(), type, context, sourceLocationReflection); + + return compare(value1, op, value2, type, context, sourceLocationReflection); +} + +QT_END_NAMESPACE diff --git a/src/xmlpatterns/data/qcomparisonfactory_p.h b/src/xmlpatterns/data/qcomparisonfactory_p.h new file mode 100644 index 0000000..09fc50b --- /dev/null +++ b/src/xmlpatterns/data/qcomparisonfactory_p.h @@ -0,0 +1,91 @@ +/**************************************************************************** +** +** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the $MODULE$ of the Qt Toolkit. +** +** $TROLLTECH_DUAL_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_ComparisonFactory_H +#define Patternist_ComparisonFactory_H + +#include "qatomiccomparator_p.h" +#include "qderivedstring_p.h" +#include "qitem_p.h" +#include "qreportcontext_p.h" +#include "qschematype_p.h" + +QT_BEGIN_HEADER +QT_BEGIN_NAMESPACE + +namespace QPatternist +{ + /** + * @short Provides compare(), which is a high-level helper function for + * comparing atomic values. + * + * This class wraps the helper class ComparisonPlatform with a more specific, + * high-level API. + * + * @see ComparisonPlatform + * @author Frans Englich + * @ingroup Patternist_schema + */ + class ComparisonFactory + { + public: + /** + * @short Returns the result of evaluating operator @p op applied to the atomic + * values @p operand1 and @p operand2. + * + * The caller guarantees that both values are of type @p type. + * + * ComparisonFactory does not take ownership of @p sourceLocationReflection. + */ + static bool compare(const AtomicValue::Ptr &operand1, + const AtomicComparator::Operator op, + const AtomicValue::Ptr &operand2, + const SchemaType::Ptr &type, + const ReportContext::Ptr &context, + const SourceLocationReflection *const sourceLocationReflection); + + /** + * @short Returns the result of evaluating operator @p op applied to the atomic + * values @p operand1 and @p operand2. + * + * In opposite to compare() it converts the operands from string type + * to @p type and compares these constructed types. + * + * The caller guarantees that both values are of type @p type. + * + * ComparisonFactory does not take ownership of @p sourceLocationReflection. + */ + static bool constructAndCompare(const DerivedString::Ptr &operand1, + const AtomicComparator::Operator op, + const DerivedString::Ptr &operand2, + const SchemaType::Ptr &type, + const ReportContext::Ptr &context, + const SourceLocationReflection *const sourceLocationReflection); + + private: + Q_DISABLE_COPY(ComparisonFactory) + }; +} + +QT_END_NAMESPACE +QT_END_HEADER + +#endif diff --git a/src/xmlpatterns/data/qitem_p.h b/src/xmlpatterns/data/qitem_p.h index 987a1c2..08b318d 100644 --- a/src/xmlpatterns/data/qitem_p.h +++ b/src/xmlpatterns/data/qitem_p.h @@ -128,6 +128,11 @@ namespace QPatternist typedef QExplicitlySharedDataPointer Ptr; /** + * A list if smart pointers wrapping AtomicValue instances. + */ + typedef QList List; + + /** * Determines whether this atomic value has an error. This is used * for implementing casting. * diff --git a/src/xmlpatterns/data/qvaluefactory.cpp b/src/xmlpatterns/data/qvaluefactory.cpp new file mode 100644 index 0000000..04df29d --- /dev/null +++ b/src/xmlpatterns/data/qvaluefactory.cpp @@ -0,0 +1,76 @@ +/**************************************************************************** +** +** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the $MODULE$ of the Qt Toolkit. +** +** $TROLLTECH_DUAL_LICENSE$ +** +****************************************************************************/ + +#include "qatomiccaster_p.h" +#include "qatomicstring_p.h" +#include "qcastingplatform_p.h" +#include "qvaluefactory_p.h" + +QT_BEGIN_NAMESPACE + +using namespace QPatternist; + +/** + * @short Helper class for ValueFactory::fromLexical() which exposes + * CastingPlatform appropriately. + * + * @relates ValueFactory + */ +class PerformValueConstruction : public CastingPlatform + , public SourceLocationReflection +{ +public: + PerformValueConstruction(const SourceLocationReflection *const sourceLocationReflection, + const SchemaType::Ptr &toType) : m_sourceReflection(sourceLocationReflection) + , m_targetType(AtomicType::Ptr(toType)) + { + Q_ASSERT(m_sourceReflection); + } + + AtomicValue::Ptr operator()(const AtomicValue::Ptr &lexicalValue, + const SchemaType::Ptr &type, + const ReportContext::Ptr &context) + { + prepareCasting(context, BuiltinTypes::xsString); + return AtomicValue::Ptr(const_cast(cast(lexicalValue, context).asAtomicValue())); + } + + const SourceLocationReflection *actualReflection() const + { + return m_sourceReflection; + } + + ItemType::Ptr targetType() const + { + return m_targetType; + } + +private: + const SourceLocationReflection *const m_sourceReflection; + const ItemType::Ptr m_targetType; +}; + +AtomicValue::Ptr ValueFactory::fromLexical(const QString &lexicalValue, + const SchemaType::Ptr &type, + const ReportContext::Ptr &context, + const SourceLocationReflection *const sourceLocationReflection) +{ + Q_ASSERT(context); + Q_ASSERT(type); + Q_ASSERT_X(type->category() == SchemaType::SimpleTypeAtomic, Q_FUNC_INFO, + "We can only construct for atomic values."); + + return PerformValueConstruction(sourceLocationReflection, type)(AtomicString::fromValue(lexicalValue), + type, + context); +} + +QT_END_NAMESPACE diff --git a/src/xmlpatterns/data/qvaluefactory_p.h b/src/xmlpatterns/data/qvaluefactory_p.h new file mode 100644 index 0000000..80b6207 --- /dev/null +++ b/src/xmlpatterns/data/qvaluefactory_p.h @@ -0,0 +1,68 @@ +/**************************************************************************** +** +** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the $MODULE$ of the Qt Toolkit. +** +** $TROLLTECH_DUAL_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_ValueFactory_H +#define Patternist_ValueFactory_H + +#include "qitem_p.h" +#include "qreportcontext_p.h" +#include "qschematype_p.h" + +QT_BEGIN_HEADER +QT_BEGIN_NAMESPACE + +namespace QPatternist +{ + /** + * @short Provides fromLexical(), which allows instantiation of atomic + * values from arbitrary types. + * + * This class wraps the helper class CastingPlatform with a more specific, + * high-level API. + * + * @see CastingPlatform + * @author Frans Englich + * @ingroup Patternist_schema + */ + class ValueFactory + { + public: + /** + * @short Returns an AtomicValue of type @p type from the lexical space + * @p lexicalValue, and raise an error through @p context if that's + * impossible. + * + * ValueFactory does not take ownership of @p sourceLocationReflection. + */ + static AtomicValue::Ptr fromLexical(const QString &lexicalValue, + const SchemaType::Ptr &type, + const ReportContext::Ptr &context, + const SourceLocationReflection *const sourceLocationReflection); + + private: + Q_DISABLE_COPY(ValueFactory) + }; +} + +QT_END_NAMESPACE +QT_END_HEADER + +#endif diff --git a/src/xmlpatterns/environment/createReportContext.xsl b/src/xmlpatterns/environment/createReportContext.xsl index e648c56..1db00e7 100644 --- a/src/xmlpatterns/environment/createReportContext.xsl +++ b/src/xmlpatterns/environment/createReportContext.xsl @@ -242,6 +242,11 @@ namespace QPatternist */]]> enum ErrorCode { + /** + * XML Schema error code. + */ + XSDError, + diff --git a/src/xmlpatterns/environment/qreportcontext.cpp b/src/xmlpatterns/environment/qreportcontext.cpp index 9704a54..acd6be0 100644 --- a/src/xmlpatterns/environment/qreportcontext.cpp +++ b/src/xmlpatterns/environment/qreportcontext.cpp @@ -448,6 +448,7 @@ QString ReportContext::codeToString(const ReportContext::ErrorCode code) case XTTE1545: result = "XTTE1545"; break; case XTTE1550: result = "XTTE1550"; break; case XTTE1555: result = "XTTE1555"; break; + case XSDError: result = "XSDError"; break; } Q_ASSERT_X(result, Q_FUNC_INFO, "Unknown enum value."); diff --git a/src/xmlpatterns/environment/qreportcontext_p.h b/src/xmlpatterns/environment/qreportcontext_p.h index bea2a97..8864756 100644 --- a/src/xmlpatterns/environment/qreportcontext_p.h +++ b/src/xmlpatterns/environment/qreportcontext_p.h @@ -151,6 +151,10 @@ namespace QPatternist */ enum ErrorCode { + /** + * XML Schema error code. + */ + XSDError, /** * It is a static error if analysis of an expression relies on some diff --git a/src/xmlpatterns/expr/qcastingplatform.cpp b/src/xmlpatterns/expr/qcastingplatform.cpp index 9e96fd8..16a1d60 100644 --- a/src/xmlpatterns/expr/qcastingplatform.cpp +++ b/src/xmlpatterns/expr/qcastingplatform.cpp @@ -83,7 +83,7 @@ Item CastingPlatform::cast(const Item &sourceValue, else { bool castImpossible = false; - const AtomicCaster::Ptr caster(locateCaster(sourceValue.type(), context, castImpossible)); + const AtomicCaster::Ptr caster(locateCaster(sourceValue.type(), context, castImpossible, static_cast(this), targetType())); if(!issueError && castImpossible) { @@ -112,7 +112,7 @@ bool CastingPlatform::prepareCasting(const ReportContext: or numeric at compile time. We'll do lookup at runtime instead. */ bool castImpossible = false; - m_caster = locateCaster(sourceType, context, castImpossible); + m_caster = locateCaster(sourceType, context, castImpossible, static_cast(this), targetType()); return !castImpossible; } @@ -120,20 +120,22 @@ bool CastingPlatform::prepareCasting(const ReportContext: template AtomicCaster::Ptr CastingPlatform::locateCaster(const ItemType::Ptr &sourceType, const ReportContext::Ptr &context, - bool &castImpossible) const + bool &castImpossible, + const SourceLocationReflection *const location, + const ItemType::Ptr &targetType) { Q_ASSERT(sourceType); - Q_ASSERT(targetType()); + Q_ASSERT(targetType); const AtomicCasterLocator::Ptr locator(static_cast( - targetType().data())->casterLocator()); + targetType.data())->casterLocator()); if(!locator) { if(issueError) { context->error(QtXmlPatterns::tr("No casting is possible with %1 as the target type.") - .arg(formatType(context->namePool(), targetType())), - ReportContext::XPTY0004, static_cast(this)); + .arg(formatType(context->namePool(), targetType)), + ReportContext::XPTY0004, location); } else castImpossible = true; @@ -141,15 +143,15 @@ AtomicCaster::Ptr CastingPlatform::locateCaster(const Ite return AtomicCaster::Ptr(); } - const AtomicCaster::Ptr caster(static_cast(sourceType.data())->accept(locator, static_cast(this))); + const AtomicCaster::Ptr caster(static_cast(sourceType.data())->accept(locator, location)); if(!caster) { if(issueError) { context->error(QtXmlPatterns::tr("It is not possible to cast from %1 to %2.") .arg(formatType(context->namePool(), sourceType)) - .arg(formatType(context->namePool(), targetType())), - ReportContext::XPTY0004, static_cast(this)); + .arg(formatType(context->namePool(), targetType)), + ReportContext::XPTY0004, location); } else castImpossible = true; diff --git a/src/xmlpatterns/expr/qcastingplatform_p.h b/src/xmlpatterns/expr/qcastingplatform_p.h index 458e9eb..a0144b2 100644 --- a/src/xmlpatterns/expr/qcastingplatform_p.h +++ b/src/xmlpatterns/expr/qcastingplatform_p.h @@ -52,16 +52,17 @@ #ifndef Patternist_CastingPlatform_H #define Patternist_CastingPlatform_H +#include "qatomiccasterlocator_p.h" #include "qatomiccaster_p.h" -#include "qqnamevalue_p.h" #include "qatomicstring_p.h" -#include "qvalidationerror_p.h" -#include "qatomiccasterlocator_p.h" #include "qatomictype_p.h" #include "qbuiltintypes_p.h" #include "qcommonsequencetypes_p.h" -#include "qschematypefactory_p.h" #include "qpatternistlocale_p.h" +#include "qqnamevalue_p.h" +#include "qschematypefactory_p.h" +#include "qstaticcontext_p.h" +#include "qvalidationerror_p.h" QT_BEGIN_HEADER @@ -101,6 +102,7 @@ namespace QPatternist * function targetType() must be implemented such that CastingPlatform knows * what type it shall cast to. * + * @see ValueFactory * @author Frans Englich * @ingroup Patternist_expressions */ @@ -167,9 +169,16 @@ namespace QPatternist * * @p castImpossible is not initialized. Initialize it to @c false. */ - AtomicCaster::Ptr locateCaster(const ItemType::Ptr &sourceType, - const ReportContext::Ptr &context, - bool &castImpossible) const; + static AtomicCaster::Ptr locateCaster(const ItemType::Ptr &sourceType, + const ReportContext::Ptr &context, + bool &castImpossible, + const SourceLocationReflection *const location, + const ItemType::Ptr &targetType); + private: + inline Item castWithCaster(const Item &sourceValue, + const AtomicCaster::Ptr &caster, + const DynamicContext::Ptr &context) const; + inline ItemType::Ptr targetType() const { diff --git a/src/xmlpatterns/expr/qexpressionfactory.cpp b/src/xmlpatterns/expr/qexpressionfactory.cpp index ec86be0..b41b0de 100644 --- a/src/xmlpatterns/expr/qexpressionfactory.cpp +++ b/src/xmlpatterns/expr/qexpressionfactory.cpp @@ -81,9 +81,13 @@ Expression::Ptr ExpressionFactory::createExpression(const QString &expr, const QUrl &queryURI, const QXmlName &initialTemplateName) { - if(lang == QXmlQuery::XQuery10) + if(lang == QXmlQuery::XSLT20) { - return createExpression(Tokenizer::Ptr(new XQueryTokenizer(expr, queryURI)), + QByteArray query(expr.toUtf8()); + QBuffer buffer(&query); + buffer.open(QIODevice::ReadOnly); + + return createExpression(&buffer, context, lang, requiredType, @@ -92,12 +96,7 @@ Expression::Ptr ExpressionFactory::createExpression(const QString &expr, } else { - Q_ASSERT(lang == QXmlQuery::XSLT20); - QByteArray query(expr.toUtf8()); - QBuffer buffer(&query); - buffer.open(QIODevice::ReadOnly); - - return createExpression(&buffer, + return createExpression(Tokenizer::Ptr(new XQueryTokenizer(expr, queryURI)), context, lang, requiredType, @@ -118,16 +117,10 @@ Expression::Ptr ExpressionFactory::createExpression(QIODevice *const device, Tokenizer::Ptr tokenizer; - if(lang == QXmlQuery::XQuery10) - { - - tokenizer = Tokenizer::Ptr(new XQueryTokenizer(QString::fromUtf8(device->readAll()), queryURI)); - } - else - { - Q_ASSERT(lang == QXmlQuery::XSLT20); + if(lang == QXmlQuery::XSLT20) tokenizer = Tokenizer::Ptr(new XSLTTokenizer(device, queryURI, context, context->namePool())); - } + else + tokenizer = Tokenizer::Ptr(new XQueryTokenizer(QString::fromUtf8(device->readAll()), queryURI)); return createExpression(tokenizer, context, lang, requiredType, queryURI, initialTemplateName); } diff --git a/src/xmlpatterns/functions/qpatternplatform.cpp b/src/xmlpatterns/functions/qpatternplatform.cpp index 0052a07..d99bac5 100644 --- a/src/xmlpatterns/functions/qpatternplatform.cpp +++ b/src/xmlpatterns/functions/qpatternplatform.cpp @@ -168,8 +168,15 @@ void PatternPlatform::applyFlags(const Flags flags, QRegExp &patternP) // TODO Apply the other flags, like 'x'. } +QRegExp PatternPlatform::parsePattern(const QString &pattern, + const ReportContext::Ptr &context) const +{ + return parsePattern(pattern, context, this); +} + QRegExp PatternPlatform::parsePattern(const QString &patternP, - const DynamicContext::Ptr &context) const + const ReportContext::Ptr &context, + const SourceLocationReflection *const location) { if(patternP == QLatin1String("(.)\\3") || patternP == QLatin1String("\\3") || @@ -177,7 +184,7 @@ QRegExp PatternPlatform::parsePattern(const QString &patternP, { context->error(QLatin1String("We don't want to hang infinitely on K2-MatchesFunc-9, " "10 and 11. See Trolltech task 148505."), - ReportContext::FOER0000, this); + ReportContext::FOER0000, location); return QRegExp(); } @@ -189,14 +196,8 @@ QRegExp PatternPlatform::parsePattern(const QString &patternP, * QChar::category(). */ rewrittenPattern.replace(QLatin1String("[\\i-[:]]"), QLatin1String("[a-zA-Z_]")); rewrittenPattern.replace(QLatin1String("[\\c-[:]]"), QLatin1String("[a-zA-Z0-9_\\-\\.]")); - rewrittenPattern.replace(QLatin1String("\\i"), QLatin1String("[a-zA-Z:_]")); - rewrittenPattern.replace(QLatin1String("\\c"), QLatin1String("[a-zA-Z0-9:_\\-\\.]")); - rewrittenPattern.replace(QLatin1String("\\p{L}"), QLatin1String("[a-zA-Z]")); - rewrittenPattern.replace(QLatin1String("\\p{Lu}"), QLatin1String("[A-Z]")); - rewrittenPattern.replace(QLatin1String("\\p{Ll}"), QLatin1String("[a-z]")); - rewrittenPattern.replace(QLatin1String("\\p{Nd}"), QLatin1String("[0-9]")); - QRegExp retval(rewrittenPattern); + QRegExp retval(rewrittenPattern, Qt::CaseSensitive, QRegExp::W3CXmlSchema11); if(retval.isValid()) return retval; @@ -204,7 +205,7 @@ QRegExp PatternPlatform::parsePattern(const QString &patternP, { context->error(QtXmlPatterns::tr("%1 is an invalid regular expression pattern: %2") .arg(formatExpression(patternP), retval.errorString()), - ReportContext::FORX0002, this); + ReportContext::FORX0002, location); return QRegExp(); } } diff --git a/src/xmlpatterns/functions/qpatternplatform_p.h b/src/xmlpatterns/functions/qpatternplatform_p.h index ce0dbd4..28da452 100644 --- a/src/xmlpatterns/functions/qpatternplatform_p.h +++ b/src/xmlpatterns/functions/qpatternplatform_p.h @@ -122,6 +122,14 @@ namespace QPatternist */ inline int captureCount() const; + /** + * @short Parses pattern + */ + static QRegExp parsePattern(const QString &pattern, + const ReportContext::Ptr &context, + const SourceLocationReflection *const location); + + protected: /** * @short This constructor is protected, because this class is supposed to be sub-classed. @@ -146,14 +154,18 @@ namespace QPatternist }; typedef QFlags PreCompiledParts; + /** + * @short Calls the public parsePattern() function and passes in @c + * this as the location. + */ + inline QRegExp parsePattern(const QString &pattern, + const ReportContext::Ptr &context) const; + Q_DISABLE_COPY(PatternPlatform) Flags parseFlags(const QString &flags, const DynamicContext::Ptr &context) const; - QRegExp parsePattern(const QString &pattern, - const DynamicContext::Ptr &context) const; - static void applyFlags(const Flags flags, QRegExp &pattern); /** diff --git a/src/xmlpatterns/parser/qquerytransformparser.cpp b/src/xmlpatterns/parser/qquerytransformparser.cpp index 60e3a0c..b2f8cd2 100644 --- a/src/xmlpatterns/parser/qquerytransformparser.cpp +++ b/src/xmlpatterns/parser/qquerytransformparser.cpp @@ -300,11 +300,18 @@ static inline QSourceLocation fromYYLTYPE(const YYLTYPE &sourceLocator, } /** + * @internal + * @relates QXmlQuery + */ +typedef QFlags QueryLanguages; + +/** * @short Flags invalid expressions and declarations in the currently * parsed language. * - * Since this grammar is used for several languages: XQuery 1.0, XSL-T 2.0 and - * XPath 2.0 inside XSL-T, it is the union of all the constructs in these + * Since this grammar is used for several languages: XQuery 1.0, XSL-T 2.0, and + * XPath 2.0 inside XSL-T, and field and selector patterns in W3C XML Schema's + * identity constraints, it is the union of all the constructs in these * languages. However, when dealing with each language individually, we * regularly need to disallow some expressions, such as direct element * constructors when parsing XSL-T, or the typeswitch when parsing XPath. @@ -315,19 +322,46 @@ static inline QSourceLocation fromYYLTYPE(const YYLTYPE &sourceLocator, * instance the @c let clause, should not be flagged as an error, because it's * used for internal purposes. * - * Hence, this function is called from each expression and declaration which is - * unavailable in XPath. + * Hence, this function is called from each expression and declaration with @p + * allowedLanguages stating what languages it is allowed in. * * If @p isInternal is @c true, no error is raised. Otherwise, if the current - * language is not XQuery, an error is raised. + * language is not in @p allowedLanguages, an error is raised. */ -static void disallowedConstruct(const ParserContext *const parseInfo, - const YYLTYPE &sourceLocator, - const bool isInternal = false) +static void allowedIn(const QueryLanguages allowedLanguages, + const ParserContext *const parseInfo, + const YYLTYPE &sourceLocator, + const bool isInternal = false) { - if(!isInternal && parseInfo->languageAccent != QXmlQuery::XQuery10) + /* We treat XPath 2.0 as a subset of XSL-T 2.0, so if XPath 2.0 is allowed + * and XSL-T is the language, it's ok. */ + if(!isInternal && + (!allowedLanguages.testFlag(parseInfo->languageAccent) && !(allowedLanguages.testFlag(QXmlQuery::XPath20) && parseInfo->languageAccent == QXmlQuery::XSLT20))) { - parseInfo->staticContext->error(QtXmlPatterns::tr("A construct was encountered which only is allowed in XQuery."), + + QString langName; + + switch(parseInfo->languageAccent) + { + case QXmlQuery::XPath20: + langName = QLatin1String("XPath 2.0"); + break; + case QXmlQuery::XSLT20: + langName = QLatin1String("XSL-T 2.0"); + break; + case QXmlQuery::XQuery10: + langName = QLatin1String("XQuery 1.0"); + break; + case QXmlQuery::XmlSchema11IdentityConstraintSelector: + langName = QtXmlPatterns::tr("W3C XML Schema identity constraint selector"); + break; + case QXmlQuery::XmlSchema11IdentityConstraintField: + langName = QtXmlPatterns::tr("W3C XML Schema identity constraint field"); + break; + } + + parseInfo->staticContext->error(QtXmlPatterns::tr("A construct was encountered " + "which is disallowed in the current language(%1).").arg(langName), ReportContext::XPST0003, fromYYLTYPE(sourceLocator, parseInfo)); @@ -1366,7 +1400,7 @@ typedef struct YYLTYPE /* Copy the second part of user declarations. */ /* Line 221 of yacc.c. */ -#line 1289 "qquerytransformparser.cpp" +#line 1323 "qquerytransformparser.cpp" #ifdef short # undef short @@ -1850,54 +1884,54 @@ static const yytype_int16 yyrhs[] = /* YYRLINE[YYN] -- source line where rule number YYN was defined. */ static const yytype_uint16 yyrline[] = { - 0, 1341, 1341, 1342, 1344, 1345, 1376, 1377, 1393, 1491, - 1493, 1499, 1501, 1508, 1514, 1520, 1527, 1530, 1534, 1538, - 1558, 1572, 1576, 1570, 1639, 1643, 1660, 1663, 1665, 1670, - 1671, 1675, 1676, 1680, 1684, 1688, 1690, 1691, 1693, 1695, - 1741, 1755, 1760, 1765, 1766, 1768, 1783, 1798, 1808, 1823, - 1827, 1832, 1846, 1850, 1855, 1869, 1874, 1879, 1884, 1889, - 1905, 1928, 1936, 1937, 1938, 1940, 1957, 1958, 1960, 1961, - 1963, 1964, 1966, 2021, 2025, 2031, 2034, 2039, 2053, 2057, - 2063, 2062, 2171, 2174, 2180, 2201, 2207, 2211, 2213, 2218, - 2228, 2229, 2234, 2235, 2244, 2314, 2325, 2326, 2330, 2335, - 2404, 2405, 2409, 2414, 2458, 2459, 2464, 2471, 2477, 2478, - 2479, 2480, 2481, 2482, 2488, 2493, 2499, 2502, 2507, 2513, - 2519, 2523, 2548, 2549, 2553, 2557, 2551, 2598, 2601, 2596, - 2617, 2618, 2619, 2622, 2626, 2634, 2633, 2647, 2646, 2655, - 2656, 2657, 2659, 2667, 2678, 2681, 2683, 2688, 2695, 2702, - 2708, 2728, 2733, 2739, 2742, 2744, 2745, 2752, 2758, 2762, - 2767, 2768, 2771, 2775, 2770, 2784, 2788, 2783, 2796, 2799, - 2803, 2798, 2812, 2816, 2811, 2824, 2826, 2854, 2853, 2865, - 2873, 2864, 2884, 2885, 2888, 2892, 2897, 2902, 2901, 2917, - 2922, 2923, 2928, 2929, 2934, 2935, 2936, 2937, 2939, 2940, - 2945, 2946, 2951, 2952, 2954, 2955, 2960, 2961, 2962, 2963, - 2965, 2966, 2971, 2972, 2977, 2978, 2980, 2984, 2989, 2990, - 2996, 2997, 3002, 3003, 3008, 3009, 3014, 3015, 3020, 3024, - 3029, 3030, 3031, 3033, 3038, 3039, 3040, 3041, 3042, 3043, - 3045, 3050, 3051, 3052, 3053, 3054, 3055, 3057, 3062, 3063, - 3064, 3066, 3080, 3081, 3082, 3084, 3100, 3104, 3109, 3110, - 3112, 3117, 3118, 3120, 3126, 3130, 3136, 3139, 3140, 3144, - 3153, 3158, 3162, 3163, 3168, 3167, 3182, 3189, 3188, 3203, - 3211, 3211, 3220, 3222, 3225, 3230, 3232, 3236, 3302, 3305, - 3311, 3314, 3323, 3327, 3331, 3336, 3337, 3342, 3343, 3346, - 3345, 3375, 3377, 3378, 3380, 3394, 3395, 3396, 3397, 3398, - 3399, 3400, 3401, 3402, 3403, 3404, 3405, 3408, 3407, 3417, - 3428, 3433, 3435, 3440, 3441, 3443, 3447, 3449, 3453, 3462, - 3468, 3469, 3474, 3475, 3476, 3477, 3478, 3479, 3480, 3481, - 3491, 3492, 3497, 3501, 3506, 3511, 3516, 3521, 3525, 3530, - 3535, 3540, 3569, 3573, 3580, 3582, 3586, 3588, 3589, 3590, - 3624, 3633, 3622, 3874, 3878, 3898, 3901, 3907, 3912, 3917, - 3923, 3926, 3936, 3943, 3947, 3953, 3967, 3973, 3990, 3995, - 4008, 4009, 4010, 4011, 4012, 4013, 4014, 4016, 4024, 4023, - 4063, 4066, 4071, 4086, 4091, 4098, 4110, 4114, 4110, 4120, - 4122, 4126, 4128, 4143, 4147, 4156, 4161, 4165, 4171, 4174, - 4179, 4184, 4189, 4190, 4191, 4192, 4194, 4195, 4196, 4197, - 4202, 4238, 4239, 4240, 4241, 4242, 4243, 4244, 4246, 4251, - 4256, 4262, 4263, 4265, 4270, 4275, 4280, 4285, 4301, 4302, - 4304, 4309, 4314, 4318, 4330, 4343, 4353, 4358, 4363, 4368, - 4382, 4396, 4397, 4399, 4409, 4411, 4416, 4423, 4430, 4432, - 4434, 4435, 4437, 4441, 4446, 4447, 4449, 4455, 4457, 4459, - 4460, 4462, 4474 + 0, 1375, 1375, 1376, 1378, 1379, 1410, 1411, 1427, 1525, + 1527, 1533, 1535, 1542, 1548, 1554, 1561, 1564, 1568, 1572, + 1592, 1606, 1610, 1604, 1673, 1677, 1694, 1697, 1699, 1704, + 1705, 1709, 1710, 1714, 1718, 1722, 1724, 1725, 1727, 1729, + 1775, 1789, 1794, 1799, 1800, 1802, 1817, 1832, 1842, 1857, + 1861, 1866, 1880, 1884, 1889, 1903, 1908, 1913, 1918, 1923, + 1939, 1962, 1970, 1971, 1972, 1974, 1991, 1992, 1994, 1995, + 1997, 1998, 2000, 2055, 2059, 2065, 2068, 2073, 2087, 2091, + 2097, 2096, 2205, 2208, 2214, 2235, 2241, 2245, 2247, 2252, + 2262, 2263, 2268, 2269, 2278, 2348, 2359, 2360, 2364, 2369, + 2438, 2439, 2443, 2448, 2492, 2493, 2498, 2505, 2511, 2512, + 2513, 2514, 2515, 2516, 2522, 2527, 2533, 2536, 2541, 2547, + 2553, 2557, 2582, 2583, 2587, 2591, 2585, 2632, 2635, 2630, + 2651, 2652, 2653, 2656, 2660, 2668, 2667, 2681, 2680, 2689, + 2690, 2691, 2693, 2701, 2712, 2715, 2717, 2722, 2729, 2736, + 2742, 2762, 2767, 2773, 2776, 2778, 2779, 2786, 2792, 2796, + 2801, 2802, 2805, 2809, 2804, 2819, 2823, 2818, 2831, 2834, + 2838, 2833, 2848, 2852, 2847, 2860, 2862, 2890, 2889, 2901, + 2909, 2900, 2920, 2921, 2924, 2928, 2933, 2938, 2937, 2953, + 2959, 2960, 2966, 2967, 2973, 2974, 2975, 2976, 2978, 2979, + 2985, 2986, 2992, 2993, 2995, 2996, 3002, 3003, 3004, 3005, + 3007, 3008, 3018, 3019, 3025, 3026, 3028, 3032, 3037, 3038, + 3045, 3046, 3052, 3053, 3059, 3060, 3066, 3067, 3073, 3077, + 3082, 3083, 3084, 3086, 3092, 3093, 3094, 3095, 3096, 3097, + 3099, 3104, 3105, 3106, 3107, 3108, 3109, 3111, 3116, 3117, + 3118, 3120, 3134, 3135, 3136, 3138, 3155, 3159, 3164, 3165, + 3167, 3172, 3173, 3175, 3181, 3185, 3191, 3194, 3195, 3199, + 3208, 3213, 3217, 3218, 3223, 3222, 3237, 3245, 3244, 3260, + 3268, 3268, 3277, 3279, 3282, 3287, 3289, 3293, 3359, 3362, + 3368, 3371, 3380, 3384, 3388, 3393, 3394, 3399, 3400, 3403, + 3402, 3432, 3434, 3435, 3437, 3481, 3482, 3483, 3484, 3485, + 3486, 3487, 3488, 3489, 3490, 3491, 3492, 3495, 3494, 3505, + 3516, 3521, 3523, 3528, 3529, 3534, 3538, 3540, 3544, 3553, + 3560, 3561, 3567, 3568, 3569, 3570, 3571, 3572, 3573, 3574, + 3584, 3585, 3590, 3595, 3601, 3607, 3612, 3617, 3622, 3628, + 3633, 3638, 3668, 3672, 3679, 3681, 3685, 3690, 3691, 3692, + 3726, 3735, 3724, 3976, 3980, 4000, 4003, 4009, 4014, 4019, + 4025, 4028, 4038, 4045, 4049, 4055, 4069, 4075, 4092, 4097, + 4110, 4111, 4112, 4113, 4114, 4115, 4116, 4118, 4126, 4125, + 4165, 4168, 4173, 4188, 4193, 4200, 4212, 4216, 4212, 4222, + 4224, 4228, 4230, 4245, 4249, 4258, 4263, 4267, 4273, 4276, + 4281, 4286, 4291, 4292, 4293, 4294, 4296, 4297, 4298, 4299, + 4304, 4340, 4341, 4342, 4343, 4344, 4345, 4346, 4348, 4353, + 4358, 4364, 4365, 4367, 4372, 4377, 4382, 4387, 4403, 4404, + 4406, 4411, 4416, 4420, 4432, 4445, 4455, 4460, 4465, 4470, + 4484, 4498, 4499, 4501, 4511, 4513, 4518, 4525, 4532, 4534, + 4536, 4537, 4539, 4543, 4548, 4549, 4551, 4557, 4559, 4561, + 4565, 4570, 4582 }; #endif @@ -3726,7 +3760,7 @@ yyreduce: { case 5: /* Line 1269 of yacc.c. */ -#line 1346 "querytransformparser.ypp" +#line 1380 "querytransformparser.ypp" { /* Suppress more compiler warnings about unused defines. */ @@ -3760,7 +3794,7 @@ yyreduce: case 7: /* Line 1269 of yacc.c. */ -#line 1378 "querytransformparser.ypp" +#line 1412 "querytransformparser.ypp" { const QRegExp encNameRegExp(QLatin1String("[A-Za-z][A-Za-z0-9._\\-]*")); @@ -3779,7 +3813,7 @@ yyreduce: case 8: /* Line 1269 of yacc.c. */ -#line 1394 "querytransformparser.ypp" +#line 1428 "querytransformparser.ypp" { /* In XSL-T, we can have dangling variable references, so resolve them * before we proceed with other steps, such as checking circularity. */ @@ -3880,7 +3914,7 @@ yyreduce: case 10: /* Line 1269 of yacc.c. */ -#line 1494 "querytransformparser.ypp" +#line 1528 "querytransformparser.ypp" { // TODO add to namespace context parseInfo->moduleNamespace = parseInfo->staticContext->namePool()->allocateNamespace((yyvsp[(3) - (6)].sval)); @@ -3889,9 +3923,9 @@ yyreduce: case 12: /* Line 1269 of yacc.c. */ -#line 1502 "querytransformparser.ypp" +#line 1536 "querytransformparser.ypp" { - disallowedConstruct(parseInfo, (yyloc)); + allowedIn(QXmlQuery::XQuery10, parseInfo, (yyloc)); if(parseInfo->hasSecondPrologPart) parseInfo->staticContext->error(QtXmlPatterns::tr("A default namespace declaration must occur before function, " "variable, and option declarations."), ReportContext::XPST0003, fromYYLTYPE((yyloc), parseInfo)); @@ -3900,7 +3934,7 @@ yyreduce: case 13: /* Line 1269 of yacc.c. */ -#line 1509 "querytransformparser.ypp" +#line 1543 "querytransformparser.ypp" { if(parseInfo->hasSecondPrologPart) parseInfo->staticContext->error(QtXmlPatterns::tr("A default namespace declaration must occur before function, " @@ -3910,7 +3944,7 @@ yyreduce: case 14: /* Line 1269 of yacc.c. */ -#line 1515 "querytransformparser.ypp" +#line 1549 "querytransformparser.ypp" { if(parseInfo->hasSecondPrologPart) parseInfo->staticContext->error(QtXmlPatterns::tr("Namespace declarations must occur before function, " @@ -3920,9 +3954,9 @@ yyreduce: case 15: /* Line 1269 of yacc.c. */ -#line 1521 "querytransformparser.ypp" +#line 1555 "querytransformparser.ypp" { - disallowedConstruct(parseInfo, (yyloc)); + allowedIn(QXmlQuery::XQuery10, parseInfo, (yyloc)); if(parseInfo->hasSecondPrologPart) parseInfo->staticContext->error(QtXmlPatterns::tr("Module imports must occur before function, " "variable, and option declarations."), ReportContext::XPST0003, fromYYLTYPE((yyloc), parseInfo)); @@ -3931,7 +3965,7 @@ yyreduce: case 17: /* Line 1269 of yacc.c. */ -#line 1531 "querytransformparser.ypp" +#line 1565 "querytransformparser.ypp" { parseInfo->hasSecondPrologPart = true; } @@ -3939,7 +3973,7 @@ yyreduce: case 18: /* Line 1269 of yacc.c. */ -#line 1535 "querytransformparser.ypp" +#line 1569 "querytransformparser.ypp" { parseInfo->hasSecondPrologPart = true; } @@ -3947,16 +3981,16 @@ yyreduce: case 19: /* Line 1269 of yacc.c. */ -#line 1539 "querytransformparser.ypp" +#line 1573 "querytransformparser.ypp" { - disallowedConstruct(parseInfo, (yyloc)); + allowedIn(QXmlQuery::XQuery10, parseInfo, (yyloc)); parseInfo->hasSecondPrologPart = true; } break; case 20: /* Line 1269 of yacc.c. */ -#line 1562 "querytransformparser.ypp" +#line 1596 "querytransformparser.ypp" { Template::Ptr temp(create(new Template(parseInfo->currentImportPrecedence, (yyvsp[(5) - (7)].sequenceType)), (yyloc), parseInfo)); @@ -3969,7 +4003,7 @@ yyreduce: case 21: /* Line 1269 of yacc.c. */ -#line 1572 "querytransformparser.ypp" +#line 1606 "querytransformparser.ypp" { parseInfo->isParsingPattern = true; } @@ -3977,7 +4011,7 @@ yyreduce: case 22: /* Line 1269 of yacc.c. */ -#line 1576 "querytransformparser.ypp" +#line 1610 "querytransformparser.ypp" { parseInfo->isParsingPattern = false; } @@ -3985,7 +4019,7 @@ yyreduce: case 23: /* Line 1269 of yacc.c. */ -#line 1585 "querytransformparser.ypp" +#line 1619 "querytransformparser.ypp" { /* In this grammar branch, we're guaranteed to be a template rule, but * may also be a named template. */ @@ -4042,7 +4076,7 @@ yyreduce: case 24: /* Line 1269 of yacc.c. */ -#line 1639 "querytransformparser.ypp" +#line 1673 "querytransformparser.ypp" { (yyval.enums.Double) = std::numeric_limits::quiet_NaN(); } @@ -4050,7 +4084,7 @@ yyreduce: case 25: /* Line 1269 of yacc.c. */ -#line 1644 "querytransformparser.ypp" +#line 1678 "querytransformparser.ypp" { const AtomicValue::Ptr val(Decimal::fromLexical((yyvsp[(2) - (2)].sval))); if(val->hasError()) @@ -4069,7 +4103,7 @@ yyreduce: case 26: /* Line 1269 of yacc.c. */ -#line 1660 "querytransformparser.ypp" +#line 1694 "querytransformparser.ypp" { (yyval.qName) = QXmlName(); } @@ -4077,7 +4111,7 @@ yyreduce: case 28: /* Line 1269 of yacc.c. */ -#line 1666 "querytransformparser.ypp" +#line 1700 "querytransformparser.ypp" { (yyval.qName) = (yyvsp[(2) - (2)].qName); } @@ -4085,42 +4119,42 @@ yyreduce: case 30: /* Line 1269 of yacc.c. */ -#line 1672 "querytransformparser.ypp" +#line 1706 "querytransformparser.ypp" { - disallowedConstruct(parseInfo, (yyloc)); + allowedIn(QXmlQuery::XQuery10, parseInfo, (yyloc)); } break; case 32: /* Line 1269 of yacc.c. */ -#line 1677 "querytransformparser.ypp" +#line 1711 "querytransformparser.ypp" { - disallowedConstruct(parseInfo, (yyloc)); + allowedIn(QXmlQuery::XQuery10, parseInfo, (yyloc)); } break; case 33: /* Line 1269 of yacc.c. */ -#line 1681 "querytransformparser.ypp" +#line 1715 "querytransformparser.ypp" { - disallowedConstruct(parseInfo, (yyloc)); + allowedIn(QXmlQuery::XQuery10, parseInfo, (yyloc)); } break; case 34: /* Line 1269 of yacc.c. */ -#line 1685 "querytransformparser.ypp" +#line 1719 "querytransformparser.ypp" { - disallowedConstruct(parseInfo, (yyloc)); + allowedIn(QXmlQuery::XQuery10, parseInfo, (yyloc)); } break; case 39: /* Line 1269 of yacc.c. */ -#line 1696 "querytransformparser.ypp" +#line 1730 "querytransformparser.ypp" { if(!(yyvsp[(6) - (7)].enums.Bool)) - disallowedConstruct(parseInfo, (yyloc)); + allowedIn(QXmlQuery::XQuery10, parseInfo, (yyloc)); if((yyvsp[(3) - (7)].sval) == QLatin1String("xmlns")) { @@ -4166,7 +4200,7 @@ yyreduce: case 40: /* Line 1269 of yacc.c. */ -#line 1742 "querytransformparser.ypp" +#line 1776 "querytransformparser.ypp" { if(parseInfo->hasDeclaration(ParserContext::BoundarySpaceDecl)) { @@ -4183,7 +4217,7 @@ yyreduce: case 41: /* Line 1269 of yacc.c. */ -#line 1756 "querytransformparser.ypp" +#line 1790 "querytransformparser.ypp" { (yyval.enums.boundarySpacePolicy) = StaticContext::BSPStrip; } @@ -4191,7 +4225,7 @@ yyreduce: case 42: /* Line 1269 of yacc.c. */ -#line 1761 "querytransformparser.ypp" +#line 1795 "querytransformparser.ypp" { (yyval.enums.boundarySpacePolicy) = StaticContext::BSPPreserve; } @@ -4199,7 +4233,7 @@ yyreduce: case 45: /* Line 1269 of yacc.c. */ -#line 1770 "querytransformparser.ypp" +#line 1804 "querytransformparser.ypp" { if(parseInfo->hasDeclaration(ParserContext::DeclareDefaultElementNamespace)) { @@ -4216,7 +4250,7 @@ yyreduce: case 46: /* Line 1269 of yacc.c. */ -#line 1785 "querytransformparser.ypp" +#line 1819 "querytransformparser.ypp" { if(parseInfo->hasDeclaration(ParserContext::DeclareDefaultFunctionNamespace)) { @@ -4233,7 +4267,7 @@ yyreduce: case 47: /* Line 1269 of yacc.c. */ -#line 1799 "querytransformparser.ypp" +#line 1833 "querytransformparser.ypp" { if((yyvsp[(3) - (5)].qName).prefix() == StandardPrefixes::empty) { @@ -4246,9 +4280,9 @@ yyreduce: case 48: /* Line 1269 of yacc.c. */ -#line 1809 "querytransformparser.ypp" +#line 1843 "querytransformparser.ypp" { - disallowedConstruct(parseInfo, (yyloc)); + allowedIn(QXmlQuery::XQuery10, parseInfo, (yyloc)); if(parseInfo->hasDeclaration(ParserContext::OrderingModeDecl)) { parseInfo->staticContext->error(prologMessage("declare ordering"), @@ -4264,7 +4298,7 @@ yyreduce: case 49: /* Line 1269 of yacc.c. */ -#line 1824 "querytransformparser.ypp" +#line 1858 "querytransformparser.ypp" { (yyval.enums.orderingMode) = StaticContext::Ordered; } @@ -4272,7 +4306,7 @@ yyreduce: case 50: /* Line 1269 of yacc.c. */ -#line 1828 "querytransformparser.ypp" +#line 1862 "querytransformparser.ypp" { (yyval.enums.orderingMode) = StaticContext::Unordered; } @@ -4280,7 +4314,7 @@ yyreduce: case 51: /* Line 1269 of yacc.c. */ -#line 1833 "querytransformparser.ypp" +#line 1867 "querytransformparser.ypp" { if(parseInfo->hasDeclaration(ParserContext::EmptyOrderDecl)) { @@ -4297,7 +4331,7 @@ yyreduce: case 52: /* Line 1269 of yacc.c. */ -#line 1847 "querytransformparser.ypp" +#line 1881 "querytransformparser.ypp" { (yyval.enums.orderingEmptySequence) = StaticContext::Least; } @@ -4305,7 +4339,7 @@ yyreduce: case 53: /* Line 1269 of yacc.c. */ -#line 1851 "querytransformparser.ypp" +#line 1885 "querytransformparser.ypp" { (yyval.enums.orderingEmptySequence) = StaticContext::Greatest; } @@ -4313,7 +4347,7 @@ yyreduce: case 54: /* Line 1269 of yacc.c. */ -#line 1857 "querytransformparser.ypp" +#line 1891 "querytransformparser.ypp" { if(parseInfo->hasDeclaration(ParserContext::CopyNamespacesDecl)) { @@ -4329,7 +4363,7 @@ yyreduce: case 55: /* Line 1269 of yacc.c. */ -#line 1870 "querytransformparser.ypp" +#line 1904 "querytransformparser.ypp" { parseInfo->preserveNamespacesMode = true; } @@ -4337,7 +4371,7 @@ yyreduce: case 56: /* Line 1269 of yacc.c. */ -#line 1875 "querytransformparser.ypp" +#line 1909 "querytransformparser.ypp" { parseInfo->preserveNamespacesMode = false; } @@ -4345,7 +4379,7 @@ yyreduce: case 57: /* Line 1269 of yacc.c. */ -#line 1880 "querytransformparser.ypp" +#line 1914 "querytransformparser.ypp" { parseInfo->inheritNamespacesMode = true; } @@ -4353,7 +4387,7 @@ yyreduce: case 58: /* Line 1269 of yacc.c. */ -#line 1885 "querytransformparser.ypp" +#line 1919 "querytransformparser.ypp" { parseInfo->inheritNamespacesMode = false; } @@ -4361,7 +4395,7 @@ yyreduce: case 59: /* Line 1269 of yacc.c. */ -#line 1890 "querytransformparser.ypp" +#line 1924 "querytransformparser.ypp" { if(parseInfo->hasDeclaration(ParserContext::DefaultCollationDecl)) { @@ -4380,9 +4414,9 @@ yyreduce: case 60: /* Line 1269 of yacc.c. */ -#line 1906 "querytransformparser.ypp" +#line 1940 "querytransformparser.ypp" { - disallowedConstruct(parseInfo, (yyloc), (yyvsp[(3) - (5)].enums.Bool)); + allowedIn(QueryLanguages(QXmlQuery::XQuery10 | QXmlQuery::XSLT20), parseInfo, (yyloc), (yyvsp[(3) - (5)].enums.Bool)); if(parseInfo->hasDeclaration(ParserContext::BaseURIDecl)) { parseInfo->staticContext->error(prologMessage("declare base-uri"), @@ -4406,7 +4440,7 @@ yyreduce: case 61: /* Line 1269 of yacc.c. */ -#line 1929 "querytransformparser.ypp" +#line 1963 "querytransformparser.ypp" { parseInfo->staticContext->error(QtXmlPatterns::tr("The Schema Import feature is not supported, " "and therefore %1 declarations cannot occur.") @@ -4417,7 +4451,7 @@ yyreduce: case 65: /* Line 1269 of yacc.c. */ -#line 1941 "querytransformparser.ypp" +#line 1975 "querytransformparser.ypp" { if((yyvsp[(4) - (6)].sval).isEmpty()) { @@ -4437,9 +4471,9 @@ yyreduce: case 72: /* Line 1269 of yacc.c. */ -#line 1968 "querytransformparser.ypp" +#line 2002 "querytransformparser.ypp" { - disallowedConstruct(parseInfo, (yyloc), (yyvsp[(3) - (9)].enums.Bool)); + allowedIn(QXmlQuery::XQuery10, parseInfo, (yyloc), (yyvsp[(3) - (9)].enums.Bool)); if(variableByName((yyvsp[(5) - (9)].qName), parseInfo)) { parseInfo->staticContext->error(QtXmlPatterns::tr("A variable by name %1 has already " @@ -4494,7 +4528,7 @@ yyreduce: case 73: /* Line 1269 of yacc.c. */ -#line 2022 "querytransformparser.ypp" +#line 2056 "querytransformparser.ypp" { (yyval.expr).reset(); } @@ -4502,7 +4536,7 @@ yyreduce: case 74: /* Line 1269 of yacc.c. */ -#line 2026 "querytransformparser.ypp" +#line 2060 "querytransformparser.ypp" { (yyval.expr) = (yyvsp[(2) - (2)].expr); } @@ -4510,7 +4544,7 @@ yyreduce: case 75: /* Line 1269 of yacc.c. */ -#line 2031 "querytransformparser.ypp" +#line 2065 "querytransformparser.ypp" { (yyval.expr).reset(); } @@ -4518,7 +4552,7 @@ yyreduce: case 76: /* Line 1269 of yacc.c. */ -#line 2035 "querytransformparser.ypp" +#line 2069 "querytransformparser.ypp" { (yyval.expr) = (yyvsp[(2) - (2)].expr); } @@ -4526,7 +4560,7 @@ yyreduce: case 77: /* Line 1269 of yacc.c. */ -#line 2040 "querytransformparser.ypp" +#line 2074 "querytransformparser.ypp" { if(parseInfo->hasDeclaration(ParserContext::ConstructionDecl)) { @@ -4543,7 +4577,7 @@ yyreduce: case 78: /* Line 1269 of yacc.c. */ -#line 2054 "querytransformparser.ypp" +#line 2088 "querytransformparser.ypp" { (yyval.enums.constructionMode) = StaticContext::CMStrip; } @@ -4551,7 +4585,7 @@ yyreduce: case 79: /* Line 1269 of yacc.c. */ -#line 2058 "querytransformparser.ypp" +#line 2092 "querytransformparser.ypp" { (yyval.enums.constructionMode) = StaticContext::CMPreserve; } @@ -4559,7 +4593,7 @@ yyreduce: case 80: /* Line 1269 of yacc.c. */ -#line 2063 "querytransformparser.ypp" +#line 2097 "querytransformparser.ypp" { (yyval.enums.slot) = parseInfo->currentExpressionSlot() - (yyvsp[(6) - (7)].functionArguments).count(); } @@ -4567,10 +4601,10 @@ yyreduce: case 81: /* Line 1269 of yacc.c. */ -#line 2067 "querytransformparser.ypp" +#line 2101 "querytransformparser.ypp" { if(!(yyvsp[(3) - (11)].enums.Bool)) - disallowedConstruct(parseInfo, (yyloc), (yyvsp[(3) - (11)].enums.Bool)); + allowedIn(QXmlQuery::XQuery10, parseInfo, (yyloc), (yyvsp[(3) - (11)].enums.Bool)); /* If FunctionBody is null, it is 'external', otherwise the value is the body. */ const QXmlName::NamespaceCode ns((yyvsp[(4) - (11)].qName).namespaceURI()); @@ -4674,7 +4708,7 @@ yyreduce: case 82: /* Line 1269 of yacc.c. */ -#line 2171 "querytransformparser.ypp" +#line 2205 "querytransformparser.ypp" { (yyval.functionArguments) = FunctionArgument::List(); } @@ -4682,7 +4716,7 @@ yyreduce: case 83: /* Line 1269 of yacc.c. */ -#line 2175 "querytransformparser.ypp" +#line 2209 "querytransformparser.ypp" { FunctionArgument::List l; l.append((yyvsp[(1) - (1)].functionArgument)); @@ -4692,7 +4726,7 @@ yyreduce: case 84: /* Line 1269 of yacc.c. */ -#line 2181 "querytransformparser.ypp" +#line 2215 "querytransformparser.ypp" { FunctionArgument::List::const_iterator it((yyvsp[(1) - (3)].functionArguments).constBegin()); const FunctionArgument::List::const_iterator end((yyvsp[(1) - (3)].functionArguments).constEnd()); @@ -4716,7 +4750,7 @@ yyreduce: case 85: /* Line 1269 of yacc.c. */ -#line 2202 "querytransformparser.ypp" +#line 2236 "querytransformparser.ypp" { pushVariable((yyvsp[(2) - (3)].qName), (yyvsp[(3) - (3)].sequenceType), Expression::Ptr(), VariableDeclaration::FunctionArgument, (yyloc), parseInfo); (yyval.functionArgument) = FunctionArgument::Ptr(new FunctionArgument((yyvsp[(2) - (3)].qName), (yyvsp[(3) - (3)].sequenceType))); @@ -4725,7 +4759,7 @@ yyreduce: case 86: /* Line 1269 of yacc.c. */ -#line 2208 "querytransformparser.ypp" +#line 2242 "querytransformparser.ypp" { (yyval.expr).reset(); } @@ -4733,7 +4767,7 @@ yyreduce: case 88: /* Line 1269 of yacc.c. */ -#line 2214 "querytransformparser.ypp" +#line 2248 "querytransformparser.ypp" { (yyval.expr) = (yyvsp[(2) - (3)].expr); } @@ -4741,7 +4775,7 @@ yyreduce: case 91: /* Line 1269 of yacc.c. */ -#line 2230 "querytransformparser.ypp" +#line 2264 "querytransformparser.ypp" { (yyval.expr) = create(new CombineNodes((yyvsp[(1) - (3)].expr), CombineNodes::Union, (yyvsp[(3) - (3)].expr)), (yyloc), parseInfo); } @@ -4749,7 +4783,7 @@ yyreduce: case 93: /* Line 1269 of yacc.c. */ -#line 2236 "querytransformparser.ypp" +#line 2270 "querytransformparser.ypp" { /* We write this into a node test. The spec says, 5.5.3 The Meaning of a Pattern: * "Similarly, / matches a document node, and only a document node, @@ -4762,7 +4796,7 @@ yyreduce: case 94: /* Line 1269 of yacc.c. */ -#line 2245 "querytransformparser.ypp" +#line 2279 "querytransformparser.ypp" { /* /axis::node-test * => @@ -4836,7 +4870,7 @@ yyreduce: case 95: /* Line 1269 of yacc.c. */ -#line 2315 "querytransformparser.ypp" +#line 2349 "querytransformparser.ypp" { /* //axis::node-test * => @@ -4851,7 +4885,7 @@ yyreduce: case 97: /* Line 1269 of yacc.c. */ -#line 2327 "querytransformparser.ypp" +#line 2361 "querytransformparser.ypp" { createIdPatternPath((yyvsp[(1) - (3)].expr), (yyvsp[(3) - (3)].expr), QXmlNodeModelIndex::AxisParent, (yylsp[(2) - (3)]), parseInfo); } @@ -4859,7 +4893,7 @@ yyreduce: case 98: /* Line 1269 of yacc.c. */ -#line 2331 "querytransformparser.ypp" +#line 2365 "querytransformparser.ypp" { createIdPatternPath((yyvsp[(1) - (3)].expr), (yyvsp[(3) - (3)].expr), QXmlNodeModelIndex::AxisAncestor, (yylsp[(2) - (3)]), parseInfo); } @@ -4867,7 +4901,7 @@ yyreduce: case 99: /* Line 1269 of yacc.c. */ -#line 2336 "querytransformparser.ypp" +#line 2370 "querytransformparser.ypp" { const Expression::List ands((yyvsp[(1) - (1)].expr)->operands()); const FunctionSignature::Ptr signature((yyvsp[(1) - (1)].expr)->as()->signature()); @@ -4939,7 +4973,7 @@ yyreduce: case 101: /* Line 1269 of yacc.c. */ -#line 2406 "querytransformparser.ypp" +#line 2440 "querytransformparser.ypp" { (yyval.expr) = createPatternPath((yyvsp[(1) - (3)].expr), (yyvsp[(3) - (3)].expr), QXmlNodeModelIndex::AxisParent, (yylsp[(2) - (3)]), parseInfo); } @@ -4947,7 +4981,7 @@ yyreduce: case 102: /* Line 1269 of yacc.c. */ -#line 2410 "querytransformparser.ypp" +#line 2444 "querytransformparser.ypp" { (yyval.expr) = createPatternPath((yyvsp[(1) - (3)].expr), (yyvsp[(3) - (3)].expr), QXmlNodeModelIndex::AxisAncestor, (yylsp[(2) - (3)]), parseInfo); } @@ -4955,7 +4989,7 @@ yyreduce: case 103: /* Line 1269 of yacc.c. */ -#line 2415 "querytransformparser.ypp" +#line 2449 "querytransformparser.ypp" { const Expression::Ptr expr(findAxisStep((yyvsp[(1) - (1)].expr))); @@ -5002,7 +5036,7 @@ yyreduce: case 105: /* Line 1269 of yacc.c. */ -#line 2460 "querytransformparser.ypp" +#line 2494 "querytransformparser.ypp" { (yyval.expr) = create(new ExpressionSequence((yyvsp[(1) - (1)].expressionList)), (yyloc), parseInfo); } @@ -5010,7 +5044,7 @@ yyreduce: case 106: /* Line 1269 of yacc.c. */ -#line 2465 "querytransformparser.ypp" +#line 2499 "querytransformparser.ypp" { Expression::List l; l.append((yyvsp[(1) - (3)].expr)); @@ -5021,7 +5055,7 @@ yyreduce: case 107: /* Line 1269 of yacc.c. */ -#line 2472 "querytransformparser.ypp" +#line 2506 "querytransformparser.ypp" { (yyvsp[(1) - (3)].expressionList).append((yyvsp[(3) - (3)].expr)); (yyval.expressionList) = (yyvsp[(1) - (3)].expressionList); @@ -5030,7 +5064,7 @@ yyreduce: case 113: /* Line 1269 of yacc.c. */ -#line 2483 "querytransformparser.ypp" +#line 2517 "querytransformparser.ypp" { (yyval.expr) = createDirAttributeValue((yyvsp[(3) - (4)].expressionList), parseInfo, (yyloc)); } @@ -5038,7 +5072,7 @@ yyreduce: case 114: /* Line 1269 of yacc.c. */ -#line 2488 "querytransformparser.ypp" +#line 2522 "querytransformparser.ypp" { QVector result; result.append(QXmlName(StandardNamespaces::InternalXSLT, StandardLocalNames::Default)); @@ -5048,7 +5082,7 @@ yyreduce: case 115: /* Line 1269 of yacc.c. */ -#line 2494 "querytransformparser.ypp" +#line 2528 "querytransformparser.ypp" { (yyval.qNameVector) = (yyvsp[(2) - (2)].qNameVector); } @@ -5056,7 +5090,7 @@ yyreduce: case 116: /* Line 1269 of yacc.c. */ -#line 2499 "querytransformparser.ypp" +#line 2533 "querytransformparser.ypp" { (yyval.qName) = QXmlName(StandardNamespaces::InternalXSLT, StandardLocalNames::Default); } @@ -5064,7 +5098,7 @@ yyreduce: case 117: /* Line 1269 of yacc.c. */ -#line 2503 "querytransformparser.ypp" +#line 2537 "querytransformparser.ypp" { (yyval.qName) = (yyvsp[(2) - (2)].qName); } @@ -5072,7 +5106,7 @@ yyreduce: case 118: /* Line 1269 of yacc.c. */ -#line 2508 "querytransformparser.ypp" +#line 2542 "querytransformparser.ypp" { QVector result; result.append((yyvsp[(1) - (1)].qName)); @@ -5082,7 +5116,7 @@ yyreduce: case 119: /* Line 1269 of yacc.c. */ -#line 2514 "querytransformparser.ypp" +#line 2548 "querytransformparser.ypp" { (yyvsp[(1) - (3)].qNameVector).append((yyvsp[(3) - (3)].qName)); (yyval.qNameVector) = (yyvsp[(1) - (3)].qNameVector); @@ -5091,7 +5125,7 @@ yyreduce: case 120: /* Line 1269 of yacc.c. */ -#line 2520 "querytransformparser.ypp" +#line 2554 "querytransformparser.ypp" { (yyval.qName) = (yyvsp[(1) - (1)].qName); } @@ -5099,7 +5133,7 @@ yyreduce: case 121: /* Line 1269 of yacc.c. */ -#line 2524 "querytransformparser.ypp" +#line 2558 "querytransformparser.ypp" { if((yyvsp[(1) - (1)].sval) == QLatin1String("#current")) (yyval.qName) = QXmlName(StandardNamespaces::InternalXSLT, StandardLocalNames::current); @@ -5126,7 +5160,7 @@ yyreduce: case 124: /* Line 1269 of yacc.c. */ -#line 2553 "querytransformparser.ypp" +#line 2587 "querytransformparser.ypp" { /* We're pushing the range variable here, not the positional. */ (yyval.expr) = pushVariable((yyvsp[(3) - (7)].qName), quantificationType((yyvsp[(4) - (7)].sequenceType)), (yyvsp[(7) - (7)].expr), VariableDeclaration::RangeVariable, (yyloc), parseInfo); @@ -5135,7 +5169,7 @@ yyreduce: case 125: /* Line 1269 of yacc.c. */ -#line 2557 "querytransformparser.ypp" +#line 2591 "querytransformparser.ypp" { /* It is ok this appears after PositionalVar, because currentRangeSlot() * uses a different "channel" than currentPositionSlot(), so they can't trash @@ -5146,7 +5180,7 @@ yyreduce: case 126: /* Line 1269 of yacc.c. */ -#line 2564 "querytransformparser.ypp" +#line 2598 "querytransformparser.ypp" { Q_ASSERT((yyvsp[(7) - (10)].expr)); Q_ASSERT((yyvsp[(10) - (10)].expr)); @@ -5182,7 +5216,7 @@ yyreduce: case 127: /* Line 1269 of yacc.c. */ -#line 2598 "querytransformparser.ypp" +#line 2632 "querytransformparser.ypp" { pushVariable((yyvsp[(3) - (7)].qName), quantificationType((yyvsp[(4) - (7)].sequenceType)), (yyvsp[(7) - (7)].expr), VariableDeclaration::RangeVariable, (yyloc), parseInfo); } @@ -5190,7 +5224,7 @@ yyreduce: case 128: /* Line 1269 of yacc.c. */ -#line 2601 "querytransformparser.ypp" +#line 2635 "querytransformparser.ypp" { /* It is ok this appears after PositionalVar, because currentRangeSlot() * uses a different "channel" than currentPositionSlot(), so they can't trash @@ -5201,7 +5235,7 @@ yyreduce: case 129: /* Line 1269 of yacc.c. */ -#line 2608 "querytransformparser.ypp" +#line 2642 "querytransformparser.ypp" { (yyval.expr) = create(new ForClause((yyvsp[(9) - (10)].enums.slot), (yyvsp[(7) - (10)].expr), (yyvsp[(10) - (10)].expr), (yyvsp[(5) - (10)].enums.slot)), (yyloc), parseInfo); @@ -5214,7 +5248,7 @@ yyreduce: case 133: /* Line 1269 of yacc.c. */ -#line 2622 "querytransformparser.ypp" +#line 2656 "querytransformparser.ypp" { (yyval.enums.slot) = -1; } @@ -5222,7 +5256,7 @@ yyreduce: case 134: /* Line 1269 of yacc.c. */ -#line 2627 "querytransformparser.ypp" +#line 2661 "querytransformparser.ypp" { pushVariable((yyvsp[(3) - (3)].qName), CommonSequenceTypes::ExactlyOneInteger, Expression::Ptr(), VariableDeclaration::PositionalVariable, (yyloc), parseInfo); @@ -5232,7 +5266,7 @@ yyreduce: case 135: /* Line 1269 of yacc.c. */ -#line 2634 "querytransformparser.ypp" +#line 2668 "querytransformparser.ypp" { (yyval.expr) = pushVariable((yyvsp[(4) - (7)].qName), quantificationType((yyvsp[(5) - (7)].sequenceType)), (yyvsp[(7) - (7)].expr), VariableDeclaration::ExpressionVariable, (yyloc), parseInfo); } @@ -5240,9 +5274,9 @@ yyreduce: case 136: /* Line 1269 of yacc.c. */ -#line 2638 "querytransformparser.ypp" +#line 2672 "querytransformparser.ypp" { - disallowedConstruct(parseInfo, (yyloc), (yyvsp[(2) - (9)].enums.Bool)); + allowedIn(QXmlQuery::XQuery10, parseInfo, (yyloc), (yyvsp[(2) - (9)].enums.Bool)); Q_ASSERT(parseInfo->variables.top()->name == (yyvsp[(4) - (9)].qName)); (yyval.expr) = create(new LetClause((yyvsp[(8) - (9)].expr), (yyvsp[(9) - (9)].expr), parseInfo->variables.top()), (yyloc), parseInfo); @@ -5252,13 +5286,13 @@ yyreduce: case 137: /* Line 1269 of yacc.c. */ -#line 2647 "querytransformparser.ypp" +#line 2681 "querytransformparser.ypp" { (yyval.expr) = pushVariable((yyvsp[(3) - (6)].qName), quantificationType((yyvsp[(4) - (6)].sequenceType)), (yyvsp[(6) - (6)].expr), VariableDeclaration::ExpressionVariable, (yyloc), parseInfo);} break; case 138: /* Line 1269 of yacc.c. */ -#line 2649 "querytransformparser.ypp" +#line 2683 "querytransformparser.ypp" { Q_ASSERT(parseInfo->variables.top()->name == (yyvsp[(3) - (8)].qName)); (yyval.expr) = create(new LetClause((yyvsp[(7) - (8)].expr), (yyvsp[(8) - (8)].expr), parseInfo->variables.top()), (yyloc), parseInfo); @@ -5268,7 +5302,7 @@ yyreduce: case 142: /* Line 1269 of yacc.c. */ -#line 2660 "querytransformparser.ypp" +#line 2694 "querytransformparser.ypp" { if((yyvsp[(1) - (3)].orderSpecs).isEmpty()) (yyval.expr) = (yyvsp[(3) - (3)].expr); @@ -5279,7 +5313,7 @@ yyreduce: case 143: /* Line 1269 of yacc.c. */ -#line 2668 "querytransformparser.ypp" +#line 2702 "querytransformparser.ypp" { if((yyvsp[(3) - (5)].orderSpecs).isEmpty()) (yyval.expr) = create(new IfThenClause((yyvsp[(2) - (5)].expr), (yyvsp[(5) - (5)].expr), create(new EmptySequence, (yyloc), parseInfo)), (yyloc), parseInfo); @@ -5292,7 +5326,7 @@ yyreduce: case 144: /* Line 1269 of yacc.c. */ -#line 2678 "querytransformparser.ypp" +#line 2712 "querytransformparser.ypp" { (yyval.orderSpecs) = OrderSpecTransfer::List(); } @@ -5300,7 +5334,7 @@ yyreduce: case 146: /* Line 1269 of yacc.c. */ -#line 2684 "querytransformparser.ypp" +#line 2718 "querytransformparser.ypp" { (yyval.orderSpecs) = (yyvsp[(2) - (2)].orderSpecs); } @@ -5308,7 +5342,7 @@ yyreduce: case 147: /* Line 1269 of yacc.c. */ -#line 2689 "querytransformparser.ypp" +#line 2723 "querytransformparser.ypp" { OrderSpecTransfer::List list; list += (yyvsp[(1) - (3)].orderSpecs); @@ -5319,7 +5353,7 @@ yyreduce: case 148: /* Line 1269 of yacc.c. */ -#line 2696 "querytransformparser.ypp" +#line 2730 "querytransformparser.ypp" { OrderSpecTransfer::List list; list.append((yyvsp[(1) - (1)].orderSpec)); @@ -5329,7 +5363,7 @@ yyreduce: case 149: /* Line 1269 of yacc.c. */ -#line 2703 "querytransformparser.ypp" +#line 2737 "querytransformparser.ypp" { (yyval.orderSpec) = OrderSpecTransfer((yyvsp[(1) - (4)].expr), OrderBy::OrderSpec((yyvsp[(2) - (4)].enums.sortDirection), (yyvsp[(3) - (4)].enums.orderingEmptySequence))); } @@ -5337,7 +5371,7 @@ yyreduce: case 150: /* Line 1269 of yacc.c. */ -#line 2708 "querytransformparser.ypp" +#line 2742 "querytransformparser.ypp" { /* Where does the specification state the default value is ascending? * @@ -5361,7 +5395,7 @@ yyreduce: case 151: /* Line 1269 of yacc.c. */ -#line 2729 "querytransformparser.ypp" +#line 2763 "querytransformparser.ypp" { (yyval.enums.sortDirection) = OrderBy::OrderSpec::Ascending; } @@ -5369,7 +5403,7 @@ yyreduce: case 152: /* Line 1269 of yacc.c. */ -#line 2734 "querytransformparser.ypp" +#line 2768 "querytransformparser.ypp" { (yyval.enums.sortDirection) = OrderBy::OrderSpec::Descending; } @@ -5377,7 +5411,7 @@ yyreduce: case 153: /* Line 1269 of yacc.c. */ -#line 2739 "querytransformparser.ypp" +#line 2773 "querytransformparser.ypp" { (yyval.enums.orderingEmptySequence) = parseInfo->staticContext->orderingEmptySequence(); } @@ -5385,7 +5419,7 @@ yyreduce: case 156: /* Line 1269 of yacc.c. */ -#line 2746 "querytransformparser.ypp" +#line 2780 "querytransformparser.ypp" { if(parseInfo->isXSLT()) resolveAndCheckCollation((yyvsp[(2) - (2)].sval), parseInfo, (yyloc)); @@ -5396,7 +5430,7 @@ yyreduce: case 157: /* Line 1269 of yacc.c. */ -#line 2753 "querytransformparser.ypp" +#line 2787 "querytransformparser.ypp" { /* We do nothing. We don't use collations, and we have this non-terminal * in order to accept expressions. */ @@ -5405,7 +5439,7 @@ yyreduce: case 158: /* Line 1269 of yacc.c. */ -#line 2759 "querytransformparser.ypp" +#line 2793 "querytransformparser.ypp" { parseInfo->orderStability.push(OrderBy::StableOrder); } @@ -5413,7 +5447,7 @@ yyreduce: case 159: /* Line 1269 of yacc.c. */ -#line 2763 "querytransformparser.ypp" +#line 2797 "querytransformparser.ypp" { parseInfo->orderStability.push(OrderBy::UnstableOrder); } @@ -5421,7 +5455,7 @@ yyreduce: case 162: /* Line 1269 of yacc.c. */ -#line 2771 "querytransformparser.ypp" +#line 2805 "querytransformparser.ypp" { pushVariable((yyvsp[(3) - (6)].qName), quantificationType((yyvsp[(4) - (6)].sequenceType)), (yyvsp[(6) - (6)].expr), VariableDeclaration::RangeVariable, (yyloc), parseInfo); @@ -5430,14 +5464,15 @@ yyreduce: case 163: /* Line 1269 of yacc.c. */ -#line 2775 "querytransformparser.ypp" +#line 2809 "querytransformparser.ypp" {(yyval.enums.slot) = parseInfo->staticContext->currentRangeSlot();} break; case 164: /* Line 1269 of yacc.c. */ -#line 2777 "querytransformparser.ypp" +#line 2811 "querytransformparser.ypp" { + allowedIn(QueryLanguages(QXmlQuery::XQuery10 | QXmlQuery::XPath20), parseInfo, (yyloc)); (yyval.expr) = create(new QuantifiedExpression((yyvsp[(8) - (9)].enums.slot), QuantifiedExpression::Some, (yyvsp[(6) - (9)].expr), (yyvsp[(9) - (9)].expr)), (yyloc), parseInfo); parseInfo->finalizePushedVariable(); @@ -5446,7 +5481,7 @@ yyreduce: case 165: /* Line 1269 of yacc.c. */ -#line 2784 "querytransformparser.ypp" +#line 2819 "querytransformparser.ypp" { (yyval.expr) = pushVariable((yyvsp[(3) - (6)].qName), quantificationType((yyvsp[(4) - (6)].sequenceType)), (yyvsp[(6) - (6)].expr), VariableDeclaration::RangeVariable, (yyloc), parseInfo); @@ -5455,13 +5490,13 @@ yyreduce: case 166: /* Line 1269 of yacc.c. */ -#line 2788 "querytransformparser.ypp" +#line 2823 "querytransformparser.ypp" {(yyval.enums.slot) = parseInfo->staticContext->currentRangeSlot();} break; case 167: /* Line 1269 of yacc.c. */ -#line 2790 "querytransformparser.ypp" +#line 2825 "querytransformparser.ypp" { (yyval.expr) = create(new QuantifiedExpression((yyvsp[(8) - (9)].enums.slot), QuantifiedExpression::Some, (yyvsp[(7) - (9)].expr), (yyvsp[(9) - (9)].expr)), (yyloc), parseInfo); @@ -5471,7 +5506,7 @@ yyreduce: case 169: /* Line 1269 of yacc.c. */ -#line 2799 "querytransformparser.ypp" +#line 2834 "querytransformparser.ypp" { pushVariable((yyvsp[(3) - (6)].qName), quantificationType((yyvsp[(4) - (6)].sequenceType)), (yyvsp[(6) - (6)].expr), VariableDeclaration::RangeVariable, (yyloc), parseInfo); @@ -5480,14 +5515,15 @@ yyreduce: case 170: /* Line 1269 of yacc.c. */ -#line 2803 "querytransformparser.ypp" +#line 2838 "querytransformparser.ypp" {(yyval.enums.slot) = parseInfo->staticContext->currentRangeSlot();} break; case 171: /* Line 1269 of yacc.c. */ -#line 2805 "querytransformparser.ypp" +#line 2840 "querytransformparser.ypp" { + allowedIn(QueryLanguages(QXmlQuery::XQuery10 | QXmlQuery::XPath20), parseInfo, (yyloc)); (yyval.expr) = create(new QuantifiedExpression((yyvsp[(8) - (9)].enums.slot), QuantifiedExpression::Every, (yyvsp[(6) - (9)].expr), (yyvsp[(9) - (9)].expr)), (yyloc), parseInfo); parseInfo->finalizePushedVariable(); @@ -5496,7 +5532,7 @@ yyreduce: case 172: /* Line 1269 of yacc.c. */ -#line 2812 "querytransformparser.ypp" +#line 2848 "querytransformparser.ypp" { (yyval.expr) = pushVariable((yyvsp[(3) - (6)].qName), quantificationType((yyvsp[(4) - (6)].sequenceType)), (yyvsp[(6) - (6)].expr), VariableDeclaration::RangeVariable, (yyloc), parseInfo); @@ -5505,13 +5541,13 @@ yyreduce: case 173: /* Line 1269 of yacc.c. */ -#line 2816 "querytransformparser.ypp" +#line 2852 "querytransformparser.ypp" {(yyval.enums.slot) = parseInfo->staticContext->currentRangeSlot();} break; case 174: /* Line 1269 of yacc.c. */ -#line 2818 "querytransformparser.ypp" +#line 2854 "querytransformparser.ypp" { (yyval.expr) = create(new QuantifiedExpression((yyvsp[(8) - (9)].enums.slot), QuantifiedExpression::Every, (yyvsp[(7) - (9)].expr), (yyvsp[(9) - (9)].expr)), (yyloc), parseInfo); @@ -5521,7 +5557,7 @@ yyreduce: case 176: /* Line 1269 of yacc.c. */ -#line 2827 "querytransformparser.ypp" +#line 2863 "querytransformparser.ypp" { (yyval.expr) = (yyvsp[(2) - (2)].expr); } @@ -5529,7 +5565,7 @@ yyreduce: case 177: /* Line 1269 of yacc.c. */ -#line 2854 "querytransformparser.ypp" +#line 2890 "querytransformparser.ypp" { parseInfo->typeswitchSource.push((yyvsp[(3) - (4)].expr)); } @@ -5537,9 +5573,9 @@ yyreduce: case 178: /* Line 1269 of yacc.c. */ -#line 2858 "querytransformparser.ypp" +#line 2894 "querytransformparser.ypp" { - disallowedConstruct(parseInfo, (yyloc)); + allowedIn(QXmlQuery::XQuery10, parseInfo, (yyloc)); parseInfo->typeswitchSource.pop(); (yyval.expr) = (yyvsp[(6) - (6)].expr); } @@ -5547,7 +5583,7 @@ yyreduce: case 179: /* Line 1269 of yacc.c. */ -#line 2865 "querytransformparser.ypp" +#line 2901 "querytransformparser.ypp" { if(!(yyvsp[(2) - (3)].qName).isNull()) { @@ -5559,7 +5595,7 @@ yyreduce: case 180: /* Line 1269 of yacc.c. */ -#line 2873 "querytransformparser.ypp" +#line 2909 "querytransformparser.ypp" { /* The variable shouldn't be in-scope for other case branches. */ if(!(yyvsp[(2) - (6)].qName).isNull()) @@ -5569,7 +5605,7 @@ yyreduce: case 181: /* Line 1269 of yacc.c. */ -#line 2879 "querytransformparser.ypp" +#line 2915 "querytransformparser.ypp" { const Expression::Ptr instanceOf(create(new InstanceOf(parseInfo->typeswitchSource.top(), (yyvsp[(3) - (8)].sequenceType)), (yyloc), parseInfo)); (yyval.expr) = create(new IfThenClause(instanceOf, (yyvsp[(6) - (8)].expr), (yyvsp[(8) - (8)].expr)), (yyloc), parseInfo); @@ -5578,7 +5614,7 @@ yyreduce: case 184: /* Line 1269 of yacc.c. */ -#line 2888 "querytransformparser.ypp" +#line 2924 "querytransformparser.ypp" { (yyval.qName) = QXmlName(); } @@ -5586,7 +5622,7 @@ yyreduce: case 185: /* Line 1269 of yacc.c. */ -#line 2893 "querytransformparser.ypp" +#line 2929 "querytransformparser.ypp" { (yyval.qName) = (yyvsp[(2) - (3)].qName); } @@ -5594,7 +5630,7 @@ yyreduce: case 186: /* Line 1269 of yacc.c. */ -#line 2898 "querytransformparser.ypp" +#line 2934 "querytransformparser.ypp" { (yyval.expr) = (yyvsp[(3) - (3)].expr); } @@ -5602,7 +5638,7 @@ yyreduce: case 187: /* Line 1269 of yacc.c. */ -#line 2902 "querytransformparser.ypp" +#line 2938 "querytransformparser.ypp" { if(!(yyvsp[(3) - (3)].qName).isNull()) { @@ -5615,7 +5651,7 @@ yyreduce: case 188: /* Line 1269 of yacc.c. */ -#line 2911 "querytransformparser.ypp" +#line 2947 "querytransformparser.ypp" { if(!(yyvsp[(3) - (6)].qName).isNull()) parseInfo->finalizePushedVariable(); @@ -5625,107 +5661,119 @@ yyreduce: case 189: /* Line 1269 of yacc.c. */ -#line 2918 "querytransformparser.ypp" +#line 2954 "querytransformparser.ypp" { + allowedIn(QueryLanguages(QXmlQuery::XQuery10 | QXmlQuery::XPath20), parseInfo, (yyloc)); (yyval.expr) = create(new IfThenClause((yyvsp[(3) - (8)].expr), (yyvsp[(6) - (8)].expr), (yyvsp[(8) - (8)].expr)), (yyloc), parseInfo); } break; case 191: /* Line 1269 of yacc.c. */ -#line 2924 "querytransformparser.ypp" +#line 2961 "querytransformparser.ypp" { + allowedIn(QueryLanguages(QXmlQuery::XQuery10 | QXmlQuery::XPath20), parseInfo, (yyloc)); (yyval.expr) = create(new OrExpression((yyvsp[(1) - (3)].expr), (yyvsp[(3) - (3)].expr)), (yyloc), parseInfo); } break; case 193: /* Line 1269 of yacc.c. */ -#line 2930 "querytransformparser.ypp" +#line 2968 "querytransformparser.ypp" { + allowedIn(QueryLanguages(QXmlQuery::XQuery10 | QXmlQuery::XPath20), parseInfo, (yyloc)); (yyval.expr) = create(new AndExpression((yyvsp[(1) - (3)].expr), (yyvsp[(3) - (3)].expr)), (yyloc), parseInfo); } break; case 199: /* Line 1269 of yacc.c. */ -#line 2941 "querytransformparser.ypp" +#line 2980 "querytransformparser.ypp" { + allowedIn(QueryLanguages(QXmlQuery::XQuery10 | QXmlQuery::XPath20), parseInfo, (yyloc)); (yyval.expr) = create(new RangeExpression((yyvsp[(1) - (3)].expr), (yyvsp[(3) - (3)].expr)), (yyloc), parseInfo); } break; case 201: /* Line 1269 of yacc.c. */ -#line 2947 "querytransformparser.ypp" +#line 2987 "querytransformparser.ypp" { + allowedIn(QueryLanguages(QXmlQuery::XQuery10 | QXmlQuery::XPath20), parseInfo, (yyloc)); (yyval.expr) = create(new ArithmeticExpression((yyvsp[(1) - (3)].expr), (yyvsp[(2) - (3)].enums.mathOperator), (yyvsp[(3) - (3)].expr)), (yyloc), parseInfo); } break; case 202: /* Line 1269 of yacc.c. */ -#line 2951 "querytransformparser.ypp" +#line 2992 "querytransformparser.ypp" {(yyval.enums.mathOperator) = AtomicMathematician::Add;} break; case 203: /* Line 1269 of yacc.c. */ -#line 2952 "querytransformparser.ypp" +#line 2993 "querytransformparser.ypp" {(yyval.enums.mathOperator) = AtomicMathematician::Substract;} break; case 205: /* Line 1269 of yacc.c. */ -#line 2956 "querytransformparser.ypp" +#line 2997 "querytransformparser.ypp" { + allowedIn(QueryLanguages(QXmlQuery::XQuery10 | QXmlQuery::XPath20), parseInfo, (yyloc)); (yyval.expr) = create(new ArithmeticExpression((yyvsp[(1) - (3)].expr), (yyvsp[(2) - (3)].enums.mathOperator), (yyvsp[(3) - (3)].expr)), (yyloc), parseInfo); } break; case 206: /* Line 1269 of yacc.c. */ -#line 2960 "querytransformparser.ypp" +#line 3002 "querytransformparser.ypp" {(yyval.enums.mathOperator) = AtomicMathematician::Multiply;} break; case 207: /* Line 1269 of yacc.c. */ -#line 2961 "querytransformparser.ypp" +#line 3003 "querytransformparser.ypp" {(yyval.enums.mathOperator) = AtomicMathematician::Div;} break; case 208: /* Line 1269 of yacc.c. */ -#line 2962 "querytransformparser.ypp" +#line 3004 "querytransformparser.ypp" {(yyval.enums.mathOperator) = AtomicMathematician::IDiv;} break; case 209: /* Line 1269 of yacc.c. */ -#line 2963 "querytransformparser.ypp" +#line 3005 "querytransformparser.ypp" {(yyval.enums.mathOperator) = AtomicMathematician::Mod;} break; case 211: /* Line 1269 of yacc.c. */ -#line 2967 "querytransformparser.ypp" +#line 3009 "querytransformparser.ypp" { + allowedIn(QueryLanguages(QXmlQuery::XQuery10 + | QXmlQuery::XPath20 + | QXmlQuery::XmlSchema11IdentityConstraintField + | QXmlQuery::XmlSchema11IdentityConstraintSelector), + parseInfo, (yyloc)); (yyval.expr) = create(new CombineNodes((yyvsp[(1) - (3)].expr), CombineNodes::Union, (yyvsp[(3) - (3)].expr)), (yyloc), parseInfo); } break; case 213: /* Line 1269 of yacc.c. */ -#line 2973 "querytransformparser.ypp" +#line 3020 "querytransformparser.ypp" { + allowedIn(QueryLanguages(QXmlQuery::XQuery10 | QXmlQuery::XPath20), parseInfo, (yyloc)); (yyval.expr) = create(new CombineNodes((yyvsp[(1) - (3)].expr), (yyvsp[(2) - (3)].enums.combinedNodeOp), (yyvsp[(3) - (3)].expr)), (yyloc), parseInfo); } break; case 216: /* Line 1269 of yacc.c. */ -#line 2981 "querytransformparser.ypp" +#line 3029 "querytransformparser.ypp" { (yyval.enums.combinedNodeOp) = CombineNodes::Intersect; } @@ -5733,7 +5781,7 @@ yyreduce: case 217: /* Line 1269 of yacc.c. */ -#line 2985 "querytransformparser.ypp" +#line 3033 "querytransformparser.ypp" { (yyval.enums.combinedNodeOp) = CombineNodes::Except; } @@ -5741,48 +5789,53 @@ yyreduce: case 219: /* Line 1269 of yacc.c. */ -#line 2991 "querytransformparser.ypp" +#line 3039 "querytransformparser.ypp" { + allowedIn(QueryLanguages(QXmlQuery::XQuery10 | QXmlQuery::XPath20), parseInfo, (yyloc)); (yyval.expr) = create(new InstanceOf((yyvsp[(1) - (4)].expr), - SequenceType::Ptr((yyvsp[(4) - (4)].sequenceType))), (yyloc), parseInfo); + SequenceType::Ptr((yyvsp[(4) - (4)].sequenceType))), (yyloc), parseInfo); } break; case 221: /* Line 1269 of yacc.c. */ -#line 2998 "querytransformparser.ypp" +#line 3047 "querytransformparser.ypp" { + allowedIn(QueryLanguages(QXmlQuery::XQuery10 | QXmlQuery::XPath20), parseInfo, (yyloc)); (yyval.expr) = create(new TreatAs((yyvsp[(1) - (4)].expr), (yyvsp[(4) - (4)].sequenceType)), (yyloc), parseInfo); } break; case 223: /* Line 1269 of yacc.c. */ -#line 3004 "querytransformparser.ypp" +#line 3054 "querytransformparser.ypp" { + allowedIn(QueryLanguages(QXmlQuery::XQuery10 | QXmlQuery::XPath20), parseInfo, (yyloc)); (yyval.expr) = create(new CastableAs((yyvsp[(1) - (4)].expr), (yyvsp[(4) - (4)].sequenceType)), (yyloc), parseInfo); } break; case 225: /* Line 1269 of yacc.c. */ -#line 3010 "querytransformparser.ypp" +#line 3061 "querytransformparser.ypp" { + allowedIn(QueryLanguages(QXmlQuery::XQuery10 | QXmlQuery::XPath20), parseInfo, (yyloc)); (yyval.expr) = create(new CastAs((yyvsp[(1) - (4)].expr), (yyvsp[(4) - (4)].sequenceType)), (yyloc), parseInfo); } break; case 227: /* Line 1269 of yacc.c. */ -#line 3016 "querytransformparser.ypp" +#line 3068 "querytransformparser.ypp" { + allowedIn(QueryLanguages(QXmlQuery::XQuery10 | QXmlQuery::XPath20), parseInfo, (yyloc)); (yyval.expr) = create(new UnaryExpression((yyvsp[(1) - (2)].enums.mathOperator), (yyvsp[(2) - (2)].expr), parseInfo->staticContext), (yyloc), parseInfo); } break; case 228: /* Line 1269 of yacc.c. */ -#line 3021 "querytransformparser.ypp" +#line 3074 "querytransformparser.ypp" { (yyval.enums.mathOperator) = AtomicMathematician::Add; } @@ -5790,7 +5843,7 @@ yyreduce: case 229: /* Line 1269 of yacc.c. */ -#line 3025 "querytransformparser.ypp" +#line 3078 "querytransformparser.ypp" { (yyval.enums.mathOperator) = AtomicMathematician::Substract; } @@ -5798,51 +5851,52 @@ yyreduce: case 233: /* Line 1269 of yacc.c. */ -#line 3034 "querytransformparser.ypp" +#line 3087 "querytransformparser.ypp" { + allowedIn(QueryLanguages(QXmlQuery::XQuery10 | QXmlQuery::XPath20), parseInfo, (yyloc)); (yyval.expr) = create(new GeneralComparison((yyvsp[(1) - (3)].expr), (yyvsp[(2) - (3)].enums.valueOperator), (yyvsp[(3) - (3)].expr), parseInfo->isBackwardsCompat.top()), (yyloc), parseInfo); } break; case 234: /* Line 1269 of yacc.c. */ -#line 3038 "querytransformparser.ypp" +#line 3092 "querytransformparser.ypp" {(yyval.enums.valueOperator) = AtomicComparator::OperatorEqual;} break; case 235: /* Line 1269 of yacc.c. */ -#line 3039 "querytransformparser.ypp" +#line 3093 "querytransformparser.ypp" {(yyval.enums.valueOperator) = AtomicComparator::OperatorNotEqual;} break; case 236: /* Line 1269 of yacc.c. */ -#line 3040 "querytransformparser.ypp" +#line 3094 "querytransformparser.ypp" {(yyval.enums.valueOperator) = AtomicComparator::OperatorGreaterOrEqual;} break; case 237: /* Line 1269 of yacc.c. */ -#line 3041 "querytransformparser.ypp" +#line 3095 "querytransformparser.ypp" {(yyval.enums.valueOperator) = AtomicComparator::OperatorGreaterThan;} break; case 238: /* Line 1269 of yacc.c. */ -#line 3042 "querytransformparser.ypp" +#line 3096 "querytransformparser.ypp" {(yyval.enums.valueOperator) = AtomicComparator::OperatorLessOrEqual;} break; case 239: /* Line 1269 of yacc.c. */ -#line 3043 "querytransformparser.ypp" +#line 3097 "querytransformparser.ypp" {(yyval.enums.valueOperator) = AtomicComparator::OperatorLessThan;} break; case 240: /* Line 1269 of yacc.c. */ -#line 3046 "querytransformparser.ypp" +#line 3100 "querytransformparser.ypp" { (yyval.expr) = create(new ValueComparison((yyvsp[(1) - (3)].expr), (yyvsp[(2) - (3)].enums.valueOperator), (yyvsp[(3) - (3)].expr)), (yyloc), parseInfo); } @@ -5850,43 +5904,43 @@ yyreduce: case 241: /* Line 1269 of yacc.c. */ -#line 3050 "querytransformparser.ypp" +#line 3104 "querytransformparser.ypp" {(yyval.enums.valueOperator) = AtomicComparator::OperatorEqual;} break; case 242: /* Line 1269 of yacc.c. */ -#line 3051 "querytransformparser.ypp" +#line 3105 "querytransformparser.ypp" {(yyval.enums.valueOperator) = AtomicComparator::OperatorNotEqual;} break; case 243: /* Line 1269 of yacc.c. */ -#line 3052 "querytransformparser.ypp" +#line 3106 "querytransformparser.ypp" {(yyval.enums.valueOperator) = AtomicComparator::OperatorGreaterOrEqual;} break; case 244: /* Line 1269 of yacc.c. */ -#line 3053 "querytransformparser.ypp" +#line 3107 "querytransformparser.ypp" {(yyval.enums.valueOperator) = AtomicComparator::OperatorGreaterThan;} break; case 245: /* Line 1269 of yacc.c. */ -#line 3054 "querytransformparser.ypp" +#line 3108 "querytransformparser.ypp" {(yyval.enums.valueOperator) = AtomicComparator::OperatorLessOrEqual;} break; case 246: /* Line 1269 of yacc.c. */ -#line 3055 "querytransformparser.ypp" +#line 3109 "querytransformparser.ypp" {(yyval.enums.valueOperator) = AtomicComparator::OperatorLessThan;} break; case 247: /* Line 1269 of yacc.c. */ -#line 3058 "querytransformparser.ypp" +#line 3112 "querytransformparser.ypp" { (yyval.expr) = create(new NodeComparison((yyvsp[(1) - (3)].expr), (yyvsp[(2) - (3)].enums.nodeOperator), (yyvsp[(3) - (3)].expr)), (yyloc), parseInfo); } @@ -5894,27 +5948,27 @@ yyreduce: case 248: /* Line 1269 of yacc.c. */ -#line 3062 "querytransformparser.ypp" +#line 3116 "querytransformparser.ypp" {(yyval.enums.nodeOperator) = QXmlNodeModelIndex::Is;} break; case 249: /* Line 1269 of yacc.c. */ -#line 3063 "querytransformparser.ypp" +#line 3117 "querytransformparser.ypp" {(yyval.enums.nodeOperator) = QXmlNodeModelIndex::Precedes;} break; case 250: /* Line 1269 of yacc.c. */ -#line 3064 "querytransformparser.ypp" +#line 3118 "querytransformparser.ypp" {(yyval.enums.nodeOperator) = QXmlNodeModelIndex::Follows;} break; case 251: /* Line 1269 of yacc.c. */ -#line 3067 "querytransformparser.ypp" +#line 3121 "querytransformparser.ypp" { - disallowedConstruct(parseInfo, (yyloc)); + allowedIn(QXmlQuery::XQuery10, parseInfo, (yyloc)); parseInfo->staticContext->error(QtXmlPatterns::tr("The Schema Validation Feature is not supported. " "Hence, %1-expressions may not be used.") .arg(formatKeyword("validate")), @@ -5927,26 +5981,27 @@ yyreduce: case 252: /* Line 1269 of yacc.c. */ -#line 3080 "querytransformparser.ypp" +#line 3134 "querytransformparser.ypp" {(yyval.enums.validationMode) = Validate::Strict;} break; case 253: /* Line 1269 of yacc.c. */ -#line 3081 "querytransformparser.ypp" +#line 3135 "querytransformparser.ypp" {(yyval.enums.validationMode) = Validate::Strict;} break; case 254: /* Line 1269 of yacc.c. */ -#line 3082 "querytransformparser.ypp" +#line 3136 "querytransformparser.ypp" {(yyval.enums.validationMode) = Validate::Lax;} break; case 255: /* Line 1269 of yacc.c. */ -#line 3085 "querytransformparser.ypp" +#line 3139 "querytransformparser.ypp" { + allowedIn(QXmlQuery::XQuery10, parseInfo, (yyloc)); /* We don't support any pragmas, so we only do the * necessary validation and use the fallback expression. */ @@ -5964,7 +6019,7 @@ yyreduce: case 256: /* Line 1269 of yacc.c. */ -#line 3101 "querytransformparser.ypp" +#line 3156 "querytransformparser.ypp" { (yyval.expr).reset(); } @@ -5972,7 +6027,7 @@ yyreduce: case 257: /* Line 1269 of yacc.c. */ -#line 3105 "querytransformparser.ypp" +#line 3160 "querytransformparser.ypp" { (yyval.expr) = (yyvsp[(2) - (3)].expr); } @@ -5980,15 +6035,15 @@ yyreduce: case 260: /* Line 1269 of yacc.c. */ -#line 3113 "querytransformparser.ypp" +#line 3168 "querytransformparser.ypp" { - disallowedConstruct(parseInfo, (yyloc)); + allowedIn(QXmlQuery::XQuery10, parseInfo, (yyloc)); } break; case 263: /* Line 1269 of yacc.c. */ -#line 3121 "querytransformparser.ypp" +#line 3176 "querytransformparser.ypp" { /* This is "/step". That is, fn:root(self::node()) treat as document-node()/RelativePathExpr. */ (yyval.expr) = create(new Path(createRootExpression(parseInfo, (yyloc)), (yyvsp[(2) - (2)].expr)), (yyloc), parseInfo); @@ -5997,7 +6052,7 @@ yyreduce: case 264: /* Line 1269 of yacc.c. */ -#line 3127 "querytransformparser.ypp" +#line 3182 "querytransformparser.ypp" { (yyval.expr) = createSlashSlashPath(createRootExpression(parseInfo, (yyloc)), (yyvsp[(2) - (2)].expr), (yyloc), parseInfo); } @@ -6005,7 +6060,7 @@ yyreduce: case 265: /* Line 1269 of yacc.c. */ -#line 3131 "querytransformparser.ypp" +#line 3186 "querytransformparser.ypp" { /* This is "/". That is, fn:root(self::node()) treat as document-node(). */ (yyval.expr) = createRootExpression(parseInfo, (yyloc)); @@ -6014,7 +6069,7 @@ yyreduce: case 268: /* Line 1269 of yacc.c. */ -#line 3141 "querytransformparser.ypp" +#line 3196 "querytransformparser.ypp" { (yyval.expr) = create(new Path((yyvsp[(1) - (3)].expr), (yyvsp[(3) - (3)].expr), (yyvsp[(2) - (3)].enums.pathKind)), (yyloc), parseInfo); } @@ -6022,7 +6077,7 @@ yyreduce: case 269: /* Line 1269 of yacc.c. */ -#line 3145 "querytransformparser.ypp" +#line 3200 "querytransformparser.ypp" { const Expression::Ptr orderBy(createReturnOrderBy((yyvsp[(4) - (7)].orderSpecs), (yyvsp[(6) - (7)].expr), parseInfo->orderStability.pop(), (yyloc), parseInfo)); @@ -6035,7 +6090,7 @@ yyreduce: case 270: /* Line 1269 of yacc.c. */ -#line 3154 "querytransformparser.ypp" +#line 3209 "querytransformparser.ypp" { (yyval.expr) = createSlashSlashPath((yyvsp[(1) - (3)].expr), (yyvsp[(3) - (3)].expr), (yyloc), parseInfo); } @@ -6043,7 +6098,7 @@ yyreduce: case 271: /* Line 1269 of yacc.c. */ -#line 3159 "querytransformparser.ypp" +#line 3214 "querytransformparser.ypp" { (yyval.expr) = NodeSortExpression::wrapAround((yyvsp[(1) - (1)].expr), parseInfo->staticContext); } @@ -6051,7 +6106,7 @@ yyreduce: case 273: /* Line 1269 of yacc.c. */ -#line 3164 "querytransformparser.ypp" +#line 3219 "querytransformparser.ypp" { (yyval.expr) = create(new CurrentItemStore((yyvsp[(2) - (2)].expr)), (yyloc), parseInfo); } @@ -6059,7 +6114,7 @@ yyreduce: case 274: /* Line 1269 of yacc.c. */ -#line 3168 "querytransformparser.ypp" +#line 3223 "querytransformparser.ypp" { const xsDouble version = (yyvsp[(1) - (1)].sval).toDouble(); @@ -6071,7 +6126,7 @@ yyreduce: case 275: /* Line 1269 of yacc.c. */ -#line 3176 "querytransformparser.ypp" +#line 3231 "querytransformparser.ypp" { if((yyvsp[(2) - (3)].enums.Double) < 2) (yyval.expr) = createCompatStore((yyvsp[(3) - (3)].expr), (yyloc), parseInfo); @@ -6082,8 +6137,9 @@ yyreduce: case 276: /* Line 1269 of yacc.c. */ -#line 3183 "querytransformparser.ypp" +#line 3238 "querytransformparser.ypp" { + allowedIn(QXmlQuery::XSLT20, parseInfo, (yyloc)); Q_ASSERT(!(yyvsp[(2) - (5)].sval).isEmpty()); (yyval.expr) = create(new StaticBaseURIStore((yyvsp[(2) - (5)].sval), (yyvsp[(4) - (5)].expr)), (yyloc), parseInfo); } @@ -6091,8 +6147,9 @@ yyreduce: case 277: /* Line 1269 of yacc.c. */ -#line 3189 "querytransformparser.ypp" +#line 3245 "querytransformparser.ypp" { + allowedIn(QueryLanguages(QXmlQuery::XQuery10 | QXmlQuery::XSLT20), parseInfo, (yyloc)); parseInfo->resolvers.push(parseInfo->staticContext->namespaceBindings()); const NamespaceResolver::Ptr resolver(new DelegatingNamespaceResolver(parseInfo->staticContext->namespaceBindings())); resolver->addBinding(QXmlName(parseInfo->staticContext->namePool()->allocateNamespace((yyvsp[(5) - (6)].sval)), @@ -6104,7 +6161,7 @@ yyreduce: case 278: /* Line 1269 of yacc.c. */ -#line 3199 "querytransformparser.ypp" +#line 3256 "querytransformparser.ypp" { parseInfo->staticContext->setNamespaceBindings(parseInfo->resolvers.pop()); (yyval.expr) = (yyvsp[(8) - (9)].expr); @@ -6113,7 +6170,7 @@ yyreduce: case 279: /* Line 1269 of yacc.c. */ -#line 3204 "querytransformparser.ypp" +#line 3261 "querytransformparser.ypp" { (yyval.expr) = create(new CallTemplate((yyvsp[(2) - (5)].qName), parseInfo->templateWithParams), (yyloc), parseInfo); parseInfo->templateWithParametersHandled(); @@ -6123,7 +6180,7 @@ yyreduce: case 280: /* Line 1269 of yacc.c. */ -#line 3211 "querytransformparser.ypp" +#line 3268 "querytransformparser.ypp" { parseInfo->startParsingWithParam(); } @@ -6131,7 +6188,7 @@ yyreduce: case 281: /* Line 1269 of yacc.c. */ -#line 3215 "querytransformparser.ypp" +#line 3272 "querytransformparser.ypp" { parseInfo->endParsingWithParam(); } @@ -6139,42 +6196,42 @@ yyreduce: case 282: /* Line 1269 of yacc.c. */ -#line 3220 "querytransformparser.ypp" +#line 3277 "querytransformparser.ypp" { } break; case 283: /* Line 1269 of yacc.c. */ -#line 3223 "querytransformparser.ypp" +#line 3280 "querytransformparser.ypp" { } break; case 284: /* Line 1269 of yacc.c. */ -#line 3226 "querytransformparser.ypp" +#line 3283 "querytransformparser.ypp" { } break; case 285: /* Line 1269 of yacc.c. */ -#line 3230 "querytransformparser.ypp" +#line 3287 "querytransformparser.ypp" { } break; case 286: /* Line 1269 of yacc.c. */ -#line 3233 "querytransformparser.ypp" +#line 3290 "querytransformparser.ypp" { } break; case 287: /* Line 1269 of yacc.c. */ -#line 3237 "querytransformparser.ypp" +#line 3294 "querytransformparser.ypp" { /* Note, this grammar rule is invoked for @c xsl:param @em and @c * xsl:with-param. */ @@ -6242,7 +6299,7 @@ yyreduce: case 288: /* Line 1269 of yacc.c. */ -#line 3302 "querytransformparser.ypp" +#line 3359 "querytransformparser.ypp" { (yyval.enums.Bool) = false; } @@ -6250,7 +6307,7 @@ yyreduce: case 289: /* Line 1269 of yacc.c. */ -#line 3306 "querytransformparser.ypp" +#line 3363 "querytransformparser.ypp" { (yyval.enums.Bool) = true; } @@ -6258,7 +6315,7 @@ yyreduce: case 290: /* Line 1269 of yacc.c. */ -#line 3311 "querytransformparser.ypp" +#line 3368 "querytransformparser.ypp" { (yyval.expr) = Expression::Ptr(); } @@ -6266,7 +6323,7 @@ yyreduce: case 291: /* Line 1269 of yacc.c. */ -#line 3315 "querytransformparser.ypp" +#line 3372 "querytransformparser.ypp" { (yyval.expr) = (yyvsp[(2) - (2)].expr); } @@ -6274,7 +6331,7 @@ yyreduce: case 292: /* Line 1269 of yacc.c. */ -#line 3324 "querytransformparser.ypp" +#line 3381 "querytransformparser.ypp" { (yyval.enums.pathKind) = Path::RegularPath; } @@ -6282,7 +6339,7 @@ yyreduce: case 293: /* Line 1269 of yacc.c. */ -#line 3328 "querytransformparser.ypp" +#line 3385 "querytransformparser.ypp" { (yyval.enums.pathKind) = Path::XSLTForEach; } @@ -6290,7 +6347,7 @@ yyreduce: case 294: /* Line 1269 of yacc.c. */ -#line 3332 "querytransformparser.ypp" +#line 3389 "querytransformparser.ypp" { (yyval.enums.pathKind) = Path::ForApplyTemplate; } @@ -6298,7 +6355,7 @@ yyreduce: case 296: /* Line 1269 of yacc.c. */ -#line 3338 "querytransformparser.ypp" +#line 3395 "querytransformparser.ypp" { (yyval.expr) = create(GenericPredicate::create((yyvsp[(1) - (4)].expr), (yyvsp[(3) - (4)].expr), parseInfo->staticContext, fromYYLTYPE((yyloc), parseInfo)), (yyloc), parseInfo); } @@ -6306,7 +6363,7 @@ yyreduce: case 299: /* Line 1269 of yacc.c. */ -#line 3346 "querytransformparser.ypp" +#line 3403 "querytransformparser.ypp" { if((yyvsp[(1) - (1)].enums.axis) == QXmlNodeModelIndex::AxisAttribute) parseInfo->nodeTestSource = BuiltinTypes::attribute; @@ -6315,7 +6372,7 @@ yyreduce: case 300: /* Line 1269 of yacc.c. */ -#line 3351 "querytransformparser.ypp" +#line 3408 "querytransformparser.ypp" { if((yyvsp[(3) - (3)].itemType)) { @@ -6344,7 +6401,7 @@ yyreduce: case 304: /* Line 1269 of yacc.c. */ -#line 3381 "querytransformparser.ypp" +#line 3438 "querytransformparser.ypp" { if((yyvsp[(1) - (2)].enums.axis) == QXmlNodeModelIndex::AxisNamespace) { @@ -6356,84 +6413,114 @@ yyreduce: } else (yyval.enums.axis) = (yyvsp[(1) - (2)].enums.axis); + + switch((yyvsp[(1) - (2)].enums.axis)) + { + case QXmlNodeModelIndex::AxisAttribute: + { + allowedIn(QueryLanguages( QXmlQuery::XPath20 + | QXmlQuery::XQuery10 + | QXmlQuery::XmlSchema11IdentityConstraintField + | QXmlQuery::XSLT20), + parseInfo, (yyloc)); + break; + } + case QXmlNodeModelIndex::AxisChild: + { + allowedIn(QueryLanguages( QXmlQuery::XPath20 + | QXmlQuery::XQuery10 + | QXmlQuery::XmlSchema11IdentityConstraintField + | QXmlQuery::XmlSchema11IdentityConstraintSelector + | QXmlQuery::XSLT20), + parseInfo, (yyloc)); + break; + } + default: + { + allowedIn(QueryLanguages( QXmlQuery::XPath20 + | QXmlQuery::XQuery10 + | QXmlQuery::XSLT20), + parseInfo, (yyloc)); + } + } } break; case 305: /* Line 1269 of yacc.c. */ -#line 3394 "querytransformparser.ypp" +#line 3481 "querytransformparser.ypp" {(yyval.enums.axis) = QXmlNodeModelIndex::AxisAncestorOrSelf ;} break; case 306: /* Line 1269 of yacc.c. */ -#line 3395 "querytransformparser.ypp" +#line 3482 "querytransformparser.ypp" {(yyval.enums.axis) = QXmlNodeModelIndex::AxisAncestor ;} break; case 307: /* Line 1269 of yacc.c. */ -#line 3396 "querytransformparser.ypp" +#line 3483 "querytransformparser.ypp" {(yyval.enums.axis) = QXmlNodeModelIndex::AxisAttribute ;} break; case 308: /* Line 1269 of yacc.c. */ -#line 3397 "querytransformparser.ypp" +#line 3484 "querytransformparser.ypp" {(yyval.enums.axis) = QXmlNodeModelIndex::AxisChild ;} break; case 309: /* Line 1269 of yacc.c. */ -#line 3398 "querytransformparser.ypp" +#line 3485 "querytransformparser.ypp" {(yyval.enums.axis) = QXmlNodeModelIndex::AxisDescendantOrSelf;} break; case 310: /* Line 1269 of yacc.c. */ -#line 3399 "querytransformparser.ypp" +#line 3486 "querytransformparser.ypp" {(yyval.enums.axis) = QXmlNodeModelIndex::AxisDescendant ;} break; case 311: /* Line 1269 of yacc.c. */ -#line 3400 "querytransformparser.ypp" +#line 3487 "querytransformparser.ypp" {(yyval.enums.axis) = QXmlNodeModelIndex::AxisFollowing ;} break; case 312: /* Line 1269 of yacc.c. */ -#line 3401 "querytransformparser.ypp" +#line 3488 "querytransformparser.ypp" {(yyval.enums.axis) = QXmlNodeModelIndex::AxisPreceding ;} break; case 313: /* Line 1269 of yacc.c. */ -#line 3402 "querytransformparser.ypp" +#line 3489 "querytransformparser.ypp" {(yyval.enums.axis) = QXmlNodeModelIndex::AxisFollowingSibling;} break; case 314: /* Line 1269 of yacc.c. */ -#line 3403 "querytransformparser.ypp" +#line 3490 "querytransformparser.ypp" {(yyval.enums.axis) = QXmlNodeModelIndex::AxisPrecedingSibling;} break; case 315: /* Line 1269 of yacc.c. */ -#line 3404 "querytransformparser.ypp" +#line 3491 "querytransformparser.ypp" {(yyval.enums.axis) = QXmlNodeModelIndex::AxisParent ;} break; case 316: /* Line 1269 of yacc.c. */ -#line 3405 "querytransformparser.ypp" +#line 3492 "querytransformparser.ypp" {(yyval.enums.axis) = QXmlNodeModelIndex::AxisSelf ;} break; case 317: /* Line 1269 of yacc.c. */ -#line 3408 "querytransformparser.ypp" +#line 3495 "querytransformparser.ypp" { parseInfo->nodeTestSource = BuiltinTypes::attribute; } @@ -6441,8 +6528,9 @@ yyreduce: case 318: /* Line 1269 of yacc.c. */ -#line 3412 "querytransformparser.ypp" +#line 3499 "querytransformparser.ypp" { + allowedIn(QueryLanguages(QXmlQuery::XQuery10 | QXmlQuery::XSLT20 | QXmlQuery::XmlSchema11IdentityConstraintField), parseInfo, (yyloc)); (yyval.expr) = create(new AxisStep(QXmlNodeModelIndex::AxisAttribute, (yyvsp[(3) - (3)].itemType)), (yyloc), parseInfo); parseInfo->restoreNodeTestSource(); @@ -6451,7 +6539,7 @@ yyreduce: case 319: /* Line 1269 of yacc.c. */ -#line 3418 "querytransformparser.ypp" +#line 3506 "querytransformparser.ypp" { ItemType::Ptr nodeTest; @@ -6466,7 +6554,7 @@ yyreduce: case 320: /* Line 1269 of yacc.c. */ -#line 3429 "querytransformparser.ypp" +#line 3517 "querytransformparser.ypp" { (yyval.expr) = create(new AxisStep(QXmlNodeModelIndex::AxisAttribute, (yyvsp[(1) - (1)].itemType)), (yyloc), parseInfo); } @@ -6474,15 +6562,23 @@ yyreduce: case 322: /* Line 1269 of yacc.c. */ -#line 3436 "querytransformparser.ypp" +#line 3524 "querytransformparser.ypp" { (yyval.expr) = create(new AxisStep(QXmlNodeModelIndex::AxisParent, BuiltinTypes::node), (yyloc), parseInfo); } break; + case 324: +/* Line 1269 of yacc.c. */ +#line 3530 "querytransformparser.ypp" + { + allowedIn(QueryLanguages(QXmlQuery::XQuery10 | QXmlQuery::XPath20), parseInfo, (yyloc)); + } + break; + case 325: /* Line 1269 of yacc.c. */ -#line 3444 "querytransformparser.ypp" +#line 3535 "querytransformparser.ypp" { (yyval.itemType) = QNameTest::create(parseInfo->nodeTestSource, (yyvsp[(1) - (1)].qName)); } @@ -6490,7 +6586,7 @@ yyreduce: case 327: /* Line 1269 of yacc.c. */ -#line 3450 "querytransformparser.ypp" +#line 3541 "querytransformparser.ypp" { (yyval.itemType) = parseInfo->nodeTestSource; } @@ -6498,7 +6594,7 @@ yyreduce: case 328: /* Line 1269 of yacc.c. */ -#line 3454 "querytransformparser.ypp" +#line 3545 "querytransformparser.ypp" { const NamePool::Ptr np(parseInfo->staticContext->namePool()); const ReflectYYLTYPE ryy((yyloc), parseInfo); @@ -6511,8 +6607,9 @@ yyreduce: case 329: /* Line 1269 of yacc.c. */ -#line 3463 "querytransformparser.ypp" +#line 3554 "querytransformparser.ypp" { + allowedIn(QueryLanguages(QXmlQuery::XQuery10 | QXmlQuery::XPath20), parseInfo, (yyloc)); const QXmlName::LocalNameCode c = parseInfo->staticContext->namePool()->allocateLocalName((yyvsp[(1) - (1)].sval)); (yyval.itemType) = LocalNameTest::create(parseInfo->nodeTestSource, c); } @@ -6520,15 +6617,16 @@ yyreduce: case 331: /* Line 1269 of yacc.c. */ -#line 3470 "querytransformparser.ypp" +#line 3562 "querytransformparser.ypp" { + allowedIn(QueryLanguages(QXmlQuery::XQuery10 | QXmlQuery::XPath20), parseInfo, (yyloc)); (yyval.expr) = create(GenericPredicate::create((yyvsp[(1) - (4)].expr), (yyvsp[(3) - (4)].expr), parseInfo->staticContext, fromYYLTYPE((yylsp[(4) - (4)]), parseInfo)), (yyloc), parseInfo); } break; case 339: /* Line 1269 of yacc.c. */ -#line 3482 "querytransformparser.ypp" +#line 3575 "querytransformparser.ypp" { (yyval.expr) = create(new ApplyTemplate(parseInfo->modeFor((yyvsp[(2) - (5)].qName)), parseInfo->templateWithParams, @@ -6541,7 +6639,7 @@ yyreduce: case 341: /* Line 1269 of yacc.c. */ -#line 3493 "querytransformparser.ypp" +#line 3586 "querytransformparser.ypp" { (yyval.expr) = create(new Literal(AtomicString::fromValue((yyvsp[(1) - (1)].sval))), (yyloc), parseInfo); } @@ -6549,31 +6647,34 @@ yyreduce: case 342: /* Line 1269 of yacc.c. */ -#line 3498 "querytransformparser.ypp" +#line 3591 "querytransformparser.ypp" { + allowedIn(QueryLanguages(QXmlQuery::XQuery10 | QXmlQuery::XPath20), parseInfo, (yyloc)); (yyval.expr) = createNumericLiteral((yyvsp[(1) - (1)].sval), (yyloc), parseInfo); } break; case 343: /* Line 1269 of yacc.c. */ -#line 3502 "querytransformparser.ypp" +#line 3596 "querytransformparser.ypp" { + allowedIn(QueryLanguages(QXmlQuery::XQuery10 | QXmlQuery::XPath20), parseInfo, (yyloc)); (yyval.expr) = createNumericLiteral((yyvsp[(1) - (1)].sval), (yyloc), parseInfo); } break; case 344: /* Line 1269 of yacc.c. */ -#line 3507 "querytransformparser.ypp" +#line 3602 "querytransformparser.ypp" { + allowedIn(QueryLanguages(QXmlQuery::XQuery10 | QXmlQuery::XPath20), parseInfo, (yyloc)); (yyval.expr) = resolveVariable((yyvsp[(2) - (2)].qName), (yyloc), parseInfo, false); } break; case 345: /* Line 1269 of yacc.c. */ -#line 3512 "querytransformparser.ypp" +#line 3608 "querytransformparser.ypp" { /* See: http://www.w3.org/TR/xpath20/#id-variables */ (yyval.qName) = parseInfo->staticContext->namePool()->allocateQName(QString(), (yyvsp[(1) - (1)].sval)); @@ -6582,7 +6683,7 @@ yyreduce: case 346: /* Line 1269 of yacc.c. */ -#line 3517 "querytransformparser.ypp" +#line 3613 "querytransformparser.ypp" { (yyval.qName) = (yyvsp[(1) - (1)].qName); } @@ -6590,23 +6691,25 @@ yyreduce: case 347: /* Line 1269 of yacc.c. */ -#line 3522 "querytransformparser.ypp" +#line 3618 "querytransformparser.ypp" { + allowedIn(QueryLanguages(QXmlQuery::XQuery10 | QXmlQuery::XPath20), parseInfo, (yyloc)); (yyval.expr) = (yyvsp[(2) - (3)].expr); } break; case 348: /* Line 1269 of yacc.c. */ -#line 3526 "querytransformparser.ypp" +#line 3623 "querytransformparser.ypp" { + allowedIn(QueryLanguages(QXmlQuery::XQuery10 | QXmlQuery::XPath20), parseInfo, (yyloc)); (yyval.expr) = create(new EmptySequence, (yyloc), parseInfo); } break; case 349: /* Line 1269 of yacc.c. */ -#line 3531 "querytransformparser.ypp" +#line 3629 "querytransformparser.ypp" { (yyval.expr) = create(new ContextItem(), (yyloc), parseInfo); } @@ -6614,7 +6717,7 @@ yyreduce: case 350: /* Line 1269 of yacc.c. */ -#line 3536 "querytransformparser.ypp" +#line 3634 "querytransformparser.ypp" { (yyval.expr) = (yyvsp[(2) - (2)].expr); } @@ -6622,8 +6725,9 @@ yyreduce: case 351: /* Line 1269 of yacc.c. */ -#line 3541 "querytransformparser.ypp" +#line 3639 "querytransformparser.ypp" { + allowedIn(QueryLanguages(QXmlQuery::XQuery10 | QXmlQuery::XPath20), parseInfo, (yyloc)); if(XPathHelper::isReservedNamespace((yyvsp[(1) - (4)].qName).namespaceURI()) || (yyvsp[(1) - (4)].qName).namespaceURI() == StandardNamespaces::InternalXSLT) { /* We got a call to a builtin function. */ const ReflectYYLTYPE ryy((yyloc), parseInfo); @@ -6653,7 +6757,7 @@ yyreduce: case 352: /* Line 1269 of yacc.c. */ -#line 3569 "querytransformparser.ypp" +#line 3668 "querytransformparser.ypp" { (yyval.expressionList) = Expression::List(); } @@ -6661,7 +6765,7 @@ yyreduce: case 353: /* Line 1269 of yacc.c. */ -#line 3574 "querytransformparser.ypp" +#line 3673 "querytransformparser.ypp" { Expression::List list; list.append((yyvsp[(1) - (1)].expr)); @@ -6671,15 +6775,15 @@ yyreduce: case 355: /* Line 1269 of yacc.c. */ -#line 3583 "querytransformparser.ypp" +#line 3682 "querytransformparser.ypp" { - disallowedConstruct(parseInfo, (yyloc)); + allowedIn(QXmlQuery::XQuery10, parseInfo, (yyloc)); } break; case 360: /* Line 1269 of yacc.c. */ -#line 3624 "querytransformparser.ypp" +#line 3726 "querytransformparser.ypp" { (yyval.enums.tokenizerPosition) = parseInfo->tokenizer->commenceScanOnly(); parseInfo->scanOnlyStack.push(true); @@ -6688,7 +6792,7 @@ yyreduce: case 361: /* Line 1269 of yacc.c. */ -#line 3633 "querytransformparser.ypp" +#line 3735 "querytransformparser.ypp" { ++parseInfo->elementConstructorDepth; Expression::List constructors; @@ -6836,7 +6940,7 @@ yyreduce: case 362: /* Line 1269 of yacc.c. */ -#line 3779 "querytransformparser.ypp" +#line 3881 "querytransformparser.ypp" { /* We add the content constructor after the attribute constructors. This might result * in nested ExpressionSequences, but it will be optimized away later on. */ @@ -6935,7 +7039,7 @@ yyreduce: case 363: /* Line 1269 of yacc.c. */ -#line 3875 "querytransformparser.ypp" +#line 3977 "querytransformparser.ypp" { (yyval.expr) = create(new EmptySequence(), (yyloc), parseInfo); } @@ -6943,7 +7047,7 @@ yyreduce: case 364: /* Line 1269 of yacc.c. */ -#line 3879 "querytransformparser.ypp" +#line 3981 "querytransformparser.ypp" { if(!(yyvsp[(4) - (5)].qName).isLexicallyEqual(parseInfo->tagStack.top())) { @@ -6965,7 +7069,7 @@ yyreduce: case 365: /* Line 1269 of yacc.c. */ -#line 3898 "querytransformparser.ypp" +#line 4000 "querytransformparser.ypp" { (yyval.attributeHolders) = AttributeHolderVector(); } @@ -6973,7 +7077,7 @@ yyreduce: case 366: /* Line 1269 of yacc.c. */ -#line 3902 "querytransformparser.ypp" +#line 4004 "querytransformparser.ypp" { (yyvsp[(1) - (2)].attributeHolders).append((yyvsp[(2) - (2)].attributeHolder)); (yyval.attributeHolders) = (yyvsp[(1) - (2)].attributeHolders); @@ -6982,7 +7086,7 @@ yyreduce: case 367: /* Line 1269 of yacc.c. */ -#line 3908 "querytransformparser.ypp" +#line 4010 "querytransformparser.ypp" { (yyval.attributeHolder) = qMakePair((yyvsp[(1) - (3)].sval), (yyvsp[(3) - (3)].expr)); } @@ -6990,7 +7094,7 @@ yyreduce: case 368: /* Line 1269 of yacc.c. */ -#line 3913 "querytransformparser.ypp" +#line 4015 "querytransformparser.ypp" { (yyval.expr) = createDirAttributeValue((yyvsp[(2) - (3)].expressionList), parseInfo, (yyloc)); } @@ -6998,7 +7102,7 @@ yyreduce: case 369: /* Line 1269 of yacc.c. */ -#line 3918 "querytransformparser.ypp" +#line 4020 "querytransformparser.ypp" { (yyval.expr) = createDirAttributeValue((yyvsp[(2) - (3)].expressionList), parseInfo, (yyloc)); } @@ -7006,7 +7110,7 @@ yyreduce: case 370: /* Line 1269 of yacc.c. */ -#line 3923 "querytransformparser.ypp" +#line 4025 "querytransformparser.ypp" { (yyval.expressionList) = Expression::List(); } @@ -7014,7 +7118,7 @@ yyreduce: case 371: /* Line 1269 of yacc.c. */ -#line 3927 "querytransformparser.ypp" +#line 4029 "querytransformparser.ypp" { Expression::Ptr content((yyvsp[(1) - (2)].expr)); @@ -7028,7 +7132,7 @@ yyreduce: case 372: /* Line 1269 of yacc.c. */ -#line 3937 "querytransformparser.ypp" +#line 4039 "querytransformparser.ypp" { (yyvsp[(2) - (2)].expressionList).prepend(create(new Literal(AtomicString::fromValue((yyvsp[(1) - (2)].sval))), (yyloc), parseInfo)); (yyval.expressionList) = (yyvsp[(2) - (2)].expressionList); @@ -7037,7 +7141,7 @@ yyreduce: case 373: /* Line 1269 of yacc.c. */ -#line 3943 "querytransformparser.ypp" +#line 4045 "querytransformparser.ypp" { (yyval.expressionList) = Expression::List(); parseInfo->isPreviousEnclosedExpr = false; @@ -7046,7 +7150,7 @@ yyreduce: case 374: /* Line 1269 of yacc.c. */ -#line 3948 "querytransformparser.ypp" +#line 4050 "querytransformparser.ypp" { (yyvsp[(1) - (2)].expressionList).append((yyvsp[(2) - (2)].expr)); (yyval.expressionList) = (yyvsp[(1) - (2)].expressionList); @@ -7056,7 +7160,7 @@ yyreduce: case 375: /* Line 1269 of yacc.c. */ -#line 3954 "querytransformparser.ypp" +#line 4056 "querytransformparser.ypp" { if(parseInfo->staticContext->boundarySpacePolicy() == StaticContext::BSPStrip && XPathHelper::isWhitespaceOnly((yyvsp[(2) - (2)].sval))) @@ -7074,7 +7178,7 @@ yyreduce: case 376: /* Line 1269 of yacc.c. */ -#line 3968 "querytransformparser.ypp" +#line 4070 "querytransformparser.ypp" { (yyvsp[(1) - (2)].expressionList).append(create(new TextNodeConstructor(create(new Literal(AtomicString::fromValue((yyvsp[(2) - (2)].sval))), (yyloc), parseInfo)), (yyloc), parseInfo)); (yyval.expressionList) = (yyvsp[(1) - (2)].expressionList); @@ -7084,7 +7188,7 @@ yyreduce: case 377: /* Line 1269 of yacc.c. */ -#line 3974 "querytransformparser.ypp" +#line 4076 "querytransformparser.ypp" { /* We insert a text node constructor that send an empty text node between * the two enclosed expressions, in order to ensure that no space is inserted. @@ -7104,7 +7208,7 @@ yyreduce: case 378: /* Line 1269 of yacc.c. */ -#line 3991 "querytransformparser.ypp" +#line 4093 "querytransformparser.ypp" { (yyval.expr) = create(new CommentConstructor(create(new Literal(AtomicString::fromValue((yyvsp[(2) - (2)].sval))), (yyloc), parseInfo)), (yyloc), parseInfo); } @@ -7112,7 +7216,7 @@ yyreduce: case 379: /* Line 1269 of yacc.c. */ -#line 3996 "querytransformparser.ypp" +#line 4098 "querytransformparser.ypp" { const ReflectYYLTYPE ryy((yyloc), parseInfo); NCNameConstructor::validateTargetNameelementConstructorDepth; @@ -7147,10 +7251,10 @@ yyreduce: case 389: /* Line 1269 of yacc.c. */ -#line 4029 "querytransformparser.ypp" +#line 4131 "querytransformparser.ypp" { Q_ASSERT(5); - disallowedConstruct(parseInfo, (yyloc), (yyvsp[(2) - (5)].enums.Bool)); + allowedIn(QXmlQuery::XQuery10, parseInfo, (yyloc), (yyvsp[(2) - (5)].enums.Bool)); Expression::Ptr effExpr; @@ -7184,7 +7288,7 @@ yyreduce: case 390: /* Line 1269 of yacc.c. */ -#line 4063 "querytransformparser.ypp" +#line 4165 "querytransformparser.ypp" { (yyval.enums.Bool) = false; } @@ -7192,7 +7296,7 @@ yyreduce: case 391: /* Line 1269 of yacc.c. */ -#line 4067 "querytransformparser.ypp" +#line 4169 "querytransformparser.ypp" { (yyval.enums.Bool) = true; } @@ -7200,9 +7304,9 @@ yyreduce: case 392: /* Line 1269 of yacc.c. */ -#line 4075 "querytransformparser.ypp" +#line 4177 "querytransformparser.ypp" { - disallowedConstruct(parseInfo, (yyloc), (yyvsp[(2) - (4)].enums.Bool)); + allowedIn(QXmlQuery::XQuery10, parseInfo, (yyloc), (yyvsp[(2) - (4)].enums.Bool)); const Expression::Ptr name(create(new AttributeNameValidator((yyvsp[(3) - (4)].expr)), (yyloc), parseInfo)); @@ -7215,7 +7319,7 @@ yyreduce: case 393: /* Line 1269 of yacc.c. */ -#line 4087 "querytransformparser.ypp" +#line 4189 "querytransformparser.ypp" { (yyval.expr) = create(new TextNodeConstructor(createSimpleContent((yyvsp[(3) - (3)].expr), (yyloc), parseInfo)), (yyloc), parseInfo); } @@ -7223,9 +7327,9 @@ yyreduce: case 394: /* Line 1269 of yacc.c. */ -#line 4092 "querytransformparser.ypp" +#line 4194 "querytransformparser.ypp" { - disallowedConstruct(parseInfo, (yyloc), (yyvsp[(2) - (3)].enums.Bool)); + allowedIn(QXmlQuery::XQuery10, parseInfo, (yyloc), (yyvsp[(2) - (3)].enums.Bool)); (yyval.expr) = create(new CommentConstructor(createSimpleContent((yyvsp[(3) - (3)].expr), (yyloc), parseInfo)), (yyloc), parseInfo); } @@ -7233,9 +7337,9 @@ yyreduce: case 395: /* Line 1269 of yacc.c. */ -#line 4099 "querytransformparser.ypp" +#line 4201 "querytransformparser.ypp" { - disallowedConstruct(parseInfo, (yyloc), (yyvsp[(2) - (3)].expr)); + allowedIn(QXmlQuery::XQuery10, parseInfo, (yyloc), (yyvsp[(2) - (3)].expr)); if((yyvsp[(3) - (3)].expr)) { @@ -7248,7 +7352,7 @@ yyreduce: case 396: /* Line 1269 of yacc.c. */ -#line 4110 "querytransformparser.ypp" +#line 4212 "querytransformparser.ypp" { parseInfo->nodeTestSource = BuiltinTypes::attribute; } @@ -7256,7 +7360,7 @@ yyreduce: case 397: /* Line 1269 of yacc.c. */ -#line 4114 "querytransformparser.ypp" +#line 4216 "querytransformparser.ypp" { parseInfo->restoreNodeTestSource(); } @@ -7264,7 +7368,7 @@ yyreduce: case 398: /* Line 1269 of yacc.c. */ -#line 4117 "querytransformparser.ypp" +#line 4219 "querytransformparser.ypp" { (yyval.expr) = create(new Literal(toItem(QNameValue::fromValue(parseInfo->staticContext->namePool(), (yyvsp[(2) - (3)].qName)))), (yyloc), parseInfo); } @@ -7272,7 +7376,7 @@ yyreduce: case 400: /* Line 1269 of yacc.c. */ -#line 4123 "querytransformparser.ypp" +#line 4225 "querytransformparser.ypp" { (yyval.expr) = create(new Literal(toItem(QNameValue::fromValue(parseInfo->staticContext->namePool(), (yyvsp[(1) - (1)].qName)))), (yyloc), parseInfo); } @@ -7280,7 +7384,7 @@ yyreduce: case 402: /* Line 1269 of yacc.c. */ -#line 4129 "querytransformparser.ypp" +#line 4231 "querytransformparser.ypp" { if(BuiltinTypes::xsQName->xdtTypeMatches((yyvsp[(1) - (1)].expr)->staticType()->itemType())) (yyval.expr) = (yyvsp[(1) - (1)].expr); @@ -7295,7 +7399,7 @@ yyreduce: case 403: /* Line 1269 of yacc.c. */ -#line 4144 "querytransformparser.ypp" +#line 4246 "querytransformparser.ypp" { (yyval.expr) = create(new NCNameConstructor(create(new Literal(AtomicString::fromValue((yyvsp[(1) - (1)].sval))), (yyloc), parseInfo)), (yyloc), parseInfo); } @@ -7303,7 +7407,7 @@ yyreduce: case 404: /* Line 1269 of yacc.c. */ -#line 4148 "querytransformparser.ypp" +#line 4250 "querytransformparser.ypp" { (yyval.expr) = create(new NCNameConstructor((yyvsp[(1) - (1)].expr)), (yyloc), parseInfo); } @@ -7311,7 +7415,7 @@ yyreduce: case 405: /* Line 1269 of yacc.c. */ -#line 4157 "querytransformparser.ypp" +#line 4259 "querytransformparser.ypp" { (yyval.expr) = create(new ComputedNamespaceConstructor((yyvsp[(2) - (3)].expr), (yyvsp[(3) - (3)].expr)), (yyloc), parseInfo); } @@ -7319,7 +7423,7 @@ yyreduce: case 406: /* Line 1269 of yacc.c. */ -#line 4162 "querytransformparser.ypp" +#line 4264 "querytransformparser.ypp" { (yyval.sequenceType) = makeGenericSequenceType((yyvsp[(1) - (1)].itemType), Cardinality::exactlyOne()); } @@ -7327,7 +7431,7 @@ yyreduce: case 407: /* Line 1269 of yacc.c. */ -#line 4166 "querytransformparser.ypp" +#line 4268 "querytransformparser.ypp" { (yyval.sequenceType) = makeGenericSequenceType((yyvsp[(1) - (2)].itemType), Cardinality::zeroOrOne()); } @@ -7335,7 +7439,7 @@ yyreduce: case 408: /* Line 1269 of yacc.c. */ -#line 4171 "querytransformparser.ypp" +#line 4273 "querytransformparser.ypp" { (yyval.sequenceType) = CommonSequenceTypes::ZeroOrMoreItems; } @@ -7343,7 +7447,7 @@ yyreduce: case 409: /* Line 1269 of yacc.c. */ -#line 4175 "querytransformparser.ypp" +#line 4277 "querytransformparser.ypp" { (yyval.sequenceType) = (yyvsp[(2) - (2)].sequenceType); } @@ -7351,7 +7455,7 @@ yyreduce: case 410: /* Line 1269 of yacc.c. */ -#line 4180 "querytransformparser.ypp" +#line 4282 "querytransformparser.ypp" { (yyval.sequenceType) = makeGenericSequenceType((yyvsp[(1) - (2)].itemType), (yyvsp[(2) - (2)].cardinality)); } @@ -7359,7 +7463,7 @@ yyreduce: case 411: /* Line 1269 of yacc.c. */ -#line 4185 "querytransformparser.ypp" +#line 4287 "querytransformparser.ypp" { (yyval.sequenceType) = CommonSequenceTypes::Empty; } @@ -7367,31 +7471,31 @@ yyreduce: case 412: /* Line 1269 of yacc.c. */ -#line 4189 "querytransformparser.ypp" +#line 4291 "querytransformparser.ypp" {(yyval.cardinality) = Cardinality::exactlyOne();} break; case 413: /* Line 1269 of yacc.c. */ -#line 4190 "querytransformparser.ypp" +#line 4292 "querytransformparser.ypp" {(yyval.cardinality) = Cardinality::oneOrMore();} break; case 414: /* Line 1269 of yacc.c. */ -#line 4191 "querytransformparser.ypp" +#line 4293 "querytransformparser.ypp" {(yyval.cardinality) = Cardinality::zeroOrMore();} break; case 415: /* Line 1269 of yacc.c. */ -#line 4192 "querytransformparser.ypp" +#line 4294 "querytransformparser.ypp" {(yyval.cardinality) = Cardinality::zeroOrOne();} break; case 419: /* Line 1269 of yacc.c. */ -#line 4198 "querytransformparser.ypp" +#line 4300 "querytransformparser.ypp" { (yyval.itemType) = BuiltinTypes::item; } @@ -7399,7 +7503,7 @@ yyreduce: case 420: /* Line 1269 of yacc.c. */ -#line 4203 "querytransformparser.ypp" +#line 4305 "querytransformparser.ypp" { const SchemaType::Ptr t(parseInfo->staticContext->schemaDefinitions()->createSchemaType((yyvsp[(1) - (1)].qName))); @@ -7435,7 +7539,7 @@ yyreduce: case 428: /* Line 1269 of yacc.c. */ -#line 4247 "querytransformparser.ypp" +#line 4349 "querytransformparser.ypp" { (yyval.itemType) = BuiltinTypes::node; } @@ -7443,7 +7547,7 @@ yyreduce: case 429: /* Line 1269 of yacc.c. */ -#line 4252 "querytransformparser.ypp" +#line 4354 "querytransformparser.ypp" { (yyval.itemType) = BuiltinTypes::document; } @@ -7451,7 +7555,7 @@ yyreduce: case 430: /* Line 1269 of yacc.c. */ -#line 4257 "querytransformparser.ypp" +#line 4359 "querytransformparser.ypp" { // TODO support for document element testing (yyval.itemType) = BuiltinTypes::document; @@ -7460,7 +7564,7 @@ yyreduce: case 433: /* Line 1269 of yacc.c. */ -#line 4266 "querytransformparser.ypp" +#line 4368 "querytransformparser.ypp" { (yyval.itemType) = BuiltinTypes::text; } @@ -7468,7 +7572,7 @@ yyreduce: case 434: /* Line 1269 of yacc.c. */ -#line 4271 "querytransformparser.ypp" +#line 4373 "querytransformparser.ypp" { (yyval.itemType) = BuiltinTypes::comment; } @@ -7476,7 +7580,7 @@ yyreduce: case 435: /* Line 1269 of yacc.c. */ -#line 4276 "querytransformparser.ypp" +#line 4378 "querytransformparser.ypp" { (yyval.itemType) = BuiltinTypes::pi; } @@ -7484,7 +7588,7 @@ yyreduce: case 436: /* Line 1269 of yacc.c. */ -#line 4281 "querytransformparser.ypp" +#line 4383 "querytransformparser.ypp" { (yyval.itemType) = LocalNameTest::create(BuiltinTypes::pi, parseInfo->staticContext->namePool()->allocateLocalName((yyvsp[(3) - (4)].sval))); } @@ -7492,7 +7596,7 @@ yyreduce: case 437: /* Line 1269 of yacc.c. */ -#line 4286 "querytransformparser.ypp" +#line 4388 "querytransformparser.ypp" { if(QXmlUtils::isNCName((yyvsp[(3) - (4)].sval))) { @@ -7511,7 +7615,7 @@ yyreduce: case 440: /* Line 1269 of yacc.c. */ -#line 4305 "querytransformparser.ypp" +#line 4407 "querytransformparser.ypp" { (yyval.itemType) = BuiltinTypes::attribute; } @@ -7519,7 +7623,7 @@ yyreduce: case 441: /* Line 1269 of yacc.c. */ -#line 4310 "querytransformparser.ypp" +#line 4412 "querytransformparser.ypp" { (yyval.itemType) = BuiltinTypes::attribute; } @@ -7527,7 +7631,7 @@ yyreduce: case 442: /* Line 1269 of yacc.c. */ -#line 4315 "querytransformparser.ypp" +#line 4417 "querytransformparser.ypp" { (yyval.itemType) = QNameTest::create(BuiltinTypes::attribute, (yyvsp[(3) - (4)].qName)); } @@ -7535,7 +7639,7 @@ yyreduce: case 443: /* Line 1269 of yacc.c. */ -#line 4319 "querytransformparser.ypp" +#line 4421 "querytransformparser.ypp" { const SchemaType::Ptr t(parseInfo->staticContext->schemaDefinitions()->createSchemaType((yyvsp[(5) - (6)].qName))); @@ -7551,7 +7655,7 @@ yyreduce: case 444: /* Line 1269 of yacc.c. */ -#line 4331 "querytransformparser.ypp" +#line 4433 "querytransformparser.ypp" { const SchemaType::Ptr t(parseInfo->staticContext->schemaDefinitions()->createSchemaType((yyvsp[(5) - (6)].qName))); @@ -7567,7 +7671,7 @@ yyreduce: case 445: /* Line 1269 of yacc.c. */ -#line 4344 "querytransformparser.ypp" +#line 4446 "querytransformparser.ypp" { parseInfo->staticContext->error(QtXmlPatterns::tr("%1 is not in the in-scope attribute " "declarations. Note that the schema import " @@ -7580,7 +7684,7 @@ yyreduce: case 446: /* Line 1269 of yacc.c. */ -#line 4354 "querytransformparser.ypp" +#line 4456 "querytransformparser.ypp" { (yyval.itemType) = BuiltinTypes::element; } @@ -7588,7 +7692,7 @@ yyreduce: case 447: /* Line 1269 of yacc.c. */ -#line 4359 "querytransformparser.ypp" +#line 4461 "querytransformparser.ypp" { (yyval.itemType) = BuiltinTypes::element; } @@ -7596,7 +7700,7 @@ yyreduce: case 448: /* Line 1269 of yacc.c. */ -#line 4364 "querytransformparser.ypp" +#line 4466 "querytransformparser.ypp" { (yyval.itemType) = QNameTest::create(BuiltinTypes::element, (yyvsp[(3) - (4)].qName)); } @@ -7604,7 +7708,7 @@ yyreduce: case 449: /* Line 1269 of yacc.c. */ -#line 4369 "querytransformparser.ypp" +#line 4471 "querytransformparser.ypp" { const SchemaType::Ptr t(parseInfo->staticContext->schemaDefinitions()->createSchemaType((yyvsp[(5) - (7)].qName))); @@ -7621,7 +7725,7 @@ yyreduce: case 450: /* Line 1269 of yacc.c. */ -#line 4383 "querytransformparser.ypp" +#line 4485 "querytransformparser.ypp" { const SchemaType::Ptr t(parseInfo->staticContext->schemaDefinitions()->createSchemaType((yyvsp[(5) - (7)].qName))); @@ -7638,7 +7742,7 @@ yyreduce: case 453: /* Line 1269 of yacc.c. */ -#line 4400 "querytransformparser.ypp" +#line 4502 "querytransformparser.ypp" { parseInfo->staticContext->error(QtXmlPatterns::tr("%1 is not in the in-scope attribute " "declarations. Note that the schema import " @@ -7651,7 +7755,7 @@ yyreduce: case 455: /* Line 1269 of yacc.c. */ -#line 4412 "querytransformparser.ypp" +#line 4514 "querytransformparser.ypp" { (yyval.qName) = parseInfo->staticContext->namePool()->allocateQName(StandardNamespaces::empty, (yyvsp[(1) - (1)].sval)); } @@ -7659,7 +7763,7 @@ yyreduce: case 457: /* Line 1269 of yacc.c. */ -#line 4424 "querytransformparser.ypp" +#line 4526 "querytransformparser.ypp" { if(parseInfo->nodeTestSource == BuiltinTypes::element) (yyval.qName) = parseInfo->staticContext->namePool()->allocateQName(parseInfo->staticContext->namespaceBindings()->lookupNamespaceURI(StandardPrefixes::empty), (yyvsp[(1) - (1)].sval)); @@ -7670,7 +7774,7 @@ yyreduce: case 462: /* Line 1269 of yacc.c. */ -#line 4438 "querytransformparser.ypp" +#line 4540 "querytransformparser.ypp" { (yyval.qName) = parseInfo->staticContext->namePool()->allocateQName(parseInfo->staticContext->defaultFunctionNamespace(), (yyvsp[(1) - (1)].sval)); } @@ -7678,7 +7782,7 @@ yyreduce: case 463: /* Line 1269 of yacc.c. */ -#line 4442 "querytransformparser.ypp" +#line 4544 "querytransformparser.ypp" { (yyval.qName) = parseInfo->staticContext->namePool()->allocateQName(StandardNamespaces::InternalXSLT, (yyvsp[(2) - (2)].sval)); } @@ -7686,7 +7790,7 @@ yyreduce: case 466: /* Line 1269 of yacc.c. */ -#line 4450 "querytransformparser.ypp" +#line 4552 "querytransformparser.ypp" { parseInfo->staticContext->error(QtXmlPatterns::tr("The name of an extension expression must be in " "a namespace."), @@ -7694,9 +7798,25 @@ yyreduce: } break; + case 469: +/* Line 1269 of yacc.c. */ +#line 4562 "querytransformparser.ypp" + { + allowedIn(QueryLanguages(QXmlQuery::XQuery10 | QXmlQuery::XPath20), parseInfo, (yyloc)); + } + break; + + case 470: +/* Line 1269 of yacc.c. */ +#line 4566 "querytransformparser.ypp" + { + allowedIn(QueryLanguages(QXmlQuery::XQuery10 | QXmlQuery::XPath20), parseInfo, (yyloc)); + } + break; + case 471: /* Line 1269 of yacc.c. */ -#line 4463 "querytransformparser.ypp" +#line 4571 "querytransformparser.ypp" { const ReflectYYLTYPE ryy((yyloc), parseInfo); @@ -7712,7 +7832,7 @@ yyreduce: case 472: /* Line 1269 of yacc.c. */ -#line 4475 "querytransformparser.ypp" +#line 4583 "querytransformparser.ypp" { (yyval.qName) = parseInfo->staticContext->namePool()->fromClarkName((yyvsp[(1) - (1)].sval)); } @@ -7720,7 +7840,7 @@ yyreduce: /* Line 1269 of yacc.c. */ -#line 7643 "qquerytransformparser.cpp" +#line 7763 "qquerytransformparser.cpp" default: break; } YY_SYMBOL_PRINT ("-> $$ =", yyr1[yyn], &yyval, &yyloc); @@ -7938,7 +8058,7 @@ yyreturn: /* Line 1486 of yacc.c. */ -#line 4479 "querytransformparser.ypp" +#line 4587 "querytransformparser.ypp" QString Tokenizer::tokenToString(const Token &token) diff --git a/src/xmlpatterns/parser/qquerytransformparser_p.h b/src/xmlpatterns/parser/qquerytransformparser_p.h index fcf8896..759c39f 100644 --- a/src/xmlpatterns/parser/qquerytransformparser_p.h +++ b/src/xmlpatterns/parser/qquerytransformparser_p.h @@ -49,6 +49,27 @@ // // We mean it. +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the $MODULE$ of the Qt Toolkit. +** +** $TROLLTECH_DUAL_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. + /* A Bison parser, made by GNU Bison 2.3a. */ /* Skeleton interface for Bison's Yacc-like parsers in C @@ -104,6 +125,25 @@ # undef SELF #endif +/* These tokens are defined to nothing on Windows because they're + * used in their documentation parser, for use in things like: + * + * int foo(IN char* name, OUT char* path); + * + * Hence this un-break fix. Note that this file was auto generated. */ +#ifdef IN +# undef IN +#endif +#ifdef INSTANCE +# undef INSTANCE +#endif +#ifdef STRICT +# undef STRICT +#endif +#ifdef SELF +# undef SELF +#endif + /* Tokens. */ #ifndef YYTOKENTYPE # define YYTOKENTYPE diff --git a/src/xmlpatterns/parser/querytransformparser.ypp b/src/xmlpatterns/parser/querytransformparser.ypp index 93974a4..e4f6b2d 100644 --- a/src/xmlpatterns/parser/querytransformparser.ypp +++ b/src/xmlpatterns/parser/querytransformparser.ypp @@ -227,11 +227,18 @@ static inline QSourceLocation fromYYLTYPE(const YYLTYPE &sourceLocator, } /** + * @internal + * @relates QXmlQuery + */ +typedef QFlags QueryLanguages; + +/** * @short Flags invalid expressions and declarations in the currently * parsed language. * - * Since this grammar is used for several languages: XQuery 1.0, XSL-T 2.0 and - * XPath 2.0 inside XSL-T, it is the union of all the constructs in these + * Since this grammar is used for several languages: XQuery 1.0, XSL-T 2.0, and + * XPath 2.0 inside XSL-T, and field and selector patterns in W3C XML Schema's + * identity constraints, it is the union of all the constructs in these * languages. However, when dealing with each language individually, we * regularly need to disallow some expressions, such as direct element * constructors when parsing XSL-T, or the typeswitch when parsing XPath. @@ -242,19 +249,46 @@ static inline QSourceLocation fromYYLTYPE(const YYLTYPE &sourceLocator, * instance the @c let clause, should not be flagged as an error, because it's * used for internal purposes. * - * Hence, this function is called from each expression and declaration which is - * unavailable in XPath. + * Hence, this function is called from each expression and declaration with @p + * allowedLanguages stating what languages it is allowed in. * * If @p isInternal is @c true, no error is raised. Otherwise, if the current - * language is not XQuery, an error is raised. + * language is not in @p allowedLanguages, an error is raised. */ -static void disallowedConstruct(const ParserContext *const parseInfo, - const YYLTYPE &sourceLocator, - const bool isInternal = false) +static void allowedIn(const QueryLanguages allowedLanguages, + const ParserContext *const parseInfo, + const YYLTYPE &sourceLocator, + const bool isInternal = false) { - if(!isInternal && parseInfo->languageAccent != QXmlQuery::XQuery10) + /* We treat XPath 2.0 as a subset of XSL-T 2.0, so if XPath 2.0 is allowed + * and XSL-T is the language, it's ok. */ + if(!isInternal && + (!allowedLanguages.testFlag(parseInfo->languageAccent) && !(allowedLanguages.testFlag(QXmlQuery::XPath20) && parseInfo->languageAccent == QXmlQuery::XSLT20))) { - parseInfo->staticContext->error(QtXmlPatterns::tr("A construct was encountered which only is allowed in XQuery."), + + QString langName; + + switch(parseInfo->languageAccent) + { + case QXmlQuery::XPath20: + langName = QLatin1String("XPath 2.0"); + break; + case QXmlQuery::XSLT20: + langName = QLatin1String("XSL-T 2.0"); + break; + case QXmlQuery::XQuery10: + langName = QLatin1String("XQuery 1.0"); + break; + case QXmlQuery::XmlSchema11IdentityConstraintSelector: + langName = QtXmlPatterns::tr("W3C XML Schema identity constraint selector"); + break; + case QXmlQuery::XmlSchema11IdentityConstraintField: + langName = QtXmlPatterns::tr("W3C XML Schema identity constraint field"); + break; + } + + parseInfo->staticContext->error(QtXmlPatterns::tr("A construct was encountered " + "which is disallowed in the current language(%1).").arg(langName), ReportContext::XPST0003, fromYYLTYPE(sourceLocator, parseInfo)); @@ -1560,7 +1594,7 @@ Prolog: /* Empty. */ /* First part. */ | Prolog DefaultNamespaceDecl { - disallowedConstruct(parseInfo, @$); + allowedIn(QXmlQuery::XQuery10, parseInfo, @$); if(parseInfo->hasSecondPrologPart) parseInfo->staticContext->error(QtXmlPatterns::tr("A default namespace declaration must occur before function, " "variable, and option declarations."), ReportContext::XPST0003, fromYYLTYPE(@$, parseInfo)); @@ -1579,7 +1613,7 @@ Prolog: /* Empty. */ } | Prolog Import { - disallowedConstruct(parseInfo, @$); + allowedIn(QXmlQuery::XQuery10, parseInfo, @$); if(parseInfo->hasSecondPrologPart) parseInfo->staticContext->error(QtXmlPatterns::tr("Module imports must occur before function, " "variable, and option declarations."), ReportContext::XPST0003, fromYYLTYPE(@$, parseInfo)); @@ -1597,7 +1631,7 @@ Prolog: /* Empty. */ } | Prolog OptionDecl { - disallowedConstruct(parseInfo, @$); + allowedIn(QXmlQuery::XQuery10, parseInfo, @$); parseInfo->hasSecondPrologPart = true; } @@ -1730,20 +1764,20 @@ TemplateName: NAME ElementName Setter: BoundarySpaceDecl /* [7] */ | DefaultCollationDecl { - disallowedConstruct(parseInfo, @$); + allowedIn(QXmlQuery::XQuery10, parseInfo, @$); } | BaseURIDecl | ConstructionDecl { - disallowedConstruct(parseInfo, @$); + allowedIn(QXmlQuery::XQuery10, parseInfo, @$); } | OrderingModeDecl { - disallowedConstruct(parseInfo, @$); + allowedIn(QXmlQuery::XQuery10, parseInfo, @$); } | EmptyOrderDecl { - disallowedConstruct(parseInfo, @$); + allowedIn(QXmlQuery::XQuery10, parseInfo, @$); } | CopyNamespacesDecl @@ -1755,7 +1789,7 @@ Separator: SEMI_COLON NamespaceDecl: DECLARE NAMESPACE NCNAME G_EQ URILiteral IsInternal Separator /* [10] */ { if(!$6) - disallowedConstruct(parseInfo, @$); + allowedIn(QXmlQuery::XQuery10, parseInfo, @$); if($3 == QLatin1String("xmlns")) { @@ -1867,7 +1901,7 @@ OptionDecl: DECLARE OPTION ElementName StringLiteral Separator OrderingModeDecl: DECLARE ORDERING OrderingMode Separator /* [14] */ { - disallowedConstruct(parseInfo, @$); + allowedIn(QXmlQuery::XQuery10, parseInfo, @$); if(parseInfo->hasDeclaration(ParserContext::OrderingModeDecl)) { parseInfo->staticContext->error(prologMessage("declare ordering"), @@ -1964,7 +1998,7 @@ DefaultCollationDecl: DECLARE DEFAULT COLLATION StringLiteral Separator BaseURIDecl: DECLARE BASEURI IsInternal URILiteral Separator /* [20] */ { - disallowedConstruct(parseInfo, @$, $3); + allowedIn(QueryLanguages(QXmlQuery::XQuery10 | QXmlQuery::XSLT20), parseInfo, @$, $3); if(parseInfo->hasDeclaration(ParserContext::BaseURIDecl)) { parseInfo->staticContext->error(prologMessage("declare base-uri"), @@ -2026,7 +2060,7 @@ FileLocation: URILiteral VarDecl: DECLARE VARIABLE IsInternal DOLLAR VarName TypeDeclaration VariableValue OptionalDefaultValue Separator /* [24] */ { - disallowedConstruct(parseInfo, @$, $3); + allowedIn(QXmlQuery::XQuery10, parseInfo, @$, $3); if(variableByName($5, parseInfo)) { parseInfo->staticContext->error(QtXmlPatterns::tr("A variable by name %1 has already " @@ -2126,7 +2160,7 @@ FunctionDecl: DECLARE FUNCTION IsInternal FunctionName LPAREN ParamList RPAREN TypeDeclaration FunctionBody Separator /* [26] */ { if(!$3) - disallowedConstruct(parseInfo, @$, $3); + allowedIn(QXmlQuery::XQuery10, parseInfo, @$, $3); /* If FunctionBody is null, it is 'external', otherwise the value is the body. */ const QXmlName::NamespaceCode ns($4.namespaceURI()); @@ -2696,7 +2730,7 @@ LetClause: LET IsInternal DOLLAR VarName TypeDeclaration ASSIGN ExprSingle } LetTail /* [36] */ { - disallowedConstruct(parseInfo, @$, $2); + allowedIn(QXmlQuery::XQuery10, parseInfo, @$, $2); Q_ASSERT(parseInfo->variables.top()->name == $4); $$ = create(new LetClause($8, $9, parseInfo->variables.top()), @$, parseInfo); @@ -2835,6 +2869,7 @@ SomeQuantificationExpr: SOME DOLLAR VarName TypeDeclaration IN ExprSingle {$$ = parseInfo->staticContext->currentRangeSlot();} SomeQuantificationTail /* [X] */ { + allowedIn(QueryLanguages(QXmlQuery::XQuery10 | QXmlQuery::XPath20), parseInfo, @$); $$ = create(new QuantifiedExpression($8, QuantifiedExpression::Some, $6, $9), @$, parseInfo); parseInfo->finalizePushedVariable(); @@ -2863,6 +2898,7 @@ EveryQuantificationExpr: EVERY DOLLAR VarName TypeDeclaration IN ExprSingle {$$ = parseInfo->staticContext->currentRangeSlot();} EveryQuantificationTail /* [X] */ { + allowedIn(QueryLanguages(QXmlQuery::XQuery10 | QXmlQuery::XPath20), parseInfo, @$); $$ = create(new QuantifiedExpression($8, QuantifiedExpression::Every, $6, $9), @$, parseInfo); parseInfo->finalizePushedVariable(); @@ -2916,7 +2952,7 @@ TypeswitchExpr: TYPESWITCH LPAREN Expr RPAREN } CaseClause /* [43] */ { - disallowedConstruct(parseInfo, @$); + allowedIn(QXmlQuery::XQuery10, parseInfo, @$); parseInfo->typeswitchSource.pop(); $$ = $6; } @@ -2976,18 +3012,21 @@ CaseDefault: DEFAULT RETURN ExprSingle IfExpr: IF LPAREN Expr RPAREN THEN ExprSingle ELSE ExprSingle /* [45] */ { + allowedIn(QueryLanguages(QXmlQuery::XQuery10 | QXmlQuery::XPath20), parseInfo, @$); $$ = create(new IfThenClause($3, $6, $8), @$, parseInfo); } OrExpr: AndExpr /* [46] */ | OrExpr OR AndExpr { + allowedIn(QueryLanguages(QXmlQuery::XQuery10 | QXmlQuery::XPath20), parseInfo, @$); $$ = create(new OrExpression($1, $3), @$, parseInfo); } AndExpr: ComparisonExpr /* [47] */ | AndExpr AND ComparisonExpr { + allowedIn(QueryLanguages(QXmlQuery::XQuery10 | QXmlQuery::XPath20), parseInfo, @$); $$ = create(new AndExpression($1, $3), @$, parseInfo); } @@ -2999,12 +3038,14 @@ ComparisonExpr: RangeExpr RangeExpr: AdditiveExpr /* [49] */ | AdditiveExpr TO AdditiveExpr { + allowedIn(QueryLanguages(QXmlQuery::XQuery10 | QXmlQuery::XPath20), parseInfo, @$); $$ = create(new RangeExpression($1, $3), @$, parseInfo); } AdditiveExpr: MultiplicativeExpr /* [50] */ | AdditiveExpr AdditiveOperator MultiplicativeExpr { + allowedIn(QueryLanguages(QXmlQuery::XQuery10 | QXmlQuery::XPath20), parseInfo, @$); $$ = create(new ArithmeticExpression($1, $2, $3), @$, parseInfo); } @@ -3014,6 +3055,7 @@ AdditiveOperator: PLUS {$$ = AtomicMathematician::Add;} MultiplicativeExpr: UnionExpr /* [51] */ | MultiplicativeExpr MultiplyOperator UnionExpr { + allowedIn(QueryLanguages(QXmlQuery::XQuery10 | QXmlQuery::XPath20), parseInfo, @$); $$ = create(new ArithmeticExpression($1, $2, $3), @$, parseInfo); } @@ -3025,12 +3067,18 @@ MultiplyOperator: STAR {$$ = AtomicMathematician::Multiply;} UnionExpr: IntersectExceptExpr /* [52] */ | UnionExpr UnionOperator IntersectExceptExpr { + allowedIn(QueryLanguages(QXmlQuery::XQuery10 + | QXmlQuery::XPath20 + | QXmlQuery::XmlSchema11IdentityConstraintField + | QXmlQuery::XmlSchema11IdentityConstraintSelector), + parseInfo, @$); $$ = create(new CombineNodes($1, CombineNodes::Union, $3), @$, parseInfo); } IntersectExceptExpr: InstanceOfExpr /* [53] */ | IntersectExceptExpr IntersectOperator InstanceOfExpr { + allowedIn(QueryLanguages(QXmlQuery::XQuery10 | QXmlQuery::XPath20), parseInfo, @$); $$ = create(new CombineNodes($1, $2, $3), @$, parseInfo); } @@ -3049,31 +3097,36 @@ IntersectOperator: INTERSECT InstanceOfExpr: TreatExpr /* [54] */ | TreatExpr INSTANCE OF SequenceType { + allowedIn(QueryLanguages(QXmlQuery::XQuery10 | QXmlQuery::XPath20), parseInfo, @$); $$ = create(new InstanceOf($1, - SequenceType::Ptr($4)), @$, parseInfo); + SequenceType::Ptr($4)), @$, parseInfo); } TreatExpr: CastableExpr /* [55] */ | CastableExpr TREAT AS SequenceType { + allowedIn(QueryLanguages(QXmlQuery::XQuery10 | QXmlQuery::XPath20), parseInfo, @$); $$ = create(new TreatAs($1, $4), @$, parseInfo); } CastableExpr: CastExpr /* [56] */ | CastExpr CASTABLE AS SingleType { + allowedIn(QueryLanguages(QXmlQuery::XQuery10 | QXmlQuery::XPath20), parseInfo, @$); $$ = create(new CastableAs($1, $4), @$, parseInfo); } CastExpr: UnaryExpr /* [57] */ | UnaryExpr CAST AS SingleType { + allowedIn(QueryLanguages(QXmlQuery::XQuery10 | QXmlQuery::XPath20), parseInfo, @$); $$ = create(new CastAs($1, $4), @$, parseInfo); } UnaryExpr: ValueExpr /* [58] */ | UnaryOperator UnaryExpr { + allowedIn(QueryLanguages(QXmlQuery::XQuery10 | QXmlQuery::XPath20), parseInfo, @$); $$ = create(new UnaryExpression($1, $2, parseInfo->staticContext), @$, parseInfo); } @@ -3092,6 +3145,7 @@ ValueExpr: ValidateExpr GeneralComp: RangeExpr GeneralComparisonOperator RangeExpr /* [60] */ { + allowedIn(QueryLanguages(QXmlQuery::XQuery10 | QXmlQuery::XPath20), parseInfo, @$); $$ = create(new GeneralComparison($1, $2, $3, parseInfo->isBackwardsCompat.top()), @$, parseInfo); } @@ -3125,7 +3179,7 @@ NodeOperator: IS {$$ = QXmlNodeModelIndex::Is;} ValidateExpr: ValidationMode EnclosedExpr /* [63] */ { - disallowedConstruct(parseInfo, @$); + allowedIn(QXmlQuery::XQuery10, parseInfo, @$); parseInfo->staticContext->error(QtXmlPatterns::tr("The Schema Validation Feature is not supported. " "Hence, %1-expressions may not be used.") .arg(formatKeyword("validate")), @@ -3143,6 +3197,7 @@ ValidationMode: VALIDATE {$$ = Validate::Strict;} ExtensionExpr: Pragmas EnclosedOptionalExpr /* [65] */ { + allowedIn(QXmlQuery::XQuery10, parseInfo, @$); /* We don't support any pragmas, so we only do the * necessary validation and use the fallback expression. */ @@ -3171,7 +3226,7 @@ Pragmas: Pragmas Pragma Pragma: PRAGMA_START PragmaName PragmaContents PRAGMA_END /* [66] */ { - disallowedConstruct(parseInfo, @$); + allowedIn(QXmlQuery::XQuery10, parseInfo, @$); } PragmaContents: /* empty */ /* [67] */ @@ -3241,12 +3296,14 @@ StepExpr: FilteredAxisStep } | BASEURI StringLiteral CURLY_LBRACE Expr CURLY_RBRACE /* [X] */ { + allowedIn(QXmlQuery::XSLT20, parseInfo, @$); Q_ASSERT(!$2.isEmpty()); $$ = create(new StaticBaseURIStore($2, $4), @$, parseInfo); } | DECLARE NAMESPACE NCNAME G_EQ STRING_LITERAL CURLY_LBRACE /* [X] */ { + allowedIn(QueryLanguages(QXmlQuery::XQuery10 | QXmlQuery::XSLT20), parseInfo, @$); parseInfo->resolvers.push(parseInfo->staticContext->namespaceBindings()); const NamespaceResolver::Ptr resolver(new DelegatingNamespaceResolver(parseInfo->staticContext->namespaceBindings())); resolver->addBinding(QXmlName(parseInfo->staticContext->namePool()->allocateNamespace($5), @@ -3449,6 +3506,36 @@ Axis: AxisToken COLONCOLON } else $$ = $1; + + switch($1) + { + case QXmlNodeModelIndex::AxisAttribute: + { + allowedIn(QueryLanguages( QXmlQuery::XPath20 + | QXmlQuery::XQuery10 + | QXmlQuery::XmlSchema11IdentityConstraintField + | QXmlQuery::XSLT20), + parseInfo, @$); + break; + } + case QXmlNodeModelIndex::AxisChild: + { + allowedIn(QueryLanguages( QXmlQuery::XPath20 + | QXmlQuery::XQuery10 + | QXmlQuery::XmlSchema11IdentityConstraintField + | QXmlQuery::XmlSchema11IdentityConstraintSelector + | QXmlQuery::XSLT20), + parseInfo, @$); + break; + } + default: + { + allowedIn(QueryLanguages( QXmlQuery::XPath20 + | QXmlQuery::XQuery10 + | QXmlQuery::XSLT20), + parseInfo, @$); + } + } } AxisToken: ANCESTOR_OR_SELF {$$ = QXmlNodeModelIndex::AxisAncestorOrSelf ;} @@ -3470,6 +3557,7 @@ AbbrevForwardStep: AT_SIGN } NodeTest /* [72] */ { + allowedIn(QueryLanguages(QXmlQuery::XQuery10 | QXmlQuery::XSLT20 | QXmlQuery::XmlSchema11IdentityConstraintField), parseInfo, @$); $$ = create(new AxisStep(QXmlNodeModelIndex::AxisAttribute, $3), @$, parseInfo); parseInfo->restoreNodeTestSource(); @@ -3499,6 +3587,9 @@ AbbrevReverseStep: DOTDOT NodeTest: NameTest /* [78] */ | KindTest + { + allowedIn(QueryLanguages(QXmlQuery::XQuery10 | QXmlQuery::XPath20), parseInfo, @$); + } NameTest: ElementName /* [79] */ { @@ -3521,6 +3612,7 @@ WildCard: STAR } | ANY_PREFIX { + allowedIn(QueryLanguages(QXmlQuery::XQuery10 | QXmlQuery::XPath20), parseInfo, @$); const QXmlName::LocalNameCode c = parseInfo->staticContext->namePool()->allocateLocalName($1); $$ = LocalNameTest::create(parseInfo->nodeTestSource, c); } @@ -3528,6 +3620,7 @@ WildCard: STAR FilterExpr: PrimaryExpr /* [81] */ | FilterExpr LBRACKET Expr RBRACKET { + allowedIn(QueryLanguages(QXmlQuery::XQuery10 | QXmlQuery::XPath20), parseInfo, @$); $$ = create(GenericPredicate::create($1, $3, parseInfo->staticContext, fromYYLTYPE(@4, parseInfo)), @$, parseInfo); } @@ -3556,15 +3649,18 @@ Literal: NumericLiteral NumericLiteral: XPATH2_NUMBER /* [86] */ { + allowedIn(QueryLanguages(QXmlQuery::XQuery10 | QXmlQuery::XPath20), parseInfo, @$); $$ = createNumericLiteral($1, @$, parseInfo); } | NUMBER { + allowedIn(QueryLanguages(QXmlQuery::XQuery10 | QXmlQuery::XPath20), parseInfo, @$); $$ = createNumericLiteral($1, @$, parseInfo); } VarRef: DOLLAR VarName /* [87] */ { + allowedIn(QueryLanguages(QXmlQuery::XQuery10 | QXmlQuery::XPath20), parseInfo, @$); $$ = resolveVariable($2, @$, parseInfo, false); } @@ -3580,10 +3676,12 @@ VarName: NCNAME ParenthesizedExpr: LPAREN Expr RPAREN /* [89] */ { + allowedIn(QueryLanguages(QXmlQuery::XQuery10 | QXmlQuery::XPath20), parseInfo, @$); $$ = $2; } | LPAREN RPAREN { + allowedIn(QueryLanguages(QXmlQuery::XQuery10 | QXmlQuery::XPath20), parseInfo, @$); $$ = create(new EmptySequence, @$, parseInfo); } @@ -3599,6 +3697,7 @@ OrderingExpr: OrderingMode EnclosedExpr FunctionCallExpr: FunctionName LPAREN FunctionArguments RPAREN /* [93] */ { + allowedIn(QueryLanguages(QXmlQuery::XQuery10 | QXmlQuery::XPath20), parseInfo, @$); if(XPathHelper::isReservedNamespace($1.namespaceURI()) || $1.namespaceURI() == StandardNamespaces::InternalXSLT) { /* We got a call to a builtin function. */ const ReflectYYLTYPE ryy(@$, parseInfo); @@ -3641,9 +3740,12 @@ FunctionArguments: /* empty */ Constructor: DirectConstructor /* [94] */ { - disallowedConstruct(parseInfo, @$); + allowedIn(QXmlQuery::XQuery10, parseInfo, @$); } | ComputedConstructor +/* The reason we cannot call alloweIn() as the action for ComputedConstructor, + * is that we use the computed constructors for XSL-T, and therefore generate + * INTERNAL tokens. */ DirectConstructor: DirElemConstructor /* [95] */ | DirCommentConstructor @@ -4075,7 +4177,7 @@ ComputedConstructor: CompDocConstructor CompDocConstructor: DOCUMENT IsInternal EnclosedExpr /* [110] */ { - disallowedConstruct(parseInfo, @$, $2); + allowedIn(QXmlQuery::XQuery10, parseInfo, @$, $2); $$ = create(new DocumentConstructor($3), @$, parseInfo); } @@ -4088,7 +4190,7 @@ CompElemConstructor: ELEMENT IsInternal CompElementName EnclosedOptionalExpr /* [111] */ { Q_ASSERT(5); - disallowedConstruct(parseInfo, @$, $2); + allowedIn(QXmlQuery::XQuery10, parseInfo, @$, $2); Expression::Ptr effExpr; @@ -4133,7 +4235,7 @@ CompAttrConstructor: ATTRIBUTE CompAttributeName EnclosedOptionalExpr /* [113] */ { - disallowedConstruct(parseInfo, @$, $2); + allowedIn(QXmlQuery::XQuery10, parseInfo, @$, $2); const Expression::Ptr name(create(new AttributeNameValidator($3), @$, parseInfo)); @@ -4150,14 +4252,14 @@ CompTextConstructor: TEXT IsInternal EnclosedExpr CompCommentConstructor: COMMENT IsInternal EnclosedExpr /* [115] */ { - disallowedConstruct(parseInfo, @$, $2); + allowedIn(QXmlQuery::XQuery10, parseInfo, @$, $2); $$ = create(new CommentConstructor(createSimpleContent($3, @$, parseInfo)), @$, parseInfo); } CompPIConstructor: PROCESSING_INSTRUCTION CompPIName EnclosedOptionalExpr /* [116] */ { - disallowedConstruct(parseInfo, @$, $2); + allowedIn(QXmlQuery::XQuery10, parseInfo, @$, $2); if($3) { @@ -4517,7 +4619,13 @@ PragmaName: NCNAME URILiteral: StringLiteral /* [140] */ StringLiteral: STRING_LITERAL /* [144] */ + { + allowedIn(QueryLanguages(QXmlQuery::XQuery10 | QXmlQuery::XPath20), parseInfo, @$); + } | XPATH2_STRING_LITERAL + { + allowedIn(QueryLanguages(QXmlQuery::XQuery10 | QXmlQuery::XPath20), parseInfo, @$); + } QName: QNAME /* [154] */ { diff --git a/src/xmlpatterns/schema/.gitignore b/src/xmlpatterns/schema/.gitignore new file mode 100644 index 0000000..2b29f27 --- /dev/null +++ b/src/xmlpatterns/schema/.gitignore @@ -0,0 +1 @@ +tests diff --git a/src/xmlpatterns/schema/builtinschemas.qrc b/src/xmlpatterns/schema/builtinschemas.qrc new file mode 100644 index 0000000..fb43d78 --- /dev/null +++ b/src/xmlpatterns/schema/builtinschemas.qrc @@ -0,0 +1,5 @@ + + + schemas/xml.xsd + + diff --git a/src/xmlpatterns/schema/doc/All_diagram.dot b/src/xmlpatterns/schema/doc/All_diagram.dot new file mode 100644 index 0000000..3352b723 --- /dev/null +++ b/src/xmlpatterns/schema/doc/All_diagram.dot @@ -0,0 +1,13 @@ +digraph All { + mindist = 2.0 + 1 -> 2 [label="annotation"] + 1 -> 3 [label="any"] + 1 -> 3 [label="element"] + 2 -> 3 [label="any"] + 2 -> 3 [label="element"] + 3 -> 3 [label="any"] + 3 -> 3 [label="element"] + 1 [shape=doublecircle, style=filled, color=blue] + 2 [shape=doublecircle, style=filled, color=green] + 3 [shape=doublecircle, style=filled, color=green] +} diff --git a/src/xmlpatterns/schema/doc/Alternative_diagram.dot b/src/xmlpatterns/schema/doc/Alternative_diagram.dot new file mode 100644 index 0000000..2119c49 --- /dev/null +++ b/src/xmlpatterns/schema/doc/Alternative_diagram.dot @@ -0,0 +1,11 @@ +digraph Alternative { + mindist = 2.0 + 1 -> 3 [label="complexType"] + 1 -> 2 [label="annotation"] + 1 -> 3 [label="simpleType"] + 2 -> 3 [label="complexType"] + 2 -> 3 [label="simpleType"] + 1 [shape=doublecircle, style=filled, color=blue] + 2 [shape=doublecircle, style=filled, color=green] + 3 [shape=doublecircle, style=filled, color=green] +} diff --git a/src/xmlpatterns/schema/doc/Annotation_diagram.dot b/src/xmlpatterns/schema/doc/Annotation_diagram.dot new file mode 100644 index 0000000..260b6f7 --- /dev/null +++ b/src/xmlpatterns/schema/doc/Annotation_diagram.dot @@ -0,0 +1,9 @@ +digraph Annotation { + mindist = 2.0 + 1 -> 2 [label="appinfo"] + 1 -> 2 [label="documentation"] + 2 -> 2 [label="appinfo"] + 2 -> 2 [label="documentation"] + 1 [shape=doublecircle, style=filled, color=blue] + 2 [shape=doublecircle, style=filled, color=green] +} diff --git a/src/xmlpatterns/schema/doc/AnyAttribute_diagram.dot b/src/xmlpatterns/schema/doc/AnyAttribute_diagram.dot new file mode 100644 index 0000000..d252ebd --- /dev/null +++ b/src/xmlpatterns/schema/doc/AnyAttribute_diagram.dot @@ -0,0 +1,6 @@ +digraph AnyAttribute { + mindist = 2.0 + 1 -> 2 [label="annotation"] + 1 [shape=doublecircle, style=filled, color=blue] + 2 [shape=doublecircle, style=filled, color=green] +} diff --git a/src/xmlpatterns/schema/doc/Any_diagram.dot b/src/xmlpatterns/schema/doc/Any_diagram.dot new file mode 100644 index 0000000..f54063f --- /dev/null +++ b/src/xmlpatterns/schema/doc/Any_diagram.dot @@ -0,0 +1,6 @@ +digraph Any { + mindist = 2.0 + 1 -> 2 [label="annotation"] + 1 [shape=doublecircle, style=filled, color=blue] + 2 [shape=doublecircle, style=filled, color=green] +} diff --git a/src/xmlpatterns/schema/doc/Assert_diagram.dot b/src/xmlpatterns/schema/doc/Assert_diagram.dot new file mode 100644 index 0000000..7093bef --- /dev/null +++ b/src/xmlpatterns/schema/doc/Assert_diagram.dot @@ -0,0 +1,6 @@ +digraph Assert { + mindist = 2.0 + 1 -> 2 [label="annotation"] + 1 [shape=doublecircle, style=filled, color=blue] + 2 [shape=doublecircle, style=filled, color=green] +} diff --git a/src/xmlpatterns/schema/doc/Choice_diagram.dot b/src/xmlpatterns/schema/doc/Choice_diagram.dot new file mode 100644 index 0000000..7b32016 --- /dev/null +++ b/src/xmlpatterns/schema/doc/Choice_diagram.dot @@ -0,0 +1,22 @@ +digraph Choice { + mindist = 2.0 + 1 -> 3 [label="choice"] + 1 -> 3 [label="group"] + 1 -> 2 [label="annotation"] + 1 -> 3 [label="sequence"] + 1 -> 3 [label="any"] + 1 -> 3 [label="element"] + 2 -> 3 [label="choice"] + 2 -> 3 [label="group"] + 2 -> 3 [label="sequence"] + 2 -> 3 [label="any"] + 2 -> 3 [label="element"] + 3 -> 3 [label="choice"] + 3 -> 3 [label="group"] + 3 -> 3 [label="sequence"] + 3 -> 3 [label="any"] + 3 -> 3 [label="element"] + 1 [shape=doublecircle, style=filled, color=blue] + 2 [shape=doublecircle, style=filled, color=green] + 3 [shape=doublecircle, style=filled, color=green] +} diff --git a/src/xmlpatterns/schema/doc/ComplexContentExtension_diagram.dot b/src/xmlpatterns/schema/doc/ComplexContentExtension_diagram.dot new file mode 100644 index 0000000..6131612 --- /dev/null +++ b/src/xmlpatterns/schema/doc/ComplexContentExtension_diagram.dot @@ -0,0 +1,47 @@ +digraph ComplexContentExtension { + mindist = 2.0 + 1 -> 4 [label="choice"] + 1 -> 4 [label="group"] + 1 -> 4 [label="all"] + 1 -> 2 [label="annotation"] + 1 -> 4 [label="sequence"] + 1 -> 6 [label="anyAttribute"] + 1 -> 7 [label="assert"] + 1 -> 3 [label="openContent"] + 1 -> 5 [label="attribute"] + 1 -> 5 [label="attributeGroup"] + 2 -> 4 [label="choice"] + 2 -> 4 [label="group"] + 2 -> 4 [label="all"] + 2 -> 4 [label="sequence"] + 2 -> 6 [label="anyAttribute"] + 2 -> 7 [label="assert"] + 2 -> 3 [label="openContent"] + 2 -> 5 [label="attribute"] + 2 -> 5 [label="attributeGroup"] + 3 -> 4 [label="choice"] + 3 -> 4 [label="group"] + 3 -> 4 [label="all"] + 3 -> 4 [label="sequence"] + 3 -> 6 [label="anyAttribute"] + 3 -> 7 [label="assert"] + 3 -> 5 [label="attribute"] + 3 -> 5 [label="attributeGroup"] + 4 -> 6 [label="anyAttribute"] + 4 -> 7 [label="assert"] + 4 -> 5 [label="attribute"] + 4 -> 5 [label="attributeGroup"] + 5 -> 6 [label="anyAttribute"] + 5 -> 7 [label="assert"] + 5 -> 5 [label="attribute"] + 5 -> 5 [label="attributeGroup"] + 6 -> 7 [label="assert"] + 7 -> 7 [label="assert"] + 1 [shape=doublecircle, style=filled, color=blue] + 2 [shape=doublecircle, style=filled, color=green] + 3 [shape=doublecircle, style=filled, color=green] + 4 [shape=doublecircle, style=filled, color=green] + 5 [shape=doublecircle, style=filled, color=green] + 6 [shape=doublecircle, style=filled, color=green] + 7 [shape=doublecircle, style=filled, color=green] +} diff --git a/src/xmlpatterns/schema/doc/ComplexContentRestriction_diagram.dot b/src/xmlpatterns/schema/doc/ComplexContentRestriction_diagram.dot new file mode 100644 index 0000000..bfda892 --- /dev/null +++ b/src/xmlpatterns/schema/doc/ComplexContentRestriction_diagram.dot @@ -0,0 +1,47 @@ +digraph ComplexContentRestriction { + mindist = 2.0 + 1 -> 4 [label="choice"] + 1 -> 4 [label="group"] + 1 -> 4 [label="all"] + 1 -> 2 [label="annotation"] + 1 -> 4 [label="sequence"] + 1 -> 6 [label="anyAttribute"] + 1 -> 7 [label="assert"] + 1 -> 3 [label="openContent"] + 1 -> 5 [label="attribute"] + 1 -> 5 [label="attributeGroup"] + 2 -> 4 [label="choice"] + 2 -> 4 [label="group"] + 2 -> 4 [label="all"] + 2 -> 4 [label="sequence"] + 2 -> 6 [label="anyAttribute"] + 2 -> 7 [label="assert"] + 2 -> 3 [label="openContent"] + 2 -> 5 [label="attribute"] + 2 -> 5 [label="attributeGroup"] + 3 -> 4 [label="choice"] + 3 -> 4 [label="group"] + 3 -> 4 [label="all"] + 3 -> 4 [label="sequence"] + 3 -> 6 [label="anyAttribute"] + 3 -> 7 [label="assert"] + 3 -> 5 [label="attribute"] + 3 -> 5 [label="attributeGroup"] + 4 -> 6 [label="anyAttribute"] + 4 -> 7 [label="assert"] + 4 -> 5 [label="attribute"] + 4 -> 5 [label="attributeGroup"] + 5 -> 6 [label="anyAttribute"] + 5 -> 7 [label="assert"] + 5 -> 5 [label="attribute"] + 5 -> 5 [label="attributeGroup"] + 6 -> 7 [label="assert"] + 7 -> 7 [label="assert"] + 1 [shape=doublecircle, style=filled, color=blue] + 2 [shape=doublecircle, style=filled, color=green] + 3 [shape=doublecircle, style=filled, color=green] + 4 [shape=doublecircle, style=filled, color=green] + 5 [shape=doublecircle, style=filled, color=green] + 6 [shape=doublecircle, style=filled, color=green] + 7 [shape=doublecircle, style=filled, color=green] +} diff --git a/src/xmlpatterns/schema/doc/ComplexContent_diagram.dot b/src/xmlpatterns/schema/doc/ComplexContent_diagram.dot new file mode 100644 index 0000000..949c27e --- /dev/null +++ b/src/xmlpatterns/schema/doc/ComplexContent_diagram.dot @@ -0,0 +1,11 @@ +digraph ComplexContent { + mindist = 2.0 + 1 -> 3 [label="restriction"] + 1 -> 2 [label="annotation"] + 1 -> 3 [label="extension"] + 2 -> 3 [label="restriction"] + 2 -> 3 [label="extension"] + 1 [shape=circle, style=filled, color=blue] + 2 [shape=circle, style=filled, color=red] + 3 [shape=doublecircle, style=filled, color=green] +} diff --git a/src/xmlpatterns/schema/doc/DefaultOpenContent_diagram.dot b/src/xmlpatterns/schema/doc/DefaultOpenContent_diagram.dot new file mode 100644 index 0000000..61e7d14 --- /dev/null +++ b/src/xmlpatterns/schema/doc/DefaultOpenContent_diagram.dot @@ -0,0 +1,9 @@ +digraph DefaultOpenContent { + mindist = 2.0 + 1 -> 2 [label="annotation"] + 1 -> 3 [label="any"] + 2 -> 3 [label="any"] + 1 [shape=doublecircle, style=filled, color=blue] + 2 [shape=circle, style=filled, color=red] + 3 [shape=doublecircle, style=filled, color=green] +} diff --git a/src/xmlpatterns/schema/doc/EnumerationFacet_diagram.dot b/src/xmlpatterns/schema/doc/EnumerationFacet_diagram.dot new file mode 100644 index 0000000..91be76b --- /dev/null +++ b/src/xmlpatterns/schema/doc/EnumerationFacet_diagram.dot @@ -0,0 +1,6 @@ +digraph EnumerationFacet { + mindist = 2.0 + 1 -> 2 [label="annotation"] + 1 [shape=doublecircle, style=filled, color=blue] + 2 [shape=doublecircle, style=filled, color=green] +} diff --git a/src/xmlpatterns/schema/doc/Field_diagram.dot b/src/xmlpatterns/schema/doc/Field_diagram.dot new file mode 100644 index 0000000..1c597b3 --- /dev/null +++ b/src/xmlpatterns/schema/doc/Field_diagram.dot @@ -0,0 +1,6 @@ +digraph Field { + mindist = 2.0 + 1 -> 2 [label="annotation"] + 1 [shape=doublecircle, style=filled, color=blue] + 2 [shape=doublecircle, style=filled, color=green] +} diff --git a/src/xmlpatterns/schema/doc/FractionDigitsFacet_diagram.dot b/src/xmlpatterns/schema/doc/FractionDigitsFacet_diagram.dot new file mode 100644 index 0000000..5e098b3 --- /dev/null +++ b/src/xmlpatterns/schema/doc/FractionDigitsFacet_diagram.dot @@ -0,0 +1,6 @@ +digraph FractionDigitsFacet { + mindist = 2.0 + 1 -> 2 [label="annotation"] + 1 [shape=doublecircle, style=filled, color=blue] + 2 [shape=doublecircle, style=filled, color=green] +} diff --git a/src/xmlpatterns/schema/doc/GlobalAttribute_diagram.dot b/src/xmlpatterns/schema/doc/GlobalAttribute_diagram.dot new file mode 100644 index 0000000..25a1a43 --- /dev/null +++ b/src/xmlpatterns/schema/doc/GlobalAttribute_diagram.dot @@ -0,0 +1,9 @@ +digraph GlobalAttribute { + mindist = 2.0 + 1 -> 2 [label="annotation"] + 1 -> 3 [label="simpleType"] + 2 -> 3 [label="simpleType"] + 1 [shape=doublecircle, style=filled, color=blue] + 2 [shape=doublecircle, style=filled, color=green] + 3 [shape=doublecircle, style=filled, color=green] +} diff --git a/src/xmlpatterns/schema/doc/GlobalComplexType_diagram.dot b/src/xmlpatterns/schema/doc/GlobalComplexType_diagram.dot new file mode 100644 index 0000000..05e40b7 --- /dev/null +++ b/src/xmlpatterns/schema/doc/GlobalComplexType_diagram.dot @@ -0,0 +1,52 @@ +digraph GlobalComplexType { + mindist = 2.0 + 1 -> 5 [label="choice"] + 1 -> 3 [label="complexContent"] + 1 -> 5 [label="group"] + 1 -> 5 [label="all"] + 1 -> 2 [label="annotation"] + 1 -> 5 [label="sequence"] + 1 -> 3 [label="simpleContent"] + 1 -> 7 [label="anyAttribute"] + 1 -> 8 [label="assert"] + 1 -> 4 [label="openContent"] + 1 -> 6 [label="attribute"] + 1 -> 6 [label="attributeGroup"] + 2 -> 5 [label="choice"] + 2 -> 3 [label="complexContent"] + 2 -> 5 [label="group"] + 2 -> 5 [label="all"] + 2 -> 5 [label="sequence"] + 2 -> 3 [label="simpleContent"] + 2 -> 7 [label="anyAttribute"] + 2 -> 8 [label="assert"] + 2 -> 4 [label="openContent"] + 2 -> 6 [label="attribute"] + 2 -> 6 [label="attributeGroup"] + 4 -> 5 [label="choice"] + 4 -> 5 [label="group"] + 4 -> 5 [label="all"] + 4 -> 5 [label="sequence"] + 4 -> 7 [label="anyAttribute"] + 4 -> 8 [label="assert"] + 4 -> 6 [label="attribute"] + 4 -> 6 [label="attributeGroup"] + 5 -> 7 [label="anyAttribute"] + 5 -> 8 [label="assert"] + 5 -> 6 [label="attribute"] + 5 -> 6 [label="attributeGroup"] + 6 -> 7 [label="anyAttribute"] + 6 -> 8 [label="assert"] + 6 -> 6 [label="attribute"] + 6 -> 6 [label="attributeGroup"] + 7 -> 8 [label="assert"] + 8 -> 8 [label="assert"] + 1 [shape=doublecircle, style=filled, color=blue] + 2 [shape=doublecircle, style=filled, color=green] + 3 [shape=doublecircle, style=filled, color=green] + 4 [shape=doublecircle, style=filled, color=green] + 5 [shape=doublecircle, style=filled, color=green] + 6 [shape=doublecircle, style=filled, color=green] + 7 [shape=doublecircle, style=filled, color=green] + 8 [shape=doublecircle, style=filled, color=green] +} diff --git a/src/xmlpatterns/schema/doc/GlobalElement_diagram.dot b/src/xmlpatterns/schema/doc/GlobalElement_diagram.dot new file mode 100644 index 0000000..20447a7 --- /dev/null +++ b/src/xmlpatterns/schema/doc/GlobalElement_diagram.dot @@ -0,0 +1,32 @@ +digraph GlobalElement { + mindist = 2.0 + 1 -> 3 [label="complexType"] + 1 -> 4 [label="alternative"] + 1 -> 2 [label="annotation"] + 1 -> 5 [label="key"] + 1 -> 3 [label="simpleType"] + 1 -> 5 [label="keyref"] + 1 -> 5 [label="unique"] + 2 -> 3 [label="complexType"] + 2 -> 4 [label="alternative"] + 2 -> 5 [label="key"] + 2 -> 3 [label="simpleType"] + 2 -> 5 [label="keyref"] + 2 -> 5 [label="unique"] + 3 -> 4 [label="alternative"] + 3 -> 5 [label="key"] + 3 -> 5 [label="keyref"] + 3 -> 5 [label="unique"] + 4 -> 4 [label="alternative"] + 4 -> 5 [label="key"] + 4 -> 5 [label="keyref"] + 4 -> 5 [label="unique"] + 5 -> 5 [label="key"] + 5 -> 5 [label="keyref"] + 5 -> 5 [label="unique"] + 1 [shape=doublecircle, style=filled, color=blue] + 2 [shape=doublecircle, style=filled, color=green] + 3 [shape=doublecircle, style=filled, color=green] + 4 [shape=doublecircle, style=filled, color=green] + 5 [shape=doublecircle, style=filled, color=green] +} diff --git a/src/xmlpatterns/schema/doc/GlobalSimpleType_diagram.dot b/src/xmlpatterns/schema/doc/GlobalSimpleType_diagram.dot new file mode 100644 index 0000000..ccb7f54 --- /dev/null +++ b/src/xmlpatterns/schema/doc/GlobalSimpleType_diagram.dot @@ -0,0 +1,13 @@ +digraph GlobalSimpleType { + mindist = 2.0 + 1 -> 3 [label="restriction"] + 1 -> 2 [label="annotation"] + 1 -> 3 [label="list"] + 1 -> 3 [label="union"] + 2 -> 3 [label="restriction"] + 2 -> 3 [label="list"] + 2 -> 3 [label="union"] + 1 [shape=circle, style=filled, color=blue] + 2 [shape=circle, style=filled, color=red] + 3 [shape=doublecircle, style=filled, color=green] +} diff --git a/src/xmlpatterns/schema/doc/Import_diagram.dot b/src/xmlpatterns/schema/doc/Import_diagram.dot new file mode 100644 index 0000000..3484bc3 --- /dev/null +++ b/src/xmlpatterns/schema/doc/Import_diagram.dot @@ -0,0 +1,6 @@ +digraph Import { + mindist = 2.0 + 1 -> 2 [label="annotation"] + 1 [shape=doublecircle, style=filled, color=blue] + 2 [shape=doublecircle, style=filled, color=green] +} diff --git a/src/xmlpatterns/schema/doc/Include_diagram.dot b/src/xmlpatterns/schema/doc/Include_diagram.dot new file mode 100644 index 0000000..357e4c9 --- /dev/null +++ b/src/xmlpatterns/schema/doc/Include_diagram.dot @@ -0,0 +1,6 @@ +digraph Include { + mindist = 2.0 + 1 -> 2 [label="annotation"] + 1 [shape=doublecircle, style=filled, color=blue] + 2 [shape=doublecircle, style=filled, color=green] +} diff --git a/src/xmlpatterns/schema/doc/KeyRef_diagram.dot b/src/xmlpatterns/schema/doc/KeyRef_diagram.dot new file mode 100644 index 0000000..ff425b9 --- /dev/null +++ b/src/xmlpatterns/schema/doc/KeyRef_diagram.dot @@ -0,0 +1,12 @@ +digraph KeyRef { + mindist = 2.0 + 1 -> 2 [label="annotation"] + 1 -> 3 [label="selector"] + 2 -> 3 [label="selector"] + 3 -> 4 [label="field"] + 4 -> 4 [label="field"] + 1 [shape=circle, style=filled, color=blue] + 2 [shape=circle, style=filled, color=red] + 3 [shape=circle, style=filled, color=red] + 4 [shape=doublecircle, style=filled, color=green] +} diff --git a/src/xmlpatterns/schema/doc/Key_diagram.dot b/src/xmlpatterns/schema/doc/Key_diagram.dot new file mode 100644 index 0000000..bbc09cd --- /dev/null +++ b/src/xmlpatterns/schema/doc/Key_diagram.dot @@ -0,0 +1,12 @@ +digraph Key { + mindist = 2.0 + 1 -> 2 [label="annotation"] + 1 -> 3 [label="selector"] + 2 -> 3 [label="selector"] + 3 -> 4 [label="field"] + 4 -> 4 [label="field"] + 1 [shape=circle, style=filled, color=blue] + 2 [shape=circle, style=filled, color=red] + 3 [shape=circle, style=filled, color=red] + 4 [shape=doublecircle, style=filled, color=green] +} diff --git a/src/xmlpatterns/schema/doc/LengthFacet_diagram.dot b/src/xmlpatterns/schema/doc/LengthFacet_diagram.dot new file mode 100644 index 0000000..1f9205b --- /dev/null +++ b/src/xmlpatterns/schema/doc/LengthFacet_diagram.dot @@ -0,0 +1,6 @@ +digraph LengthFacet { + mindist = 2.0 + 1 -> 2 [label="annotation"] + 1 [shape=doublecircle, style=filled, color=blue] + 2 [shape=doublecircle, style=filled, color=green] +} diff --git a/src/xmlpatterns/schema/doc/List_diagram.dot b/src/xmlpatterns/schema/doc/List_diagram.dot new file mode 100644 index 0000000..44cc698 --- /dev/null +++ b/src/xmlpatterns/schema/doc/List_diagram.dot @@ -0,0 +1,9 @@ +digraph List { + mindist = 2.0 + 1 -> 2 [label="annotation"] + 1 -> 3 [label="simpleType"] + 2 -> 3 [label="simpleType"] + 1 [shape=doublecircle, style=filled, color=blue] + 2 [shape=doublecircle, style=filled, color=green] + 3 [shape=doublecircle, style=filled, color=green] +} diff --git a/src/xmlpatterns/schema/doc/LocalAll_diagram.dot b/src/xmlpatterns/schema/doc/LocalAll_diagram.dot new file mode 100644 index 0000000..88f1b61 --- /dev/null +++ b/src/xmlpatterns/schema/doc/LocalAll_diagram.dot @@ -0,0 +1,13 @@ +digraph LocalAll { + mindist = 2.0 + 1 -> 2 [label="annotation"] + 1 -> 3 [label="any"] + 1 -> 3 [label="element"] + 2 -> 3 [label="any"] + 2 -> 3 [label="element"] + 3 -> 3 [label="any"] + 3 -> 3 [label="element"] + 1 [shape=doublecircle, style=filled, color=blue] + 2 [shape=doublecircle, style=filled, color=green] + 3 [shape=doublecircle, style=filled, color=green] +} diff --git a/src/xmlpatterns/schema/doc/LocalAttribute_diagram.dot b/src/xmlpatterns/schema/doc/LocalAttribute_diagram.dot new file mode 100644 index 0000000..b01f0cf --- /dev/null +++ b/src/xmlpatterns/schema/doc/LocalAttribute_diagram.dot @@ -0,0 +1,9 @@ +digraph LocalAttribute { + mindist = 2.0 + 1 -> 2 [label="annotation"] + 1 -> 3 [label="simpleType"] + 2 -> 3 [label="simpleType"] + 1 [shape=doublecircle, style=filled, color=blue] + 2 [shape=doublecircle, style=filled, color=green] + 3 [shape=doublecircle, style=filled, color=green] +} diff --git a/src/xmlpatterns/schema/doc/LocalChoice_diagram.dot b/src/xmlpatterns/schema/doc/LocalChoice_diagram.dot new file mode 100644 index 0000000..b16c47f --- /dev/null +++ b/src/xmlpatterns/schema/doc/LocalChoice_diagram.dot @@ -0,0 +1,22 @@ +digraph LocalChoice { + mindist = 2.0 + 1 -> 3 [label="choice"] + 1 -> 3 [label="group"] + 1 -> 2 [label="annotation"] + 1 -> 3 [label="sequence"] + 1 -> 3 [label="any"] + 1 -> 3 [label="element"] + 2 -> 3 [label="choice"] + 2 -> 3 [label="group"] + 2 -> 3 [label="sequence"] + 2 -> 3 [label="any"] + 2 -> 3 [label="element"] + 3 -> 3 [label="choice"] + 3 -> 3 [label="group"] + 3 -> 3 [label="sequence"] + 3 -> 3 [label="any"] + 3 -> 3 [label="element"] + 1 [shape=doublecircle, style=filled, color=blue] + 2 [shape=doublecircle, style=filled, color=green] + 3 [shape=doublecircle, style=filled, color=green] +} diff --git a/src/xmlpatterns/schema/doc/LocalComplexType_diagram.dot b/src/xmlpatterns/schema/doc/LocalComplexType_diagram.dot new file mode 100644 index 0000000..92c54b7 --- /dev/null +++ b/src/xmlpatterns/schema/doc/LocalComplexType_diagram.dot @@ -0,0 +1,52 @@ +digraph LocalComplexType { + mindist = 2.0 + 1 -> 5 [label="choice"] + 1 -> 3 [label="complexContent"] + 1 -> 5 [label="group"] + 1 -> 5 [label="all"] + 1 -> 2 [label="annotation"] + 1 -> 5 [label="sequence"] + 1 -> 3 [label="simpleContent"] + 1 -> 7 [label="anyAttribute"] + 1 -> 8 [label="assert"] + 1 -> 4 [label="openContent"] + 1 -> 6 [label="attribute"] + 1 -> 6 [label="attributeGroup"] + 2 -> 5 [label="choice"] + 2 -> 3 [label="complexContent"] + 2 -> 5 [label="group"] + 2 -> 5 [label="all"] + 2 -> 5 [label="sequence"] + 2 -> 3 [label="simpleContent"] + 2 -> 7 [label="anyAttribute"] + 2 -> 8 [label="assert"] + 2 -> 4 [label="openContent"] + 2 -> 6 [label="attribute"] + 2 -> 6 [label="attributeGroup"] + 4 -> 5 [label="choice"] + 4 -> 5 [label="group"] + 4 -> 5 [label="all"] + 4 -> 5 [label="sequence"] + 4 -> 7 [label="anyAttribute"] + 4 -> 8 [label="assert"] + 4 -> 6 [label="attribute"] + 4 -> 6 [label="attributeGroup"] + 5 -> 7 [label="anyAttribute"] + 5 -> 8 [label="assert"] + 5 -> 6 [label="attribute"] + 5 -> 6 [label="attributeGroup"] + 6 -> 7 [label="anyAttribute"] + 6 -> 8 [label="assert"] + 6 -> 6 [label="attribute"] + 6 -> 6 [label="attributeGroup"] + 7 -> 8 [label="assert"] + 8 -> 8 [label="assert"] + 1 [shape=doublecircle, style=filled, color=blue] + 2 [shape=doublecircle, style=filled, color=green] + 3 [shape=doublecircle, style=filled, color=green] + 4 [shape=doublecircle, style=filled, color=green] + 5 [shape=doublecircle, style=filled, color=green] + 6 [shape=doublecircle, style=filled, color=green] + 7 [shape=doublecircle, style=filled, color=green] + 8 [shape=doublecircle, style=filled, color=green] +} diff --git a/src/xmlpatterns/schema/doc/LocalElement_diagram.dot b/src/xmlpatterns/schema/doc/LocalElement_diagram.dot new file mode 100644 index 0000000..397397a --- /dev/null +++ b/src/xmlpatterns/schema/doc/LocalElement_diagram.dot @@ -0,0 +1,32 @@ +digraph LocalElement { + mindist = 2.0 + 1 -> 3 [label="complexType"] + 1 -> 4 [label="alternative"] + 1 -> 2 [label="annotation"] + 1 -> 5 [label="key"] + 1 -> 3 [label="simpleType"] + 1 -> 5 [label="keyref"] + 1 -> 5 [label="unique"] + 2 -> 3 [label="complexType"] + 2 -> 4 [label="alternative"] + 2 -> 5 [label="key"] + 2 -> 3 [label="simpleType"] + 2 -> 5 [label="keyref"] + 2 -> 5 [label="unique"] + 3 -> 4 [label="alternative"] + 3 -> 5 [label="key"] + 3 -> 5 [label="keyref"] + 3 -> 5 [label="unique"] + 4 -> 4 [label="alternative"] + 4 -> 5 [label="key"] + 4 -> 5 [label="keyref"] + 4 -> 5 [label="unique"] + 5 -> 5 [label="key"] + 5 -> 5 [label="keyref"] + 5 -> 5 [label="unique"] + 1 [shape=doublecircle, style=filled, color=blue] + 2 [shape=doublecircle, style=filled, color=green] + 3 [shape=doublecircle, style=filled, color=green] + 4 [shape=doublecircle, style=filled, color=green] + 5 [shape=doublecircle, style=filled, color=green] +} diff --git a/src/xmlpatterns/schema/doc/LocalSequence_diagram.dot b/src/xmlpatterns/schema/doc/LocalSequence_diagram.dot new file mode 100644 index 0000000..0dc7f39 --- /dev/null +++ b/src/xmlpatterns/schema/doc/LocalSequence_diagram.dot @@ -0,0 +1,22 @@ +digraph LocalSequence { + mindist = 2.0 + 1 -> 3 [label="choice"] + 1 -> 3 [label="group"] + 1 -> 2 [label="annotation"] + 1 -> 3 [label="sequence"] + 1 -> 3 [label="any"] + 1 -> 3 [label="element"] + 2 -> 3 [label="choice"] + 2 -> 3 [label="group"] + 2 -> 3 [label="sequence"] + 2 -> 3 [label="any"] + 2 -> 3 [label="element"] + 3 -> 3 [label="choice"] + 3 -> 3 [label="group"] + 3 -> 3 [label="sequence"] + 3 -> 3 [label="any"] + 3 -> 3 [label="element"] + 1 [shape=doublecircle, style=filled, color=blue] + 2 [shape=doublecircle, style=filled, color=green] + 3 [shape=doublecircle, style=filled, color=green] +} diff --git a/src/xmlpatterns/schema/doc/LocalSimpleType_diagram.dot b/src/xmlpatterns/schema/doc/LocalSimpleType_diagram.dot new file mode 100644 index 0000000..ac13305 --- /dev/null +++ b/src/xmlpatterns/schema/doc/LocalSimpleType_diagram.dot @@ -0,0 +1,13 @@ +digraph LocalSimpleType { + mindist = 2.0 + 1 -> 3 [label="restriction"] + 1 -> 2 [label="annotation"] + 1 -> 3 [label="list"] + 1 -> 3 [label="union"] + 2 -> 3 [label="restriction"] + 2 -> 3 [label="list"] + 2 -> 3 [label="union"] + 1 [shape=circle, style=filled, color=blue] + 2 [shape=circle, style=filled, color=red] + 3 [shape=doublecircle, style=filled, color=green] +} diff --git a/src/xmlpatterns/schema/doc/MaxExclusiveFacet_diagram.dot b/src/xmlpatterns/schema/doc/MaxExclusiveFacet_diagram.dot new file mode 100644 index 0000000..28364f7 --- /dev/null +++ b/src/xmlpatterns/schema/doc/MaxExclusiveFacet_diagram.dot @@ -0,0 +1,6 @@ +digraph MaxExclusiveFacet { + mindist = 2.0 + 1 -> 2 [label="annotation"] + 1 [shape=doublecircle, style=filled, color=blue] + 2 [shape=doublecircle, style=filled, color=green] +} diff --git a/src/xmlpatterns/schema/doc/MaxInclusiveFacet_diagram.dot b/src/xmlpatterns/schema/doc/MaxInclusiveFacet_diagram.dot new file mode 100644 index 0000000..9e2c265 --- /dev/null +++ b/src/xmlpatterns/schema/doc/MaxInclusiveFacet_diagram.dot @@ -0,0 +1,6 @@ +digraph MaxInclusiveFacet { + mindist = 2.0 + 1 -> 2 [label="annotation"] + 1 [shape=doublecircle, style=filled, color=blue] + 2 [shape=doublecircle, style=filled, color=green] +} diff --git a/src/xmlpatterns/schema/doc/MaxLengthFacet_diagram.dot b/src/xmlpatterns/schema/doc/MaxLengthFacet_diagram.dot new file mode 100644 index 0000000..d565217 --- /dev/null +++ b/src/xmlpatterns/schema/doc/MaxLengthFacet_diagram.dot @@ -0,0 +1,6 @@ +digraph MaxLengthFacet { + mindist = 2.0 + 1 -> 2 [label="annotation"] + 1 [shape=doublecircle, style=filled, color=blue] + 2 [shape=doublecircle, style=filled, color=green] +} diff --git a/src/xmlpatterns/schema/doc/MinExclusiveFacet_diagram.dot b/src/xmlpatterns/schema/doc/MinExclusiveFacet_diagram.dot new file mode 100644 index 0000000..d3b3f1f --- /dev/null +++ b/src/xmlpatterns/schema/doc/MinExclusiveFacet_diagram.dot @@ -0,0 +1,6 @@ +digraph MinExclusiveFacet { + mindist = 2.0 + 1 -> 2 [label="annotation"] + 1 [shape=doublecircle, style=filled, color=blue] + 2 [shape=doublecircle, style=filled, color=green] +} diff --git a/src/xmlpatterns/schema/doc/MinInclusiveFacet_diagram.dot b/src/xmlpatterns/schema/doc/MinInclusiveFacet_diagram.dot new file mode 100644 index 0000000..e5ca65d --- /dev/null +++ b/src/xmlpatterns/schema/doc/MinInclusiveFacet_diagram.dot @@ -0,0 +1,6 @@ +digraph MinInclusiveFacet { + mindist = 2.0 + 1 -> 2 [label="annotation"] + 1 [shape=doublecircle, style=filled, color=blue] + 2 [shape=doublecircle, style=filled, color=green] +} diff --git a/src/xmlpatterns/schema/doc/MinLengthFacet_diagram.dot b/src/xmlpatterns/schema/doc/MinLengthFacet_diagram.dot new file mode 100644 index 0000000..1dcced4 --- /dev/null +++ b/src/xmlpatterns/schema/doc/MinLengthFacet_diagram.dot @@ -0,0 +1,6 @@ +digraph MinLengthFacet { + mindist = 2.0 + 1 -> 2 [label="annotation"] + 1 [shape=doublecircle, style=filled, color=blue] + 2 [shape=doublecircle, style=filled, color=green] +} diff --git a/src/xmlpatterns/schema/doc/NamedAttributeGroup_diagram.dot b/src/xmlpatterns/schema/doc/NamedAttributeGroup_diagram.dot new file mode 100644 index 0000000..1754f67 --- /dev/null +++ b/src/xmlpatterns/schema/doc/NamedAttributeGroup_diagram.dot @@ -0,0 +1,17 @@ +digraph NamedAttributeGroup { + mindist = 2.0 + 1 -> 2 [label="annotation"] + 1 -> 4 [label="anyAttribute"] + 1 -> 3 [label="attribute"] + 1 -> 3 [label="attributeGroup"] + 2 -> 4 [label="anyAttribute"] + 2 -> 3 [label="attribute"] + 2 -> 3 [label="attributeGroup"] + 3 -> 4 [label="anyAttribute"] + 3 -> 3 [label="attribute"] + 3 -> 3 [label="attributeGroup"] + 1 [shape=doublecircle, style=filled, color=blue] + 2 [shape=doublecircle, style=filled, color=green] + 3 [shape=doublecircle, style=filled, color=green] + 4 [shape=doublecircle, style=filled, color=green] +} diff --git a/src/xmlpatterns/schema/doc/NamedGroup_diagram.dot b/src/xmlpatterns/schema/doc/NamedGroup_diagram.dot new file mode 100644 index 0000000..6d9a289 --- /dev/null +++ b/src/xmlpatterns/schema/doc/NamedGroup_diagram.dot @@ -0,0 +1,13 @@ +digraph NamedGroup { + mindist = 2.0 + 1 -> 3 [label="choice"] + 1 -> 3 [label="all"] + 1 -> 2 [label="annotation"] + 1 -> 3 [label="sequence"] + 2 -> 3 [label="choice"] + 2 -> 3 [label="all"] + 2 -> 3 [label="sequence"] + 1 [shape=doublecircle, style=filled, color=blue] + 2 [shape=doublecircle, style=filled, color=green] + 3 [shape=doublecircle, style=filled, color=green] +} diff --git a/src/xmlpatterns/schema/doc/Notation_diagram.dot b/src/xmlpatterns/schema/doc/Notation_diagram.dot new file mode 100644 index 0000000..951f26a --- /dev/null +++ b/src/xmlpatterns/schema/doc/Notation_diagram.dot @@ -0,0 +1,6 @@ +digraph Notation { + mindist = 2.0 + 1 -> 2 [label="annotation"] + 1 [shape=doublecircle, style=filled, color=blue] + 2 [shape=doublecircle, style=filled, color=green] +} diff --git a/src/xmlpatterns/schema/doc/Override_diagram.dot b/src/xmlpatterns/schema/doc/Override_diagram.dot new file mode 100644 index 0000000..448451a --- /dev/null +++ b/src/xmlpatterns/schema/doc/Override_diagram.dot @@ -0,0 +1,21 @@ +digraph Override { + mindist = 2.0 + 1 -> 2 [label="group"] + 1 -> 2 [label="complexType"] + 1 -> 2 [label="annotation"] + 1 -> 2 [label="simpleType"] + 1 -> 2 [label="element"] + 1 -> 2 [label="notation"] + 1 -> 2 [label="attribute"] + 1 -> 2 [label="attributeGroup"] + 2 -> 2 [label="group"] + 2 -> 2 [label="complexType"] + 2 -> 2 [label="annotation"] + 2 -> 2 [label="simpleType"] + 2 -> 2 [label="element"] + 2 -> 2 [label="notation"] + 2 -> 2 [label="attribute"] + 2 -> 2 [label="attributeGroup"] + 1 [shape=doublecircle, style=filled, color=blue] + 2 [shape=doublecircle, style=filled, color=green] +} diff --git a/src/xmlpatterns/schema/doc/PatternFacet_diagram.dot b/src/xmlpatterns/schema/doc/PatternFacet_diagram.dot new file mode 100644 index 0000000..794d74c --- /dev/null +++ b/src/xmlpatterns/schema/doc/PatternFacet_diagram.dot @@ -0,0 +1,6 @@ +digraph PatternFacet { + mindist = 2.0 + 1 -> 2 [label="annotation"] + 1 [shape=doublecircle, style=filled, color=blue] + 2 [shape=doublecircle, style=filled, color=green] +} diff --git a/src/xmlpatterns/schema/doc/Redefine_diagram.dot b/src/xmlpatterns/schema/doc/Redefine_diagram.dot new file mode 100644 index 0000000..ba4871d --- /dev/null +++ b/src/xmlpatterns/schema/doc/Redefine_diagram.dot @@ -0,0 +1,15 @@ +digraph Redefine { + mindist = 2.0 + 1 -> 2 [label="group"] + 1 -> 2 [label="complexType"] + 1 -> 2 [label="annotation"] + 1 -> 2 [label="simpleType"] + 1 -> 2 [label="attributeGroup"] + 2 -> 2 [label="group"] + 2 -> 2 [label="complexType"] + 2 -> 2 [label="annotation"] + 2 -> 2 [label="simpleType"] + 2 -> 2 [label="attributeGroup"] + 1 [shape=doublecircle, style=filled, color=blue] + 2 [shape=doublecircle, style=filled, color=green] +} diff --git a/src/xmlpatterns/schema/doc/ReferredAttributeGroup_diagram.dot b/src/xmlpatterns/schema/doc/ReferredAttributeGroup_diagram.dot new file mode 100644 index 0000000..fd08872 --- /dev/null +++ b/src/xmlpatterns/schema/doc/ReferredAttributeGroup_diagram.dot @@ -0,0 +1,6 @@ +digraph ReferredAttributeGroup { + mindist = 2.0 + 1 -> 2 [label="annotation"] + 1 [shape=doublecircle, style=filled, color=blue] + 2 [shape=doublecircle, style=filled, color=green] +} diff --git a/src/xmlpatterns/schema/doc/ReferredGroup_diagram.dot b/src/xmlpatterns/schema/doc/ReferredGroup_diagram.dot new file mode 100644 index 0000000..c32f69f --- /dev/null +++ b/src/xmlpatterns/schema/doc/ReferredGroup_diagram.dot @@ -0,0 +1,13 @@ +digraph ReferredGroup { + mindist = 2.0 + 1 -> 3 [label="choice"] + 1 -> 3 [label="all"] + 1 -> 2 [label="annotation"] + 1 -> 3 [label="sequence"] + 2 -> 3 [label="choice"] + 2 -> 3 [label="all"] + 2 -> 3 [label="sequence"] + 1 [shape=doublecircle, style=filled, color=blue] + 2 [shape=doublecircle, style=filled, color=green] + 3 [shape=doublecircle, style=filled, color=green] +} diff --git a/src/xmlpatterns/schema/doc/Schema_diagram.dot b/src/xmlpatterns/schema/doc/Schema_diagram.dot new file mode 100644 index 0000000..7d39337 --- /dev/null +++ b/src/xmlpatterns/schema/doc/Schema_diagram.dot @@ -0,0 +1,66 @@ +digraph Schema { + mindist = 2.0 + 1 -> 5 [label="group"] + 1 -> 5 [label="complexType"] + 1 -> 2 [label="import"] + 1 -> 2 [label="include"] + 1 -> 2 [label="annotation"] + 1 -> 3 [label="defaultOpenContent"] + 1 -> 5 [label="simpleType"] + 1 -> 5 [label="element"] + 1 -> 5 [label="notation"] + 1 -> 2 [label="override"] + 1 -> 5 [label="attribute"] + 1 -> 5 [label="attributeGroup"] + 1 -> 2 [label="redefine"] + 2 -> 5 [label="group"] + 2 -> 5 [label="complexType"] + 2 -> 2 [label="import"] + 2 -> 2 [label="include"] + 2 -> 2 [label="annotation"] + 2 -> 3 [label="defaultOpenContent"] + 2 -> 5 [label="simpleType"] + 2 -> 5 [label="element"] + 2 -> 5 [label="notation"] + 2 -> 2 [label="override"] + 2 -> 5 [label="attribute"] + 2 -> 5 [label="attributeGroup"] + 2 -> 2 [label="redefine"] + 3 -> 5 [label="group"] + 3 -> 5 [label="complexType"] + 3 -> 4 [label="annotation"] + 3 -> 5 [label="simpleType"] + 3 -> 5 [label="element"] + 3 -> 5 [label="notation"] + 3 -> 5 [label="attribute"] + 3 -> 5 [label="attributeGroup"] + 4 -> 5 [label="group"] + 4 -> 5 [label="complexType"] + 4 -> 5 [label="simpleType"] + 4 -> 5 [label="element"] + 4 -> 5 [label="notation"] + 4 -> 5 [label="attribute"] + 4 -> 5 [label="attributeGroup"] + 5 -> 5 [label="group"] + 5 -> 5 [label="complexType"] + 5 -> 6 [label="annotation"] + 5 -> 5 [label="simpleType"] + 5 -> 5 [label="element"] + 5 -> 5 [label="notation"] + 5 -> 5 [label="attribute"] + 5 -> 5 [label="attributeGroup"] + 6 -> 5 [label="group"] + 6 -> 5 [label="complexType"] + 6 -> 6 [label="annotation"] + 6 -> 5 [label="simpleType"] + 6 -> 5 [label="element"] + 6 -> 5 [label="notation"] + 6 -> 5 [label="attribute"] + 6 -> 5 [label="attributeGroup"] + 1 [shape=doublecircle, style=filled, color=blue] + 2 [shape=doublecircle, style=filled, color=green] + 3 [shape=doublecircle, style=filled, color=green] + 4 [shape=doublecircle, style=filled, color=green] + 5 [shape=doublecircle, style=filled, color=green] + 6 [shape=doublecircle, style=filled, color=green] +} diff --git a/src/xmlpatterns/schema/doc/Selector_diagram.dot b/src/xmlpatterns/schema/doc/Selector_diagram.dot new file mode 100644 index 0000000..f3e93dc --- /dev/null +++ b/src/xmlpatterns/schema/doc/Selector_diagram.dot @@ -0,0 +1,6 @@ +digraph Selector { + mindist = 2.0 + 1 -> 2 [label="annotation"] + 1 [shape=doublecircle, style=filled, color=blue] + 2 [shape=doublecircle, style=filled, color=green] +} diff --git a/src/xmlpatterns/schema/doc/Sequence_diagram.dot b/src/xmlpatterns/schema/doc/Sequence_diagram.dot new file mode 100644 index 0000000..9172744 --- /dev/null +++ b/src/xmlpatterns/schema/doc/Sequence_diagram.dot @@ -0,0 +1,22 @@ +digraph Sequence { + mindist = 2.0 + 1 -> 3 [label="choice"] + 1 -> 3 [label="group"] + 1 -> 2 [label="annotation"] + 1 -> 3 [label="sequence"] + 1 -> 3 [label="any"] + 1 -> 3 [label="element"] + 2 -> 3 [label="choice"] + 2 -> 3 [label="group"] + 2 -> 3 [label="sequence"] + 2 -> 3 [label="any"] + 2 -> 3 [label="element"] + 3 -> 3 [label="choice"] + 3 -> 3 [label="group"] + 3 -> 3 [label="sequence"] + 3 -> 3 [label="any"] + 3 -> 3 [label="element"] + 1 [shape=doublecircle, style=filled, color=blue] + 2 [shape=doublecircle, style=filled, color=green] + 3 [shape=doublecircle, style=filled, color=green] +} diff --git a/src/xmlpatterns/schema/doc/SimpleContentExtension_diagram.dot b/src/xmlpatterns/schema/doc/SimpleContentExtension_diagram.dot new file mode 100644 index 0000000..3ceebfd --- /dev/null +++ b/src/xmlpatterns/schema/doc/SimpleContentExtension_diagram.dot @@ -0,0 +1,23 @@ +digraph SimpleContentExtension { + mindist = 2.0 + 1 -> 2 [label="annotation"] + 1 -> 4 [label="anyAttribute"] + 1 -> 5 [label="assert"] + 1 -> 3 [label="attribute"] + 1 -> 3 [label="attributeGroup"] + 2 -> 4 [label="anyAttribute"] + 2 -> 5 [label="assert"] + 2 -> 3 [label="attribute"] + 2 -> 3 [label="attributeGroup"] + 3 -> 4 [label="anyAttribute"] + 3 -> 5 [label="assert"] + 3 -> 3 [label="attribute"] + 3 -> 3 [label="attributeGroup"] + 4 -> 5 [label="assert"] + 5 -> 5 [label="assert"] + 1 [shape=doublecircle, style=filled, color=blue] + 2 [shape=doublecircle, style=filled, color=green] + 3 [shape=doublecircle, style=filled, color=green] + 4 [shape=doublecircle, style=filled, color=green] + 5 [shape=doublecircle, style=filled, color=green] +} diff --git a/src/xmlpatterns/schema/doc/SimpleContentRestriction_diagram.dot b/src/xmlpatterns/schema/doc/SimpleContentRestriction_diagram.dot new file mode 100644 index 0000000..75b0b71 --- /dev/null +++ b/src/xmlpatterns/schema/doc/SimpleContentRestriction_diagram.dot @@ -0,0 +1,87 @@ +digraph SimpleContentRestriction { + mindist = 2.0 + 1 -> 3 [label="simpleType"] + 1 -> 2 [label="annotation"] + 1 -> 4 [label="length"] + 1 -> 6 [label="anyAttribute"] + 1 -> 4 [label="maxExclusive"] + 1 -> 4 [label="totalDigits"] + 1 -> 4 [label="maxInclusive"] + 1 -> 4 [label="maxLength"] + 1 -> 7 [label="assert"] + 1 -> 4 [label="assertion"] + 1 -> 5 [label="attribute"] + 1 -> 4 [label="minExclusive"] + 1 -> 5 [label="attributeGroup"] + 1 -> 4 [label="minInclusive"] + 1 -> 4 [label="minLength"] + 1 -> 4 [label="whiteSpace"] + 1 -> 4 [label="pattern"] + 1 -> 4 [label="enumeration"] + 1 -> 4 [label="fractionDigits"] + 2 -> 3 [label="simpleType"] + 2 -> 4 [label="length"] + 2 -> 6 [label="anyAttribute"] + 2 -> 4 [label="maxExclusive"] + 2 -> 4 [label="totalDigits"] + 2 -> 4 [label="maxInclusive"] + 2 -> 4 [label="maxLength"] + 2 -> 7 [label="assert"] + 2 -> 4 [label="assertion"] + 2 -> 5 [label="attribute"] + 2 -> 4 [label="minExclusive"] + 2 -> 5 [label="attributeGroup"] + 2 -> 4 [label="minInclusive"] + 2 -> 4 [label="minLength"] + 2 -> 4 [label="whiteSpace"] + 2 -> 4 [label="pattern"] + 2 -> 4 [label="enumeration"] + 2 -> 4 [label="fractionDigits"] + 3 -> 4 [label="fractionDigits"] + 3 -> 4 [label="minLength"] + 3 -> 4 [label="whiteSpace"] + 3 -> 6 [label="anyAttribute"] + 3 -> 4 [label="length"] + 3 -> 7 [label="assert"] + 3 -> 4 [label="maxExclusive"] + 3 -> 4 [label="enumeration"] + 3 -> 4 [label="assertion"] + 3 -> 4 [label="maxInclusive"] + 3 -> 5 [label="attribute"] + 3 -> 4 [label="maxLength"] + 3 -> 4 [label="pattern"] + 3 -> 4 [label="totalDigits"] + 3 -> 5 [label="attributeGroup"] + 3 -> 4 [label="minExclusive"] + 3 -> 4 [label="minInclusive"] + 4 -> 4 [label="fractionDigits"] + 4 -> 4 [label="minLength"] + 4 -> 4 [label="whiteSpace"] + 4 -> 6 [label="anyAttribute"] + 4 -> 4 [label="length"] + 4 -> 7 [label="assert"] + 4 -> 4 [label="maxExclusive"] + 4 -> 4 [label="enumeration"] + 4 -> 4 [label="assertion"] + 4 -> 4 [label="maxInclusive"] + 4 -> 5 [label="attribute"] + 4 -> 4 [label="maxLength"] + 4 -> 4 [label="pattern"] + 4 -> 4 [label="totalDigits"] + 4 -> 5 [label="attributeGroup"] + 4 -> 4 [label="minExclusive"] + 4 -> 4 [label="minInclusive"] + 5 -> 6 [label="anyAttribute"] + 5 -> 7 [label="assert"] + 5 -> 5 [label="attribute"] + 5 -> 5 [label="attributeGroup"] + 6 -> 7 [label="assert"] + 7 -> 7 [label="assert"] + 1 [shape=doublecircle, style=filled, color=blue] + 2 [shape=doublecircle, style=filled, color=green] + 3 [shape=doublecircle, style=filled, color=green] + 4 [shape=doublecircle, style=filled, color=green] + 5 [shape=doublecircle, style=filled, color=green] + 6 [shape=doublecircle, style=filled, color=green] + 7 [shape=doublecircle, style=filled, color=green] +} diff --git a/src/xmlpatterns/schema/doc/SimpleContent_diagram.dot b/src/xmlpatterns/schema/doc/SimpleContent_diagram.dot new file mode 100644 index 0000000..c996329 --- /dev/null +++ b/src/xmlpatterns/schema/doc/SimpleContent_diagram.dot @@ -0,0 +1,11 @@ +digraph SimpleContent { + mindist = 2.0 + 1 -> 3 [label="restriction"] + 1 -> 2 [label="annotation"] + 1 -> 3 [label="extension"] + 2 -> 3 [label="restriction"] + 2 -> 3 [label="extension"] + 1 [shape=circle, style=filled, color=blue] + 2 [shape=circle, style=filled, color=red] + 3 [shape=doublecircle, style=filled, color=green] +} diff --git a/src/xmlpatterns/schema/doc/SimpleRestriction_diagram.dot b/src/xmlpatterns/schema/doc/SimpleRestriction_diagram.dot new file mode 100644 index 0000000..09cb041 --- /dev/null +++ b/src/xmlpatterns/schema/doc/SimpleRestriction_diagram.dot @@ -0,0 +1,62 @@ +digraph SimpleRestriction { + mindist = 2.0 + 1 -> 4 [label="fractionDigits"] + 1 -> 4 [label="minLength"] + 1 -> 4 [label="whiteSpace"] + 1 -> 2 [label="annotation"] + 1 -> 3 [label="simpleType"] + 1 -> 4 [label="length"] + 1 -> 4 [label="maxExclusive"] + 1 -> 4 [label="enumeration"] + 1 -> 4 [label="assertion"] + 1 -> 4 [label="maxInclusive"] + 1 -> 4 [label="maxLength"] + 1 -> 4 [label="pattern"] + 1 -> 4 [label="totalDigits"] + 1 -> 4 [label="minExclusive"] + 1 -> 4 [label="minInclusive"] + 2 -> 4 [label="fractionDigits"] + 2 -> 4 [label="minLength"] + 2 -> 4 [label="whiteSpace"] + 2 -> 3 [label="simpleType"] + 2 -> 4 [label="length"] + 2 -> 4 [label="maxExclusive"] + 2 -> 4 [label="enumeration"] + 2 -> 4 [label="assertion"] + 2 -> 4 [label="maxInclusive"] + 2 -> 4 [label="maxLength"] + 2 -> 4 [label="pattern"] + 2 -> 4 [label="totalDigits"] + 2 -> 4 [label="minExclusive"] + 2 -> 4 [label="minInclusive"] + 3 -> 4 [label="fractionDigits"] + 3 -> 4 [label="minLength"] + 3 -> 4 [label="whiteSpace"] + 3 -> 4 [label="length"] + 3 -> 4 [label="maxExclusive"] + 3 -> 4 [label="enumeration"] + 3 -> 4 [label="assertion"] + 3 -> 4 [label="maxInclusive"] + 3 -> 4 [label="maxLength"] + 3 -> 4 [label="pattern"] + 3 -> 4 [label="totalDigits"] + 3 -> 4 [label="minExclusive"] + 3 -> 4 [label="minInclusive"] + 4 -> 4 [label="fractionDigits"] + 4 -> 4 [label="minLength"] + 4 -> 4 [label="whiteSpace"] + 4 -> 4 [label="length"] + 4 -> 4 [label="maxExclusive"] + 4 -> 4 [label="enumeration"] + 4 -> 4 [label="assertion"] + 4 -> 4 [label="maxInclusive"] + 4 -> 4 [label="maxLength"] + 4 -> 4 [label="pattern"] + 4 -> 4 [label="totalDigits"] + 4 -> 4 [label="minExclusive"] + 4 -> 4 [label="minInclusive"] + 1 [shape=doublecircle, style=filled, color=blue] + 2 [shape=doublecircle, style=filled, color=green] + 3 [shape=doublecircle, style=filled, color=green] + 4 [shape=doublecircle, style=filled, color=green] +} diff --git a/src/xmlpatterns/schema/doc/TotalDigitsFacet_diagram.dot b/src/xmlpatterns/schema/doc/TotalDigitsFacet_diagram.dot new file mode 100644 index 0000000..0ef4cd6 --- /dev/null +++ b/src/xmlpatterns/schema/doc/TotalDigitsFacet_diagram.dot @@ -0,0 +1,6 @@ +digraph TotalDigitsFacet { + mindist = 2.0 + 1 -> 2 [label="annotation"] + 1 [shape=doublecircle, style=filled, color=blue] + 2 [shape=doublecircle, style=filled, color=green] +} diff --git a/src/xmlpatterns/schema/doc/Union_diagram.dot b/src/xmlpatterns/schema/doc/Union_diagram.dot new file mode 100644 index 0000000..d6c1865 --- /dev/null +++ b/src/xmlpatterns/schema/doc/Union_diagram.dot @@ -0,0 +1,10 @@ +digraph Union { + mindist = 2.0 + 1 -> 2 [label="annotation"] + 1 -> 3 [label="simpleType"] + 2 -> 3 [label="simpleType"] + 3 -> 3 [label="simpleType"] + 1 [shape=doublecircle, style=filled, color=blue] + 2 [shape=doublecircle, style=filled, color=green] + 3 [shape=doublecircle, style=filled, color=green] +} diff --git a/src/xmlpatterns/schema/doc/Unique_diagram.dot b/src/xmlpatterns/schema/doc/Unique_diagram.dot new file mode 100644 index 0000000..5b1d098 --- /dev/null +++ b/src/xmlpatterns/schema/doc/Unique_diagram.dot @@ -0,0 +1,12 @@ +digraph Unique { + mindist = 2.0 + 1 -> 2 [label="annotation"] + 1 -> 3 [label="selector"] + 2 -> 3 [label="selector"] + 3 -> 4 [label="field"] + 4 -> 4 [label="field"] + 1 [shape=circle, style=filled, color=blue] + 2 [shape=circle, style=filled, color=red] + 3 [shape=circle, style=filled, color=red] + 4 [shape=doublecircle, style=filled, color=green] +} diff --git a/src/xmlpatterns/schema/doc/WhiteSpaceFacet_diagram.dot b/src/xmlpatterns/schema/doc/WhiteSpaceFacet_diagram.dot new file mode 100644 index 0000000..596403c --- /dev/null +++ b/src/xmlpatterns/schema/doc/WhiteSpaceFacet_diagram.dot @@ -0,0 +1,6 @@ +digraph WhiteSpaceFacet { + mindist = 2.0 + 1 -> 2 [label="annotation"] + 1 [shape=doublecircle, style=filled, color=blue] + 2 [shape=doublecircle, style=filled, color=green] +} diff --git a/src/xmlpatterns/schema/doc/legend.dot b/src/xmlpatterns/schema/doc/legend.dot new file mode 100644 index 0000000..4f5792e --- /dev/null +++ b/src/xmlpatterns/schema/doc/legend.dot @@ -0,0 +1,7 @@ +digraph { + size="5,4" + 1 [label=" start state ", shape=circle, style=filled, color=blue] + 2 [label="start/end state", shape=doublecircle, style=filled, color=blue] + 3 [label=" internal state", shape=circle, style=filled, color=red] + 4 [label=" end state ", shape=doublecircle, style=filled, color=green] +} diff --git a/src/xmlpatterns/schema/qnamespacesupport.cpp b/src/xmlpatterns/schema/qnamespacesupport.cpp new file mode 100644 index 0000000..00698d6 --- /dev/null +++ b/src/xmlpatterns/schema/qnamespacesupport.cpp @@ -0,0 +1,132 @@ +/**************************************************************************** +** +** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the $MODULE$ of the Qt Toolkit. +** +** $TROLLTECH_DUAL_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. + +#include "qnamespacesupport_p.h" + +QT_BEGIN_NAMESPACE + +using namespace QPatternist; + +NamespaceSupport::NamespaceSupport() +{ +} + +NamespaceSupport::NamespaceSupport(const NamePool::Ptr &namePool) + : m_namePool(namePool) +{ + // the XML namespace + const QXmlName binding = namePool->allocateBinding(QLatin1String("xml"), + QLatin1String("http://www.w3.org/XML/1998/namespace")); + m_ns.insert(binding.prefix(), binding.namespaceURI()); +} + +void NamespaceSupport::setPrefix(const QXmlName::PrefixCode prefixCode, const QXmlName::NamespaceCode namespaceCode) +{ + m_ns.insert(prefixCode, namespaceCode); +} + +void NamespaceSupport::setPrefixes(const QXmlStreamNamespaceDeclarations &declarations) +{ + for (int i = 0; i < declarations.count(); i++) { + const QXmlStreamNamespaceDeclaration declaration = declarations.at(i); + + const QXmlName::PrefixCode prefixCode = m_namePool->allocatePrefix(declaration.prefix().toString()); + const QXmlName::NamespaceCode namespaceCode = m_namePool->allocateNamespace(declaration.namespaceUri().toString()); + m_ns.insert(prefixCode, namespaceCode); + } +} + +void NamespaceSupport::setTargetNamespace(const QXmlName::NamespaceCode namespaceCode) +{ + m_ns.insert(0, namespaceCode); +} + +QXmlName::PrefixCode NamespaceSupport::prefix(const QXmlName::NamespaceCode namespaceCode) const +{ + NamespaceHash::const_iterator itc, it = m_ns.constBegin(); + while ((itc=it) != m_ns.constEnd()) { + ++it; + if (*itc == namespaceCode) + return itc.key(); + } + return 0; +} + +QXmlName::NamespaceCode NamespaceSupport::uri(const QXmlName::PrefixCode prefixCode) const +{ + return m_ns.value(prefixCode); +} + +bool NamespaceSupport::processName(const QString& qname, NameType type, QXmlName &name) const +{ + int len = qname.size(); + const QChar *data = qname.constData(); + for (int pos = 0; pos < len; ++pos) { + if (data[pos] == QLatin1Char(':')) { + const QXmlName::PrefixCode prefixCode = m_namePool->allocatePrefix(qname.left(pos)); + if (!m_ns.contains(prefixCode)) + return false; + const QXmlName::NamespaceCode namespaceCode = uri(prefixCode); + const QXmlName::LocalNameCode localNameCode = m_namePool->allocateLocalName(qname.mid(pos + 1)); + name = QXmlName(namespaceCode, localNameCode, prefixCode); + return true; + } + } + + // there was no ':' + QXmlName::NamespaceCode namespaceCode = 0; + // attributes don't take default namespace + if (type == ElementName && !m_ns.isEmpty()) { + namespaceCode = m_ns.value(0); // get default namespace + } + + const QXmlName::LocalNameCode localNameCode = m_namePool->allocateLocalName(qname); + name = QXmlName(namespaceCode, localNameCode, 0); + + return true; +} + +void NamespaceSupport::pushContext() +{ + m_nsStack.push(m_ns); +} + +void NamespaceSupport::popContext() +{ + m_ns.clear(); + if(!m_nsStack.isEmpty()) + m_ns = m_nsStack.pop(); +} + +QList NamespaceSupport::namespaceBindings() const +{ + QList bindings; + + QHashIterator it(m_ns); + while (it.hasNext()) { + it.next(); + bindings.append(QXmlName(it.value(), StandardLocalNames::empty, it.key())); + } + + return bindings; +} + +QT_END_NAMESPACE diff --git a/src/xmlpatterns/schema/qnamespacesupport_p.h b/src/xmlpatterns/schema/qnamespacesupport_p.h new file mode 100644 index 0000000..d338eae --- /dev/null +++ b/src/xmlpatterns/schema/qnamespacesupport_p.h @@ -0,0 +1,143 @@ +/**************************************************************************** +** +** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the $MODULE$ of the Qt Toolkit. +** +** $TROLLTECH_DUAL_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_NamespaceSupport_H +#define Patternist_NamespaceSupport_H + +#include "qnamepool_p.h" + +#include +#include +#include +#include +#include + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +namespace QPatternist +{ + /** + * @short A helper class for handling nested namespace declarations. + * + * This class is mostly an adaption of QXmlNamespaceSupport to the NamePool + * mechanism used in XmlPatterns. + * + * @ingroup Patternist_schema + * @author Tobias Koenig + */ + class NamespaceSupport + { + public: + /** + * Describes whether the name to process is an attribute or element. + */ + enum NameType + { + AttributeName, ///< An attribute name to process. + ElementName ///< An element name to process. + }; + + /** + * Creates an empty namespace support object. + */ + NamespaceSupport(); + + /** + * Creates a new namespace support object. + * + * @param namePool The name pool where all processed names are stored in. + */ + NamespaceSupport(const NamePool::Ptr &namePool); + + /** + * Adds a new prefix-to-namespace binding. + * + * @param prefixCode The name pool code for the prefix. + * @param namespaceCode The name pool code for the namespace. + */ + void setPrefix(const QXmlName::PrefixCode prefixCode, const QXmlName::NamespaceCode namespaceCode); + + /** + * Adds the prefix-to-namespace bindings from @p declarations to + * the namespace support. + */ + void setPrefixes(const QXmlStreamNamespaceDeclarations &declarations); + + /** + * Sets the name pool code of the target namespace of the schema the + * namespace support works on. + */ + void setTargetNamespace(const QXmlName::NamespaceCode code); + + /** + * Returns the prefix code for the given namespace @p code. + */ + QXmlName::PrefixCode prefix(const QXmlName::NamespaceCode code) const; + + /** + * Returns the namespace code for the given prefix @p code. + */ + QXmlName::NamespaceCode uri(const QXmlName::PrefixCode code) const; + + /** + * Converts the given @p qualifiedName to a resolved QXmlName @p name according + * to the current namespace mapping. + * + * @param qualifiedName The full qualified name. + * @param type The type of name processing. + * @param name The resolved QXmlName. + * + * @returns @c true if the name could be processed correctly or @c false if the + * namespace prefix is unknown. + */ + bool processName(const QString &qualifiedName, NameType type, QXmlName &name) const; + + /** + * Pushes the current namespace mapping onto the stack. + */ + void pushContext(); + + /** + * Pops the current namespace mapping from the stack. + */ + void popContext(); + + /** + * Returns the list of namespace bindings. + */ + QList namespaceBindings() const; + + private: + typedef QHash NamespaceHash; + + NamePool::Ptr m_namePool; + QStack m_nsStack; + NamespaceHash m_ns; + }; +} + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif diff --git a/src/xmlpatterns/schema/qxsdalternative.cpp b/src/xmlpatterns/schema/qxsdalternative.cpp new file mode 100644 index 0000000..f3f589a --- /dev/null +++ b/src/xmlpatterns/schema/qxsdalternative.cpp @@ -0,0 +1,38 @@ +/**************************************************************************** +** +** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the $MODULE$ of the Qt Toolkit. +** +** $TROLLTECH_DUAL_LICENSE$ +** +****************************************************************************/ + +#include "qxsdalternative_p.h" + +QT_BEGIN_NAMESPACE + +using namespace QPatternist; + +void XsdAlternative::setTest(const XsdXPathExpression::Ptr &test) +{ + m_test = test; +} + +XsdXPathExpression::Ptr XsdAlternative::test() const +{ + return m_test; +} + +void XsdAlternative::setType(const SchemaType::Ptr &type) +{ + m_type = type; +} + +SchemaType::Ptr XsdAlternative::type() const +{ + return m_type; +} + +QT_END_NAMESPACE diff --git a/src/xmlpatterns/schema/qxsdalternative_p.h b/src/xmlpatterns/schema/qxsdalternative_p.h new file mode 100644 index 0000000..451441e --- /dev/null +++ b/src/xmlpatterns/schema/qxsdalternative_p.h @@ -0,0 +1,84 @@ +/**************************************************************************** +** +** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the $MODULE$ of the Qt Toolkit. +** +** $TROLLTECH_DUAL_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_XsdAlternative_H +#define Patternist_XsdAlternative_H + +#include "qnamedschemacomponent_p.h" +#include "qschematype_p.h" +#include "qxsdannotated_p.h" +#include "qxsdxpathexpression_p.h" + +#include + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +namespace QPatternist +{ + /** + * @short Represents a XSD alternative object. + * + * @ingroup Patternist_schema + * @author Tobias Koenig + */ + class XsdAlternative : public NamedSchemaComponent, public XsdAnnotated + { + public: + typedef QExplicitlySharedDataPointer Ptr; + typedef QList List; + + /** + * Sets the xpath @p test of the alternative. + * + * @see Test Definition + */ + void setTest(const XsdXPathExpression::Ptr &test); + + /** + * Returns the xpath test of the alternative. + */ + XsdXPathExpression::Ptr test() const; + + /** + * Sets the @p type of the alternative. + * + * @see Type Definition + */ + void setType(const SchemaType::Ptr &type); + + /** + * Returns the type of the alternative. + */ + SchemaType::Ptr type() const; + + private: + XsdXPathExpression::Ptr m_test; + SchemaType::Ptr m_type; + }; +} + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif diff --git a/src/xmlpatterns/schema/qxsdannotated.cpp b/src/xmlpatterns/schema/qxsdannotated.cpp new file mode 100644 index 0000000..a29b5c4 --- /dev/null +++ b/src/xmlpatterns/schema/qxsdannotated.cpp @@ -0,0 +1,33 @@ +/**************************************************************************** +** +** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the $MODULE$ of the Qt Toolkit. +** +** $TROLLTECH_DUAL_LICENSE$ +** +****************************************************************************/ + +#include "qxsdannotated_p.h" + +QT_BEGIN_NAMESPACE + +using namespace QPatternist; + +void XsdAnnotated::addAnnotation(const XsdAnnotation::Ptr &annotation) +{ + m_annotations.append(annotation); +} + +void XsdAnnotated::addAnnotations(const XsdAnnotation::List &annotations) +{ + m_annotations << annotations; +} + +XsdAnnotation::List XsdAnnotated::annotations() const +{ + return m_annotations; +} + +QT_END_NAMESPACE diff --git a/src/xmlpatterns/schema/qxsdannotated_p.h b/src/xmlpatterns/schema/qxsdannotated_p.h new file mode 100644 index 0000000..251b252 --- /dev/null +++ b/src/xmlpatterns/schema/qxsdannotated_p.h @@ -0,0 +1,66 @@ +/**************************************************************************** +** +** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the $MODULE$ of the Qt Toolkit. +** +** $TROLLTECH_DUAL_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_XsdAnnotated_H +#define Patternist_XsdAnnotated_H + +#include "qxsdannotation_p.h" + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +namespace QPatternist +{ + /** + * @short Base class for all XSD components with annotation content. + * + * @ingroup Patternist_schema + * @author Tobias Koenig + */ + class XsdAnnotated + { + public: + /** + * Adds a new @p annotation to the component. + */ + void addAnnotation(const XsdAnnotation::Ptr &annotation); + + /** + * Adds a list of new @p annotations to the component. + */ + void addAnnotations(const XsdAnnotation::List &annotations); + + /** + * Returns the list of all annotations of the component. + */ + XsdAnnotation::List annotations() const; + + private: + XsdAnnotation::List m_annotations; + }; +} + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif diff --git a/src/xmlpatterns/schema/qxsdannotation.cpp b/src/xmlpatterns/schema/qxsdannotation.cpp new file mode 100644 index 0000000..0a9dc04 --- /dev/null +++ b/src/xmlpatterns/schema/qxsdannotation.cpp @@ -0,0 +1,48 @@ +/**************************************************************************** +** +** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the $MODULE$ of the Qt Toolkit. +** +** $TROLLTECH_DUAL_LICENSE$ +** +****************************************************************************/ + +#include "qxsdannotation_p.h" + +QT_BEGIN_NAMESPACE + +using namespace QPatternist; + +void XsdAnnotation::setId(const DerivedString::Ptr &id) +{ + m_id = id; +} + +DerivedString::Ptr XsdAnnotation::id() const +{ + return m_id; +} + +void XsdAnnotation::addApplicationInformation(const XsdApplicationInformation::Ptr &information) +{ + m_applicationInformation.append(information); +} + +XsdApplicationInformation::List XsdAnnotation::applicationInformation() const +{ + return m_applicationInformation; +} + +void XsdAnnotation::addDocumentation(const XsdDocumentation::Ptr &documentation) +{ + m_documentations.append(documentation); +} + +XsdDocumentation::List XsdAnnotation::documentation() const +{ + return m_documentations; +} + +QT_END_NAMESPACE diff --git a/src/xmlpatterns/schema/qxsdannotation_p.h b/src/xmlpatterns/schema/qxsdannotation_p.h new file mode 100644 index 0000000..8c23bae --- /dev/null +++ b/src/xmlpatterns/schema/qxsdannotation_p.h @@ -0,0 +1,97 @@ +/**************************************************************************** +** +** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the $MODULE$ of the Qt Toolkit. +** +** $TROLLTECH_DUAL_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_XsdAnnotation_H +#define Patternist_XsdAnnotation_H + +#include "qderivedstring_p.h" +#include "qxsdapplicationinformation_p.h" +#include "qxsddocumentation_p.h" + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +namespace QPatternist +{ + /** + * @short Represents a XSD annotation object. + * + * This class represents the annotation object of a XML schema as described + * here. + * + * @ingroup Patternist_schema + * @author Tobias Koenig + */ + class XsdAnnotation : public NamedSchemaComponent + { + public: + typedef QExplicitlySharedDataPointer Ptr; + typedef QList List; + + /** + * Sets the @p id of the annotation. + */ + void setId(const DerivedString::Ptr &id); + + /** + * Returns the @p id of the annotation. + */ + DerivedString::Ptr id() const; + + /** + * Adds an application @p information to the annotation. + * + * The application information is meant to be interpreted by + * a software system, e.g. other parts of the XML processor pipeline. + */ + void addApplicationInformation(const XsdApplicationInformation::Ptr &information); + + /** + * Returns the list of all application information of the annotation. + */ + XsdApplicationInformation::List applicationInformation() const; + + /** + * Adds a @p documentation to the annotation. + * + * The documentation is meant to be read by human being, e.g. additional + * constraints or information about schema components. + */ + void addDocumentation(const XsdDocumentation::Ptr &documentation); + + /** + * Returns the list of all documentations of the annotation. + */ + XsdDocumentation::List documentation() const; + + private: + DerivedString::Ptr m_id; + XsdApplicationInformation::List m_applicationInformation; + XsdDocumentation::List m_documentations; + }; +} + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif diff --git a/src/xmlpatterns/schema/qxsdapplicationinformation.cpp b/src/xmlpatterns/schema/qxsdapplicationinformation.cpp new file mode 100644 index 0000000..5669220 --- /dev/null +++ b/src/xmlpatterns/schema/qxsdapplicationinformation.cpp @@ -0,0 +1,38 @@ +/**************************************************************************** +** +** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the $MODULE$ of the Qt Toolkit. +** +** $TROLLTECH_DUAL_LICENSE$ +** +****************************************************************************/ + +#include "qxsdapplicationinformation_p.h" + +QT_BEGIN_NAMESPACE + +using namespace QPatternist; + +void XsdApplicationInformation::setSource(const AnyURI::Ptr &source) +{ + m_source = source; +} + +AnyURI::Ptr XsdApplicationInformation::source() const +{ + return m_source; +} + +void XsdApplicationInformation::setContent(const QString &content) +{ + m_content = content; +} + +QString XsdApplicationInformation::content() const +{ + return m_content; +} + +QT_END_NAMESPACE diff --git a/src/xmlpatterns/schema/qxsdapplicationinformation_p.h b/src/xmlpatterns/schema/qxsdapplicationinformation_p.h new file mode 100644 index 0000000..30839d3 --- /dev/null +++ b/src/xmlpatterns/schema/qxsdapplicationinformation_p.h @@ -0,0 +1,85 @@ +/**************************************************************************** +** +** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the $MODULE$ of the Qt Toolkit. +** +** $TROLLTECH_DUAL_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_XsdApplicationInformation_H +#define Patternist_XsdApplicationInformation_H + +#include "qanytype_p.h" +#include "qanyuri_p.h" +#include "qnamedschemacomponent_p.h" + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +namespace QPatternist +{ + /** + * @short Represents a XSD appinfo object. + * + * This class represents the appinfo component of an annotation object + * of a XML schema as described here. + * + * @ingroup Patternist_schema + * @author Tobias Koenig + */ + class XsdApplicationInformation : public NamedSchemaComponent + { + public: + typedef QExplicitlySharedDataPointer Ptr; + typedef QList List; + + /** + * Sets the @p source of the application information. + * + * The source points to an URL that contains more + * information. + */ + void setSource(const AnyURI::Ptr &source); + + /** + * Returns the source of the application information. + */ + AnyURI::Ptr source() const; + + /** + * Sets the @p content of the application information. + * + * The content can be of abritrary type. + */ + void setContent(const QString &content); + + /** + * Returns the content of the application information. + */ + QString content() const; + + private: + AnyURI::Ptr m_source; + QString m_content; + }; +} + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif diff --git a/src/xmlpatterns/schema/qxsdassertion.cpp b/src/xmlpatterns/schema/qxsdassertion.cpp new file mode 100644 index 0000000..f6cbf81 --- /dev/null +++ b/src/xmlpatterns/schema/qxsdassertion.cpp @@ -0,0 +1,28 @@ +/**************************************************************************** +** +** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the $MODULE$ of the Qt Toolkit. +** +** $TROLLTECH_DUAL_LICENSE$ +** +****************************************************************************/ + +#include "qxsdassertion_p.h" + +QT_BEGIN_NAMESPACE + +using namespace QPatternist; + +void XsdAssertion::setTest(const XsdXPathExpression::Ptr &test) +{ + m_test = test; +} + +XsdXPathExpression::Ptr XsdAssertion::test() const +{ + return m_test; +} + +QT_END_NAMESPACE diff --git a/src/xmlpatterns/schema/qxsdassertion_p.h b/src/xmlpatterns/schema/qxsdassertion_p.h new file mode 100644 index 0000000..0ae5ff6 --- /dev/null +++ b/src/xmlpatterns/schema/qxsdassertion_p.h @@ -0,0 +1,71 @@ +/**************************************************************************** +** +** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the $MODULE$ of the Qt Toolkit. +** +** $TROLLTECH_DUAL_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_XsdAssertion_H +#define Patternist_XsdAssertion_H + +#include "qnamedschemacomponent_p.h" +#include "qxsdannotated_p.h" +#include "qxsdxpathexpression_p.h" + +#include + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +namespace QPatternist +{ + /** + * @short Represents a XSD assertion object. + * + * @ingroup Patternist_schema + * @author Tobias Koenig + * @see Assertion Definition + */ + class XsdAssertion : public NamedSchemaComponent, public XsdAnnotated + { + public: + typedef QExplicitlySharedDataPointer Ptr; + typedef QList List; + + /** + * Sets the @p test of the assertion. + * + * @see Test Definition + */ + void setTest(const XsdXPathExpression::Ptr &test); + + /** + * Returns the test of the assertion. + */ + XsdXPathExpression::Ptr test() const; + + private: + XsdXPathExpression::Ptr m_test; + }; +} + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif diff --git a/src/xmlpatterns/schema/qxsdattribute.cpp b/src/xmlpatterns/schema/qxsdattribute.cpp new file mode 100644 index 0000000..6cf60ec --- /dev/null +++ b/src/xmlpatterns/schema/qxsdattribute.cpp @@ -0,0 +1,100 @@ +/**************************************************************************** +** +** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the $MODULE$ of the Qt Toolkit. +** +** $TROLLTECH_DUAL_LICENSE$ +** +****************************************************************************/ + +#include "qxsdattribute_p.h" +#include "qxsdcomplextype_p.h" + +QT_BEGIN_NAMESPACE + +using namespace QPatternist; + + +void XsdAttribute::Scope::setVariety(Variety variety) +{ + m_variety = variety; +} + +XsdAttribute::Scope::Variety XsdAttribute::Scope::variety() const +{ + return m_variety; +} + +void XsdAttribute::Scope::setParent(const NamedSchemaComponent::Ptr &parent) +{ + m_parent = parent; +} + +NamedSchemaComponent::Ptr XsdAttribute::Scope::parent() const +{ + return m_parent; +} + +void XsdAttribute::ValueConstraint::setVariety(Variety variety) +{ + m_variety = variety; +} + +XsdAttribute::ValueConstraint::Variety XsdAttribute::ValueConstraint::variety() const +{ + return m_variety; +} + +void XsdAttribute::ValueConstraint::setValue(const QString &value) +{ + m_value = value; +} + +QString XsdAttribute::ValueConstraint::value() const +{ + return m_value; +} + +void XsdAttribute::ValueConstraint::setLexicalForm(const QString &form) +{ + m_lexicalForm = form; +} + +QString XsdAttribute::ValueConstraint::lexicalForm() const +{ + return m_lexicalForm; +} + +void XsdAttribute::setType(const AnySimpleType::Ptr &type) +{ + m_type = type; +} + +AnySimpleType::Ptr XsdAttribute::type() const +{ + return m_type; +} + +void XsdAttribute::setScope(const Scope::Ptr &scope) +{ + m_scope = scope; +} + +XsdAttribute::Scope::Ptr XsdAttribute::scope() const +{ + return m_scope; +} + +void XsdAttribute::setValueConstraint(const ValueConstraint::Ptr &constraint) +{ + m_valueConstraint = constraint; +} + +XsdAttribute::ValueConstraint::Ptr XsdAttribute::valueConstraint() const +{ + return m_valueConstraint; +} + +QT_END_NAMESPACE diff --git a/src/xmlpatterns/schema/qxsdattribute_p.h b/src/xmlpatterns/schema/qxsdattribute_p.h new file mode 100644 index 0000000..46d7355 --- /dev/null +++ b/src/xmlpatterns/schema/qxsdattribute_p.h @@ -0,0 +1,216 @@ +/**************************************************************************** +** +** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the $MODULE$ of the Qt Toolkit. +** +** $TROLLTECH_DUAL_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_XsdAttribute_H +#define Patternist_XsdAttribute_H + +#include "qanysimpletype_p.h" +#include "qnamedschemacomponent_p.h" +#include "qxsdannotated_p.h" + +#include + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +namespace QPatternist +{ + /** + * @short Represents a XSD attribute object. + * + * This class represents the attribute object of a XML schema as described + * here. + * + * It contains information from either a top-level attribute declaration (as child of + * a schema object) or of a local attribute declaration (as child of complexType + * or attributeGroup object without a 'ref' attribute). + * + * All other occurrences of the attribute object are represented by the XsdAttributeUse class. + * + * @see XML Schema API reference + * @ingroup Patternist_schema + * @author Tobias Koenig + */ + class XsdAttribute : public NamedSchemaComponent, public XsdAnnotated + { + public: + typedef QExplicitlySharedDataPointer Ptr; + typedef QList List; + + /** + * @short Describes the scope of an attribute. + * + * @see Scope Definition + */ + class Scope : public QSharedData + { + public: + typedef QExplicitlySharedDataPointer Ptr; + + /** + * Describes the scope of an attribute. + */ + enum Variety + { + Global, ///< The attribute is defined globally as child of the schema object. + Local ///< The attribute is defined locally as child of a complex type or attribute group definition. + }; + + /** + * Sets the @p variety of the attribute scope. + * + * @see Variety Definition + */ + void setVariety(Variety variety); + + /** + * Returns the variety of the attribute scope. + */ + Variety variety() const; + + /** + * Sets the @p parent complex type or attribute group definition of the attribute scope. + * + * @see Parent Definition + */ + void setParent(const NamedSchemaComponent::Ptr &parent); + + /** + * Returns the parent complex type or attribute group definition of the attribute scope. + */ + NamedSchemaComponent::Ptr parent() const; + + private: + Variety m_variety; + NamedSchemaComponent::Ptr m_parent; + }; + + + /** + * @short Describes the value constraint of an attribute. + * + * @see Value Constraint Definition + */ + class ValueConstraint : public QSharedData + { + public: + typedef QExplicitlySharedDataPointer Ptr; + + /** + * Describes the value constraint of an attribute. + */ + enum Variety + { + Default, ///< The attribute has a default value set. + Fixed ///< The attribute has a fixed value set. + }; + + /** + * Sets the @p variety of the attribute value constraint. + * + * @see Variety Definition + */ + void setVariety(Variety variety); + + /** + * Returns the variety of the attribute value constraint. + */ + Variety variety() const; + + /** + * Sets the @p value of the constraint. + * + * @see Value Definition + */ + void setValue(const QString &value); + + /** + * Returns the value of the constraint. + */ + QString value() const; + + /** + * Sets the lexical @p form of the constraint. + * + * @see Lexical Form Definition + */ + void setLexicalForm(const QString &form); + + /** + * Returns the lexical form of the constraint. + */ + QString lexicalForm() const; + + private: + Variety m_variety; + QString m_value; + QString m_lexicalForm; + }; + + /** + * Sets the simple @p type definition of the attribute. + * + * @see Simple Type Definition + */ + void setType(const AnySimpleType::Ptr &type); + + /** + * Returns the simple type definition of the attribute. + */ + AnySimpleType::Ptr type() const; + + /** + * Sets the @p scope of the attribute. + * + * @see Scope Definition + */ + void setScope(const Scope::Ptr &scope); + + /** + * Returns the scope of the attribute. + */ + Scope::Ptr scope() const; + + /** + * Sets the value @p constraint of the attribute. + * + * @see Value Constraint Definition + */ + void setValueConstraint(const ValueConstraint::Ptr &constraint); + + /** + * Returns the value constraint of the attribute. + */ + ValueConstraint::Ptr valueConstraint() const; + + private: + AnySimpleType::Ptr m_type; + Scope::Ptr m_scope; + ValueConstraint::Ptr m_valueConstraint; + }; +} + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif diff --git a/src/xmlpatterns/schema/qxsdattributegroup.cpp b/src/xmlpatterns/schema/qxsdattributegroup.cpp new file mode 100644 index 0000000..8f2a47e --- /dev/null +++ b/src/xmlpatterns/schema/qxsdattributegroup.cpp @@ -0,0 +1,43 @@ +/**************************************************************************** +** +** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the $MODULE$ of the Qt Toolkit. +** +** $TROLLTECH_DUAL_LICENSE$ +** +****************************************************************************/ + +#include "qxsdattributegroup_p.h" + +QT_BEGIN_NAMESPACE + +using namespace QPatternist; + +void XsdAttributeGroup::setAttributeUses(const XsdAttributeUse::List &attributeUses) +{ + m_attributeUses = attributeUses; +} + +void XsdAttributeGroup::addAttributeUse(const XsdAttributeUse::Ptr &attributeUse) +{ + m_attributeUses.append(attributeUse); +} + +XsdAttributeUse::List XsdAttributeGroup::attributeUses() const +{ + return m_attributeUses; +} + +void XsdAttributeGroup::setWildcard(const XsdWildcard::Ptr &wildcard) +{ + m_wildcard = wildcard; +} + +XsdWildcard::Ptr XsdAttributeGroup::wildcard() const +{ + return m_wildcard; +} + +QT_END_NAMESPACE diff --git a/src/xmlpatterns/schema/qxsdattributegroup_p.h b/src/xmlpatterns/schema/qxsdattributegroup_p.h new file mode 100644 index 0000000..7a3bd79 --- /dev/null +++ b/src/xmlpatterns/schema/qxsdattributegroup_p.h @@ -0,0 +1,92 @@ +/**************************************************************************** +** +** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the $MODULE$ of the Qt Toolkit. +** +** $TROLLTECH_DUAL_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_XsdAttributeGroup_H +#define Patternist_XsdAttributeGroup_H + +#include "qxsdannotated_p.h" +#include "qxsdattributeuse_p.h" +#include "qxsdwildcard_p.h" + +#include + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +namespace QPatternist +{ + /** + * @short Represents the XSD attributeGroup object. + * + * This class represents the attributeGroup object of a XML schema as described + * here. + * + * @see XML Schema API reference + * @ingroup Patternist_schema + * @author Tobias Koenig + */ + class XsdAttributeGroup : public NamedSchemaComponent, public XsdAnnotated + { + public: + typedef QExplicitlySharedDataPointer Ptr; + typedef QList List; + + /** + * Sets the list of attribute @p uses that are defined in the attribute group. + * + * @see Attribute Uses + */ + void setAttributeUses(const XsdAttributeUse::List &uses); + + /** + * Adds a new attribute @p use to the attribute group. + */ + void addAttributeUse(const XsdAttributeUse::Ptr &use); + + /** + * Returns the list of all attribute uses of the attribute group. + */ + XsdAttributeUse::List attributeUses() const; + + /** + * Sets the attribute @p wildcard of the attribute group. + * + * @see Attribute Wildcard + */ + void setWildcard(const XsdWildcard::Ptr &wildcard); + + /** + * Returns the attribute wildcard of the attribute group. + */ + XsdWildcard::Ptr wildcard() const; + + private: + XsdAttributeUse::List m_attributeUses; + XsdWildcard::Ptr m_wildcard; + }; +} + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif diff --git a/src/xmlpatterns/schema/qxsdattributereference.cpp b/src/xmlpatterns/schema/qxsdattributereference.cpp new file mode 100644 index 0000000..3c36a4e --- /dev/null +++ b/src/xmlpatterns/schema/qxsdattributereference.cpp @@ -0,0 +1,58 @@ +/**************************************************************************** +** +** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the $MODULE$ of the Qt Toolkit. +** +** $TROLLTECH_DUAL_LICENSE$ +** +****************************************************************************/ + +#include "qxsdattributereference_p.h" + +QT_BEGIN_NAMESPACE + +using namespace QPatternist; + +bool XsdAttributeReference::isAttributeUse() const +{ + return false; +} + +bool XsdAttributeReference::isReference() const +{ + return true; +} + +void XsdAttributeReference::setType(Type type) +{ + m_type = type; +} + +XsdAttributeReference::Type XsdAttributeReference::type() const +{ + return m_type; +} + +void XsdAttributeReference::setReferenceName(const QXmlName &referenceName) +{ + m_referenceName = referenceName; +} + +QXmlName XsdAttributeReference::referenceName() const +{ + return m_referenceName; +} + +void XsdAttributeReference::setSourceLocation(const QSourceLocation &location) +{ + m_sourceLocation = location; +} + +QSourceLocation XsdAttributeReference::sourceLocation() const +{ + return m_sourceLocation; +} + +QT_END_NAMESPACE diff --git a/src/xmlpatterns/schema/qxsdattributereference_p.h b/src/xmlpatterns/schema/qxsdattributereference_p.h new file mode 100644 index 0000000..be48b3a --- /dev/null +++ b/src/xmlpatterns/schema/qxsdattributereference_p.h @@ -0,0 +1,117 @@ +/**************************************************************************** +** +** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the $MODULE$ of the Qt Toolkit. +** +** $TROLLTECH_DUAL_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_XsdAttributeReference_H +#define Patternist_XsdAttributeReference_H + +#include "qxsdattributeuse_p.h" + +#include + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +namespace QPatternist +{ + /** + * @short A helper class for attribute reference resolving. + * + * For easy resolving of attribute references, we have this class + * that can be used as a place holder for the real attribute use + * object it is referring to. + * So whenever the parser detects an attribute reference, it creates + * a XsdAttributeReference and returns it instead of the XsdAttributeUse. + * During a later phase, the resolver will look for all XsdAttributeReferences + * in the schema and will replace them with their referring XsdAttributeUse + * objects. + * + * @ingroup Patternist_schema + * @author Tobias Koenig + */ + class XsdAttributeReference : public XsdAttributeUse + { + public: + typedef QExplicitlySharedDataPointer Ptr; + + /** + * Describes the type of the attribute reference. + */ + enum Type + { + AttributeUse, ///< The reference points to an attribute use. + AttributeGroup ///< The reference points to an attribute group. + }; + + /** + * Always returns false, used to avoid dynamic casts. + */ + virtual bool isAttributeUse() const; + + /** + * Always returns true, used to avoid dynamic casts. + */ + virtual bool isReference() const; + + /** + * Sets the @p type of the attribute reference. + */ + void setType(Type type); + + /** + * Returns the type of the attribute reference. + */ + Type type() const; + + /** + * Sets the @p name of the attribute or attribute group the + * attribute reference refers to. + */ + void setReferenceName(const QXmlName &name); + + /** + * Returns the name of the attribute or attribute group the + * attribute reference refers to. + */ + QXmlName referenceName() const; + + /** + * Sets the source @p location where the reference is located. + */ + void setSourceLocation(const QSourceLocation &location); + + /** + * Returns the source location where the reference is located. + */ + QSourceLocation sourceLocation() const; + + private: + Type m_type; + QXmlName m_referenceName; + QSourceLocation m_sourceLocation; + }; +} + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif diff --git a/src/xmlpatterns/schema/qxsdattributeterm.cpp b/src/xmlpatterns/schema/qxsdattributeterm.cpp new file mode 100644 index 0000000..a9c3898 --- /dev/null +++ b/src/xmlpatterns/schema/qxsdattributeterm.cpp @@ -0,0 +1,28 @@ +/**************************************************************************** +** +** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the $MODULE$ of the Qt Toolkit. +** +** $TROLLTECH_DUAL_LICENSE$ +** +****************************************************************************/ + +#include "qxsdattributeterm_p.h" + +QT_BEGIN_NAMESPACE + +using namespace QPatternist; + +bool XsdAttributeTerm::isAttributeUse() const +{ + return false; +} + +bool XsdAttributeTerm::isReference() const +{ + return false; +} + +QT_END_NAMESPACE diff --git a/src/xmlpatterns/schema/qxsdattributeterm_p.h b/src/xmlpatterns/schema/qxsdattributeterm_p.h new file mode 100644 index 0000000..507df32 --- /dev/null +++ b/src/xmlpatterns/schema/qxsdattributeterm_p.h @@ -0,0 +1,66 @@ +/**************************************************************************** +** +** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the $MODULE$ of the Qt Toolkit. +** +** $TROLLTECH_DUAL_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_XsdAttributeTerm_H +#define Patternist_XsdAttributeTerm_H + +#include "qnamedschemacomponent_p.h" +#include "qxsdannotated_p.h" + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +namespace QPatternist +{ + /** + * @short A base class for all attribute types. + * + * For easy resolving of attribute references, we use this as + * common base class for XsdAttribute and XsdAttributeReference. + * + * @ingroup Patternist_schema + * @author Tobias Koenig + */ + class XsdAttributeTerm : public NamedSchemaComponent, public XsdAnnotated + { + public: + typedef QExplicitlySharedDataPointer Ptr; + + /** + * Returns @c true if the term is an attribute use, @c false otherwise. + */ + virtual bool isAttributeUse() const; + + /** + * Returns @c true if the term is an attribute use reference, @c false otherwise. + * + * @note The reference term is only used internally as helper during type resolving. + */ + virtual bool isReference() const; + }; +} + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif diff --git a/src/xmlpatterns/schema/qxsdattributeuse.cpp b/src/xmlpatterns/schema/qxsdattributeuse.cpp new file mode 100644 index 0000000..96d81bc --- /dev/null +++ b/src/xmlpatterns/schema/qxsdattributeuse.cpp @@ -0,0 +1,106 @@ +/**************************************************************************** +** +** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the $MODULE$ of the Qt Toolkit. +** +** $TROLLTECH_DUAL_LICENSE$ +** +****************************************************************************/ + +#include "qxsdattributeuse_p.h" + +QT_BEGIN_NAMESPACE + +using namespace QPatternist; + +void XsdAttributeUse::ValueConstraint::setVariety(Variety variety) +{ + m_variety = variety; +} + +XsdAttributeUse::ValueConstraint::Variety XsdAttributeUse::ValueConstraint::variety() const +{ + return m_variety; +} + +void XsdAttributeUse::ValueConstraint::setValue(const QString &value) +{ + m_value = value; +} + +QString XsdAttributeUse::ValueConstraint::value() const +{ + return m_value; +} + +void XsdAttributeUse::ValueConstraint::setLexicalForm(const QString &form) +{ + m_lexicalForm = form; +} + +QString XsdAttributeUse::ValueConstraint::lexicalForm() const +{ + return m_lexicalForm; +} + +XsdAttributeUse::ValueConstraint::Ptr XsdAttributeUse::ValueConstraint::fromAttributeValueConstraint(const XsdAttribute::ValueConstraint::Ptr &constraint) +{ + XsdAttributeUse::ValueConstraint::Ptr newConstraint(new XsdAttributeUse::ValueConstraint()); + switch (constraint->variety()) { + case XsdAttribute::ValueConstraint::Fixed: newConstraint->setVariety(Fixed); break; + case XsdAttribute::ValueConstraint::Default: newConstraint->setVariety(Default); break; + } + newConstraint->setValue(constraint->value()); + newConstraint->setLexicalForm(constraint->lexicalForm()); + + return newConstraint; +} + +XsdAttributeUse::XsdAttributeUse() + : m_useType(OptionalUse) +{ +} + +bool XsdAttributeUse::isAttributeUse() const +{ + return true; +} + +void XsdAttributeUse::setUseType(UseType type) +{ + m_useType = type; +} + +XsdAttributeUse::UseType XsdAttributeUse::useType() const +{ + return m_useType; +} + +bool XsdAttributeUse::isRequired() const +{ + return (m_useType == RequiredUse); +} + +void XsdAttributeUse::setAttribute(const XsdAttribute::Ptr &attribute) +{ + m_attribute = attribute; +} + +XsdAttribute::Ptr XsdAttributeUse::attribute() const +{ + return m_attribute; +} + +void XsdAttributeUse::setValueConstraint(const ValueConstraint::Ptr &constraint) +{ + m_valueConstraint = constraint; +} + +XsdAttributeUse::ValueConstraint::Ptr XsdAttributeUse::valueConstraint() const +{ + return m_valueConstraint; +} + +QT_END_NAMESPACE diff --git a/src/xmlpatterns/schema/qxsdattributeuse_p.h b/src/xmlpatterns/schema/qxsdattributeuse_p.h new file mode 100644 index 0000000..86021e1 --- /dev/null +++ b/src/xmlpatterns/schema/qxsdattributeuse_p.h @@ -0,0 +1,194 @@ +/**************************************************************************** +** +** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the $MODULE$ of the Qt Toolkit. +** +** $TROLLTECH_DUAL_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_XsdAttributeUse_H +#define Patternist_XsdAttributeUse_H + +#include "qxsdattribute_p.h" +#include "qxsdattributeterm_p.h" + +#include + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +namespace QPatternist +{ + /** + * @short Represents a XSD attribute use object. + * + * This class represents the attribute use object of a XML schema as described + * here. + * + * It contains information from a local attribute declaration (as child of complexType + * or attributeGroup object). + * + * All other occurrences of the attribute object are represented by the XsdAttribute class. + * + * @see XML Schema API reference + * @ingroup Patternist_schema + * @author Tobias Koenig + */ + class XsdAttributeUse : public XsdAttributeTerm + { + public: + typedef QExplicitlySharedDataPointer Ptr; + typedef QList List; + + /** + * Describes the value constraint of an attribute use. + * + * @see Value Constraint Definition + */ + class ValueConstraint : public QSharedData + { + public: + typedef QExplicitlySharedDataPointer Ptr; + + /** + * Describes the value constraint of an attribute use. + */ + enum Variety + { + Default, ///< The attribute use has a default value set. + Fixed ///< The attribute use has a fixed value set. + }; + + /** + * Sets the @p variety of the attribute use value constraint. + */ + void setVariety(Variety variety); + + /** + * Returns the variety of the attribute use value constraint. + */ + Variety variety() const; + + /** + * Sets the @p value of the constraint. + */ + void setValue(const QString &value); + + /** + * Returns the value of the constraint. + */ + QString value() const; + + /** + * Sets the lexical @p form of the constraint. + */ + void setLexicalForm(const QString &form); + + /** + * Returns the lexical form of the constraint. + */ + QString lexicalForm() const; + + /** + * Creates a new value constraint from a XsdAttribute::ValueConstraint. + */ + static ValueConstraint::Ptr fromAttributeValueConstraint(const XsdAttribute::ValueConstraint::Ptr &constraint); + + private: + Variety m_variety; + QString m_value; + QString m_lexicalForm; + }; + + /** + * Describes the use type of the attribute use. + */ + enum UseType + { + OptionalUse, ///< The attribute can be there but doesn't need to. + RequiredUse, ///< The attribute must be there. + ProhibitedUse ///< The attribute is not allowed to be there. + }; + + /** + * Creates a new attribute use object. + */ + XsdAttributeUse(); + + /** + * Always returns true, used to avoid dynamic casts. + */ + virtual bool isAttributeUse() const; + + /** + * Sets the use @p type of the attribute use. + * + * @see UseType + */ + void setUseType(UseType type); + + /** + * Returns the use type of the attribute use. + */ + UseType useType() const; + + /** + * Returns whether the attribute use is required. + * + * @see Required Definition + */ + bool isRequired() const; + + /** + * Sets the @p attribute the attribute use is referring to. + * That is either a local definition as child of a complexType + * or attributeGroup object, or a reference defined by the + * 'ref' attribute. + * + * @see Attribute Declaration + */ + void setAttribute(const XsdAttribute::Ptr &attribute); + + /** + * Returns the attribute the attribute use is referring to. + */ + XsdAttribute::Ptr attribute() const; + + /** + * Sets the value @p constraint of the attribute use. + * + * @see http://www.w3.org/TR/xmlschema11-1/#vc_au + */ + void setValueConstraint(const ValueConstraint::Ptr &constraint); + + /** + * Returns the value constraint of the attribute use. + */ + ValueConstraint::Ptr valueConstraint() const; + + private: + UseType m_useType; + XsdAttribute::Ptr m_attribute; + ValueConstraint::Ptr m_valueConstraint; + }; +} + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif diff --git a/src/xmlpatterns/schema/qxsdcomplextype.cpp b/src/xmlpatterns/schema/qxsdcomplextype.cpp new file mode 100644 index 0000000..ddc9110 --- /dev/null +++ b/src/xmlpatterns/schema/qxsdcomplextype.cpp @@ -0,0 +1,201 @@ +/**************************************************************************** +** +** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the $MODULE$ of the Qt Toolkit. +** +** $TROLLTECH_DUAL_LICENSE$ +** +****************************************************************************/ + +#include "qxsdcomplextype_p.h" + +QT_BEGIN_NAMESPACE + +using namespace QPatternist; + +void XsdComplexType::OpenContent::setMode(Mode mode) +{ + m_mode = mode; +} + +XsdComplexType::OpenContent::Mode XsdComplexType::OpenContent::mode() const +{ + return m_mode; +} + +void XsdComplexType::OpenContent::setWildcard(const XsdWildcard::Ptr &wildcard) +{ + m_wildcard = wildcard; +} + +XsdWildcard::Ptr XsdComplexType::OpenContent::wildcard() const +{ + return m_wildcard; +} + +void XsdComplexType::ContentType::setVariety(Variety variety) +{ + m_variety = variety; +} + +XsdComplexType::ContentType::Variety XsdComplexType::ContentType::variety() const +{ + return m_variety; +} + +void XsdComplexType::ContentType::setParticle(const XsdParticle::Ptr &particle) +{ + m_particle = particle; +} + +XsdParticle::Ptr XsdComplexType::ContentType::particle() const +{ + return m_particle; +} + +void XsdComplexType::ContentType::setOpenContent(const OpenContent::Ptr &content) +{ + m_openContent = content; +} + +XsdComplexType::OpenContent::Ptr XsdComplexType::ContentType::openContent() const +{ + return m_openContent; +} + +void XsdComplexType::ContentType::setSimpleType(const AnySimpleType::Ptr &type) +{ + m_simpleType = type; +} + +AnySimpleType::Ptr XsdComplexType::ContentType::simpleType() const +{ + return m_simpleType; +} + + +XsdComplexType::XsdComplexType() + : m_isAbstract(false) + , m_contentType(new ContentType()) +{ + m_contentType->setVariety(ContentType::Empty); +} + +void XsdComplexType::setIsAbstract(bool abstract) +{ + m_isAbstract = abstract; +} + +bool XsdComplexType::isAbstract() const +{ + return m_isAbstract; +} + +QString XsdComplexType::displayName(const NamePool::Ptr &np) const +{ + return np->displayName(name(np)); +} + +void XsdComplexType::setWxsSuperType(const SchemaType::Ptr &type) +{ + m_superType = type; +} + +SchemaType::Ptr XsdComplexType::wxsSuperType() const +{ + return m_superType; +} + +void XsdComplexType::setContext(const NamedSchemaComponent::Ptr &component) +{ + m_context = component; +} + +NamedSchemaComponent::Ptr XsdComplexType::context() const +{ + return m_context; +} + +void XsdComplexType::setContentType(const ContentType::Ptr &type) +{ + m_contentType = type; +} + +XsdComplexType::ContentType::Ptr XsdComplexType::contentType() const +{ + return m_contentType; +} + +void XsdComplexType::setAttributeUses(const XsdAttributeUse::List &attributeUses) +{ + m_attributeUses = attributeUses; +} + +void XsdComplexType::addAttributeUse(const XsdAttributeUse::Ptr &attributeUse) +{ + m_attributeUses.append(attributeUse); +} + +XsdAttributeUse::List XsdComplexType::attributeUses() const +{ + return m_attributeUses; +} + +void XsdComplexType::setAttributeWildcard(const XsdWildcard::Ptr &wildcard) +{ + m_attributeWildcard = wildcard; +} + +XsdWildcard::Ptr XsdComplexType::attributeWildcard() const +{ + return m_attributeWildcard; +} + +XsdComplexType::TypeCategory XsdComplexType::category() const +{ + return ComplexType; +} + +void XsdComplexType::setDerivationMethod(DerivationMethod method) +{ + m_derivationMethod = method; +} + +XsdComplexType::DerivationMethod XsdComplexType::derivationMethod() const +{ + return m_derivationMethod; +} + +void XsdComplexType::setProhibitedSubstitutions(const BlockingConstraints &substitutions) +{ + m_prohibitedSubstitutions = substitutions; +} + +XsdComplexType::BlockingConstraints XsdComplexType::prohibitedSubstitutions() const +{ + return m_prohibitedSubstitutions; +} + +void XsdComplexType::setAssertions(const XsdAssertion::List &assertions) +{ + m_assertions = assertions; +} + +void XsdComplexType::addAssertion(const XsdAssertion::Ptr &assertion) +{ + m_assertions.append(assertion); +} + +XsdAssertion::List XsdComplexType::assertions() const +{ + return m_assertions; +} + +bool XsdComplexType::isDefinedBySchema() const +{ + return true; +} + +QT_END_NAMESPACE diff --git a/src/xmlpatterns/schema/qxsdcomplextype_p.h b/src/xmlpatterns/schema/qxsdcomplextype_p.h new file mode 100644 index 0000000..078c8f0 --- /dev/null +++ b/src/xmlpatterns/schema/qxsdcomplextype_p.h @@ -0,0 +1,374 @@ +/**************************************************************************** +** +** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the $MODULE$ of the Qt Toolkit. +** +** $TROLLTECH_DUAL_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_XsdComplexType_H +#define Patternist_XsdComplexType_H + +#include "qanytype_p.h" +#include "qxsdassertion_p.h" +#include "qxsdattributeuse_p.h" +#include "qxsdparticle_p.h" +#include "qxsdsimpletype_p.h" +#include "qxsduserschematype_p.h" +#include "qxsdwildcard_p.h" + +#include + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +namespace QPatternist +{ + /** + * @short Represents a XSD complexType object. + * + * This class represents the complexType object of a XML schema as described + * here. + * + * It contains information from either a top-level complex type declaration (as child of a schema object) + * or a local complex type declaration (as descendant of an element object). + * + * @see XML Schema API reference + * @ingroup Patternist_schema + * @author Tobias Koenig + */ + class XsdComplexType : public XsdUserSchemaType + { + public: + typedef QExplicitlySharedDataPointer Ptr; + + /** + * @short Describes the open content object of a complex type. + * + * @see Open Content Definition + */ + class OpenContent : public QSharedData, public XsdAnnotated + { + public: + typedef QExplicitlySharedDataPointer Ptr; + + /** + * Describes the mode of the open content. + * + * @see Mode Definition + */ + enum Mode + { + None, + Interleave, + Suffix + }; + + /** + * Sets the @p mode of the open content. + * + * @see Mode Definition + */ + void setMode(Mode mode); + + /** + * Returns the mode of the open content. + */ + Mode mode() const; + + /** + * Sets the @p wildcard of the open content. + * + * @see Wildcard Definition + */ + void setWildcard(const XsdWildcard::Ptr &wildcard); + + /** + * Returns the wildcard of the open content. + */ + XsdWildcard::Ptr wildcard() const; + + private: + Mode m_mode; + XsdWildcard::Ptr m_wildcard; + }; + + /** + * @short Describes the content type of a complex type. + */ + class ContentType : public QSharedData + { + public: + typedef QExplicitlySharedDataPointer Ptr; + + /** + * Describes the variety of the content type. + */ + enum Variety + { + Empty = 0, ///< The complex type has no further content. + Simple, ///< The complex type has only simple type content (e.g. text, number etc.) + ElementOnly, ///< The complex type has further elements or attributes but no text as content. + Mixed ///< The complex type has further elements or attributes and text as content. + }; + + /** + * Sets the @p variety of the content type. + * + * @see Variety Definition + */ + void setVariety(Variety variety); + + /** + * Returns the variety of the content type. + */ + Variety variety() const; + + /** + * Sets the @p particle object of the content type. + * + * The content type has only a particle object if + * its variety is ElementOnly or Mixed. + * + * @see XsdParticle + * @see Particle Declaration + */ + void setParticle(const XsdParticle::Ptr &particle); + + /** + * Returns the particle object of the content type, + * or an empty pointer if its variety is neither + * ElementOnly nor Mixed. + */ + XsdParticle::Ptr particle() const; + + /** + * Sets the open @p content object of the content type. + * + * The content type has only an open content object if + * its variety is ElementOnly or Mixed. + * + * @see OpenContent + * @see Open Content Declaration + */ + void setOpenContent(const OpenContent::Ptr &content); + + /** + * Returns the open content object of the content type, + * or an empty pointer if its variety is neither + * ElementOnly nor Mixed. + */ + OpenContent::Ptr openContent() const; + + /** + * Sets the simple @p type object of the content type. + * + * The content type has only a simple type object if + * its variety is Simple. + * + * @see Simple Type Definition + */ + void setSimpleType(const AnySimpleType::Ptr &type); + + /** + * Returns the simple type object of the content type, + * or an empty pointer if its variety is not Simple. + */ + AnySimpleType::Ptr simpleType() const; + + private: + Variety m_variety; + XsdParticle::Ptr m_particle; + OpenContent::Ptr m_openContent; + XsdSimpleType::Ptr m_simpleType; + }; + + + /** + * Creates a complex type object with empty content. + */ + XsdComplexType(); + + /** + * Destroys the complex type object. + */ + ~XsdComplexType() {}; + + /** + * Returns the display name of the complex type. + * + * The display name can be used to show the type name + * to the user. + * + * @param namePool The name pool where the type name is stored in. + */ + virtual QString displayName(const NamePool::Ptr &namePool) const; + + /** + * Sets the base type of the complex type. + * + * @see Base Type Definition + */ + void setWxsSuperType(const SchemaType::Ptr &type); + + /** + * Returns the base type of the complex type. + */ + virtual SchemaType::Ptr wxsSuperType() const; + + /** + * Sets the context @p component of the complex type. + * + * The component is either an element declaration or a complex type definition. + */ + void setContext(const NamedSchemaComponent::Ptr &component); + + /** + * Returns the context component of the complex type. + */ + NamedSchemaComponent::Ptr context() const; + + /** + * Sets the derivation @p method of the complex type. + * + * The derivation method depends on whether the complex + * type object has an extension or restriction object as child. + * + * @see Derivation Method Definition + * @see DerivationMethod + */ + void setDerivationMethod(DerivationMethod method); + + /** + * Returns the derivation method of the complex type. + */ + virtual DerivationMethod derivationMethod() const; + + /** + * Sets whether the complex type is @p abstract. + * + * @see Abstract Definition + */ + void setIsAbstract(bool abstract); + + /** + * Returns whether the complex type is abstract. + */ + virtual bool isAbstract() const; + + /** + * Sets the list of all attribute @p uses of the complex type. + * + * @see Attribute Uses Declaration + */ + void setAttributeUses(const XsdAttributeUse::List &uses); + + /** + * Adds a new attribute @p use to the complex type. + */ + void addAttributeUse(const XsdAttributeUse::Ptr &use); + + /** + * Returns the list of all attribute uses of the complex type. + */ + XsdAttributeUse::List attributeUses() const; + + /** + * Sets the attribute @p wildcard of the complex type. + * + * @see Attribute Wildcard Declaration + */ + void setAttributeWildcard(const XsdWildcard::Ptr &wildcard); + + /** + * Returns the attribute wildcard of the complex type. + */ + XsdWildcard::Ptr attributeWildcard() const; + + /** + * Always returns SchemaType::ComplexType + */ + virtual TypeCategory category() const; + + /** + * Sets the content @p type of the complex type. + * + * @see ContentType + */ + void setContentType(const ContentType::Ptr &type); + + /** + * Returns the content type of the complex type. + */ + ContentType::Ptr contentType() const; + + /** + * Sets the prohibited @p substitutions of the complex type. + * + * Only ExtensionConstraint and RestrictionConstraint are allowed. + * + * @see Prohibited Substitutions Definition + */ + void setProhibitedSubstitutions(const BlockingConstraints &substitutions); + + /** + * Returns the prohibited substitutions of the complex type. + */ + BlockingConstraints prohibitedSubstitutions() const; + + /** + * Sets the @p assertions of the complex type. + * + * @see Assertions Definition + */ + void setAssertions(const XsdAssertion::List &assertions); + + /** + * Adds an @p assertion to the complex type. + * + * @see Assertions Definition + */ + void addAssertion(const XsdAssertion::Ptr &assertion); + + /** + * Returns the assertions of the complex type. + */ + XsdAssertion::List assertions() const; + + /** + * Always returns @c true. + */ + virtual bool isDefinedBySchema() const; + + private: + SchemaType::Ptr m_superType; + NamedSchemaComponent::Ptr m_context; + DerivationMethod m_derivationMethod; + bool m_isAbstract; + XsdAttributeUse::List m_attributeUses; + XsdWildcard::Ptr m_attributeWildcard; + ContentType::Ptr m_contentType; + BlockingConstraints m_prohibitedSubstitutions; + XsdAssertion::List m_assertions; + }; +} + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif diff --git a/src/xmlpatterns/schema/qxsddocumentation.cpp b/src/xmlpatterns/schema/qxsddocumentation.cpp new file mode 100644 index 0000000..4994143 --- /dev/null +++ b/src/xmlpatterns/schema/qxsddocumentation.cpp @@ -0,0 +1,56 @@ +/**************************************************************************** +** +** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the $MODULE$ of the Qt Toolkit. +** +** $TROLLTECH_DUAL_LICENSE$ +** +****************************************************************************/ + +#include "qxsddocumentation_p.h" + +QT_BEGIN_NAMESPACE + +using namespace QPatternist; + +XsdDocumentation::XsdDocumentation() +{ +} + +XsdDocumentation::~XsdDocumentation() +{ +} + +void XsdDocumentation::setSource(const AnyURI::Ptr &source) +{ + m_source = source; +} + +AnyURI::Ptr XsdDocumentation::source() const +{ + return m_source; +} + +void XsdDocumentation::setLanguage(const DerivedString::Ptr &language) +{ + m_language = language; +} + +DerivedString::Ptr XsdDocumentation::language() const +{ + return m_language; +} + +void XsdDocumentation::setContent(const QString &content) +{ + m_content = content; +} + +QString XsdDocumentation::content() const +{ + return m_content; +} + +QT_END_NAMESPACE diff --git a/src/xmlpatterns/schema/qxsddocumentation_p.h b/src/xmlpatterns/schema/qxsddocumentation_p.h new file mode 100644 index 0000000..c44a2bb --- /dev/null +++ b/src/xmlpatterns/schema/qxsddocumentation_p.h @@ -0,0 +1,107 @@ +/**************************************************************************** +** +** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the $MODULE$ of the Qt Toolkit. +** +** $TROLLTECH_DUAL_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_XsdDocumentation_H +#define Patternist_XsdDocumentation_H + +#include "qanytype_p.h" +#include "qanyuri_p.h" +#include "qderivedstring_p.h" +#include "qnamedschemacomponent_p.h" + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +namespace QPatternist +{ + /** + * @short Represents a XSD documentation object. + * + * This class represents the documentation component of an annotation object + * of a XML schema as described here. + * + * @ingroup Patternist_schema + * @author Tobias Koenig + */ + class XsdDocumentation : public NamedSchemaComponent + { + public: + typedef QExplicitlySharedDataPointer Ptr; + typedef QList List; + + /** + * Creates a new documentation object. + */ + XsdDocumentation(); + + /** + * Destroys the documentation object. + */ + ~XsdDocumentation(); + + /** + * Sets the @p source of the documentation. + * + * The source points to an URL that contains more + * information. + */ + void setSource(const AnyURI::Ptr &source); + + /** + * Returns the source of the documentation. + */ + AnyURI::Ptr source() const; + + /** + * Sets the @p language of the documentation. + */ + void setLanguage(const DerivedString::Ptr &language); + + /** + * Returns the language of the documentation. + */ + DerivedString::Ptr language() const; + + /** + * Sets the @p content of the documentation. + * + * The content can be of abritrary type. + */ + void setContent(const QString &content); + + /** + * Returns the content of the documentation. + */ + QString content() const; + + private: + AnyURI::Ptr m_source; + DerivedString::Ptr m_language; + QString m_content; + }; +} + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif diff --git a/src/xmlpatterns/schema/qxsdelement.cpp b/src/xmlpatterns/schema/qxsdelement.cpp new file mode 100644 index 0000000..2b8ccab --- /dev/null +++ b/src/xmlpatterns/schema/qxsdelement.cpp @@ -0,0 +1,214 @@ +/**************************************************************************** +** +** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the $MODULE$ of the Qt Toolkit. +** +** $TROLLTECH_DUAL_LICENSE$ +** +****************************************************************************/ + +#include "qxsdelement_p.h" + +QT_BEGIN_NAMESPACE + +using namespace QPatternist; + +void XsdElement::Scope::setVariety(Variety variety) +{ + m_variety = variety; +} + +XsdElement::Scope::Variety XsdElement::Scope::variety() const +{ + return m_variety; +} + +void XsdElement::Scope::setParent(const NamedSchemaComponent::Ptr &parent) +{ + m_parent = parent; +} + +NamedSchemaComponent::Ptr XsdElement::Scope::parent() const +{ + return m_parent; +} + +void XsdElement::ValueConstraint::setVariety(Variety variety) +{ + m_variety = variety; +} + +XsdElement::ValueConstraint::Variety XsdElement::ValueConstraint::variety() const +{ + return m_variety; +} + +void XsdElement::ValueConstraint::setValue(const QString &value) +{ + m_value = value; +} + +QString XsdElement::ValueConstraint::value() const +{ + return m_value; +} + +void XsdElement::ValueConstraint::setLexicalForm(const QString &form) +{ + m_lexicalForm = form; +} + +QString XsdElement::ValueConstraint::lexicalForm() const +{ + return m_lexicalForm; +} + +void XsdElement::TypeTable::addAlternative(const XsdAlternative::Ptr &alternative) +{ + m_alternatives.append(alternative); +} + +XsdAlternative::List XsdElement::TypeTable::alternatives() const +{ + return m_alternatives; +} + +void XsdElement::TypeTable::setDefaultTypeDefinition(const XsdAlternative::Ptr &type) +{ + m_defaultTypeDefinition = type; +} + +XsdAlternative::Ptr XsdElement::TypeTable::defaultTypeDefinition() const +{ + return m_defaultTypeDefinition; +} + + +XsdElement::XsdElement() + : m_isAbstract(false) +{ +} + +bool XsdElement::isElement() const +{ + return true; +} + +void XsdElement::setType(const SchemaType::Ptr &type) +{ + m_type = type; +} + +SchemaType::Ptr XsdElement::type() const +{ + return m_type; +} + +void XsdElement::setScope(const Scope::Ptr &scope) +{ + m_scope = scope; +} + +XsdElement::Scope::Ptr XsdElement::scope() const +{ + return m_scope; +} + +void XsdElement::setValueConstraint(const ValueConstraint::Ptr &constraint) +{ + m_valueConstraint = constraint; +} + +XsdElement::ValueConstraint::Ptr XsdElement::valueConstraint() const +{ + return m_valueConstraint; +} + +void XsdElement::setTypeTable(const TypeTable::Ptr &table) +{ + m_typeTable = table; +} + +XsdElement::TypeTable::Ptr XsdElement::typeTable() const +{ + return m_typeTable; +} + +void XsdElement::setIsAbstract(bool abstract) +{ + m_isAbstract = abstract; +} + +bool XsdElement::isAbstract() const +{ + return m_isAbstract; +} + +void XsdElement::setIsNillable(bool nillable) +{ + m_isNillable = nillable; +} + +bool XsdElement::isNillable() const +{ + return m_isNillable; +} + +void XsdElement::setDisallowedSubstitutions(const BlockingConstraints &substitutions) +{ + m_disallowedSubstitutions = substitutions; +} + +XsdElement::BlockingConstraints XsdElement::disallowedSubstitutions() const +{ + return m_disallowedSubstitutions; +} + +void XsdElement::setSubstitutionGroupExclusions(const SchemaType::DerivationConstraints &exclusions) +{ + m_substitutionGroupExclusions = exclusions; +} + +SchemaType::DerivationConstraints XsdElement::substitutionGroupExclusions() const +{ + return m_substitutionGroupExclusions; +} + +void XsdElement::setIdentityConstraints(const XsdIdentityConstraint::List &constraints) +{ + m_identityConstraints = constraints; +} + +void XsdElement::addIdentityConstraint(const XsdIdentityConstraint::Ptr &constraint) +{ + m_identityConstraints.append(constraint); +} + +XsdIdentityConstraint::List XsdElement::identityConstraints() const +{ + return m_identityConstraints; +} + +void XsdElement::setSubstitutionGroupAffiliations(const XsdElement::List &affiliations) +{ + m_substitutionGroupAffiliations = affiliations; +} + +XsdElement::List XsdElement::substitutionGroupAffiliations() const +{ + return m_substitutionGroupAffiliations; +} + +void XsdElement::addSubstitutionGroup(const XsdElement::Ptr &element) +{ + m_substitutionGroups.insert(element); +} + +XsdElement::List XsdElement::substitutionGroups() const +{ + return m_substitutionGroups.toList(); +} + +QT_END_NAMESPACE diff --git a/src/xmlpatterns/schema/qxsdelement_p.h b/src/xmlpatterns/schema/qxsdelement_p.h new file mode 100644 index 0000000..e571687 --- /dev/null +++ b/src/xmlpatterns/schema/qxsdelement_p.h @@ -0,0 +1,373 @@ +/**************************************************************************** +** +** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the $MODULE$ of the Qt Toolkit. +** +** $TROLLTECH_DUAL_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_XsdElement_H +#define Patternist_XsdElement_H + +#include "qschemacomponent_p.h" +#include "qschematype_p.h" +#include "qxsdalternative_p.h" +#include "qxsdidentityconstraint_p.h" +#include "qxsdcomplextype_p.h" + +#include +#include + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +namespace QPatternist +{ + /** + * @short Represents a XSD element object. + * + * This class represents the element object of a XML schema as described + * here. + * + * It contains information from either a top-level element declaration (as child of a schema object) + * or a local element declaration (as descendant of an complexType object). + * + * @see XML Schema API reference + * @ingroup Patternist_schema + * @author Tobias Koenig + */ + class XsdElement : public XsdTerm + { + public: + typedef QExplicitlySharedDataPointer Ptr; + typedef QList List; + + + /** + * Describes the constraint type of the element. + */ + enum ConstraintType + { + NoneConstraint, ///< The value of the element has no constraints. + DefaultConstraint, ///< The element has a default value set. + FixedConstraint ///< The element has a fixed value set. + }; + + /** + * Describes the scope of an element. + * + * @see Scope Definition + */ + class Scope : public QSharedData + { + public: + typedef QExplicitlySharedDataPointer Ptr; + + /** + * Describes the scope of an attribute. + */ + enum Variety + { + Global, ///< The element is defined globally as child of the schema object. + Local ///< The element is defined locally as child of a complex type or model group definition. + }; + + /** + * Sets the @p variety of the element scope. + */ + void setVariety(Variety variety); + + /** + * Returns the variety of the element scope. + */ + Variety variety() const; + + /** + * Sets the @p parent complex type or model group definition of the element scope. + */ + void setParent(const NamedSchemaComponent::Ptr &parent); + + /** + * Returns the parent complex type or model group definition of the element scope. + */ + NamedSchemaComponent::Ptr parent() const; + + private: + Variety m_variety; + NamedSchemaComponent::Ptr m_parent; + }; + + /** + * Describes a type table of an element. + * + * @see Type Table Definition + */ + class TypeTable : public QSharedData + { + public: + typedef QExplicitlySharedDataPointer Ptr; + + /** + * Adds an @p alternative to the type table. + */ + void addAlternative(const XsdAlternative::Ptr &alternative); + + /** + * Returns the alternatives of the type table. + */ + XsdAlternative::List alternatives() const; + + /** + * Sets the default @p type definition. + */ + void setDefaultTypeDefinition(const XsdAlternative::Ptr &type); + + /** + * Returns the default type definition. + */ + XsdAlternative::Ptr defaultTypeDefinition() const; + + private: + XsdAlternative::List m_alternatives; + XsdAlternative::Ptr m_defaultTypeDefinition; + }; + + + /** + * Describes the value constraint of an element. + * + * @see Value Constraint Definition + */ + class ValueConstraint : public QSharedData + { + public: + typedef QExplicitlySharedDataPointer Ptr; + + /** + * Describes the value constraint of an element. + */ + enum Variety + { + Default, ///< The element has a default value set. + Fixed ///< The element has a fixed value set. + }; + + /** + * Sets the @p variety of the element value constraint. + */ + void setVariety(Variety variety); + + /** + * Returns the variety of the element value constraint. + */ + Variety variety() const; + + /** + * Sets the @p value of the constraint. + */ + void setValue(const QString &value); + + /** + * Returns the value of the constraint. + */ + QString value() const; + + /** + * Sets the lexical @p form of the constraint. + */ + void setLexicalForm(const QString &form); + + /** + * Returns the lexical form of the constraint. + */ + QString lexicalForm() const; + + private: + Variety m_variety; + QString m_value; + QString m_lexicalForm; + }; + + /** + * Creates a new element object. + */ + XsdElement(); + + /** + * Always returns @c true, used to avoid dynamic casts. + */ + virtual bool isElement() const; + + /** + * Sets the @p type of the element. + * + * @see Type Definition + */ + void setType(const SchemaType::Ptr &type); + + /** + * Returns the type of the element. + */ + SchemaType::Ptr type() const; + + /** + * Sets the @p scope of the element. + * + * @see Scope Definition + */ + void setScope(const Scope::Ptr &scope); + + /** + * Returns the scope of the element. + */ + Scope::Ptr scope() const; + + /** + * Sets the value @p constraint of the element. + * + * @see Value Constraint Definition + */ + void setValueConstraint(const ValueConstraint::Ptr &constraint); + + /** + * Returns the value constraint of the element. + */ + ValueConstraint::Ptr valueConstraint() const; + + /** + * Sets the type table of the element. + * + * @see Type Table Definition + */ + void setTypeTable(const TypeTable::Ptr &table); + + /** + * Returns the type table of the element. + */ + TypeTable::Ptr typeTable() const; + + /** + * Sets whether the element is @p abstract. + * + * @see Abstract Definition + */ + void setIsAbstract(bool abstract); + + /** + * Returns whether the element is abstract. + */ + bool isAbstract() const; + + /** + * Sets whether the element is @p nillable. + * + * @see Nillable Definition + */ + void setIsNillable(bool nillable); + + /** + * Returns whether the element is nillable. + */ + bool isNillable() const; + + /** + * Sets the disallowed @p substitutions of the element. + * + * Only ExtensionConstraint, RestrictionConstraint and SubstitutionConstraint are allowed. + * + * @see Disallowed Substitutions Definition + */ + void setDisallowedSubstitutions(const BlockingConstraints &substitutions); + + /** + * Returns the disallowed substitutions of the element. + */ + BlockingConstraints disallowedSubstitutions() const; + + /** + * Sets the substitution group @p exclusions of the element. + * + * Only SchemaType::ExtensionConstraint and SchemaType::RestrictionConstraint are allowed. + * + * @see Substitution Group Exclusions Definition + */ + void setSubstitutionGroupExclusions(const SchemaType::DerivationConstraints &exclusions); + + /** + * Returns the substitution group exclusions of the element. + */ + SchemaType::DerivationConstraints substitutionGroupExclusions() const; + + /** + * Sets the identity @p constraints of the element. + * + * @see Identity Constraint Definition + */ + void setIdentityConstraints(const XsdIdentityConstraint::List &constraints); + + /** + * Adds a new identity @p constraint to the element. + */ + void addIdentityConstraint(const XsdIdentityConstraint::Ptr &constraint); + + /** + * Returns a list of all identity constraints of the element. + */ + XsdIdentityConstraint::List identityConstraints() const; + + /** + * Sets the substitution group @p affiliations of the element. + * + * @see Substitution Group Affiliations + */ + void setSubstitutionGroupAffiliations(const XsdElement::List &affiliations); + + /** + * Returns the substitution group affiliations of the element. + */ + XsdElement::List substitutionGroupAffiliations() const; + + /** + * Adds a substitution group to the element. + */ + void addSubstitutionGroup(const XsdElement::Ptr &elements); + + /** + * Returns the substitution groups of the element. + */ + XsdElement::List substitutionGroups() const; + + private: + SchemaType::Ptr m_type; + Scope::Ptr m_scope; + ValueConstraint::Ptr m_valueConstraint; + TypeTable::Ptr m_typeTable; + bool m_isAbstract; + bool m_isNillable; + BlockingConstraints m_disallowedSubstitutions; + SchemaType::DerivationConstraints m_substitutionGroupExclusions; + XsdIdentityConstraint::List m_identityConstraints; + XsdElement::List m_substitutionGroupAffiliations; + QSet m_substitutionGroups; + }; +} + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif diff --git a/src/xmlpatterns/schema/qxsdfacet.cpp b/src/xmlpatterns/schema/qxsdfacet.cpp new file mode 100644 index 0000000..513eee8 --- /dev/null +++ b/src/xmlpatterns/schema/qxsdfacet.cpp @@ -0,0 +1,94 @@ +/**************************************************************************** +** +** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the $MODULE$ of the Qt Toolkit. +** +** $TROLLTECH_DUAL_LICENSE$ +** +****************************************************************************/ + +#include "qxsdfacet_p.h" + +QT_BEGIN_NAMESPACE + +using namespace QPatternist; + +XsdFacet::XsdFacet() + : m_type(None) +{ +} + +void XsdFacet::setType(Type type) +{ + m_type = type; +} + +XsdFacet::Type XsdFacet::type() const +{ + return m_type; +} + +void XsdFacet::setValue(const AtomicValue::Ptr &value) +{ + m_value = value; +} + +AtomicValue::Ptr XsdFacet::value() const +{ + return m_value; +} + +void XsdFacet::setMultiValue(const AtomicValue::List &value) +{ + m_multiValue = value; +} + +AtomicValue::List XsdFacet::multiValue() const +{ + return m_multiValue; +} + +void XsdFacet::setAssertions(const XsdAssertion::List &assertions) +{ + m_assertions = assertions; +} + +XsdAssertion::List XsdFacet::assertions() const +{ + return m_assertions; +} + +void XsdFacet::setFixed(bool fixed) +{ + m_fixed = fixed; +} + +bool XsdFacet::fixed() const +{ + return m_fixed; +} + +QString XsdFacet::typeName(Type type) +{ + switch (type) { + case Length: return QLatin1String("length"); break; + case MinimumLength: return QLatin1String("minLength"); break; + case MaximumLength: return QLatin1String("maxLength"); break; + case Pattern: return QLatin1String("pattern"); break; + case WhiteSpace: return QLatin1String("whiteSpace"); break; + case MaximumInclusive: return QLatin1String("maxInclusive"); break; + case MaximumExclusive: return QLatin1String("maxExclusive"); break; + case MinimumInclusive: return QLatin1String("minInclusive"); break; + case MinimumExclusive: return QLatin1String("minExclusive"); break; + case TotalDigits: return QLatin1String("totalDigits"); break; + case FractionDigits: return QLatin1String("fractionDigits"); break; + case Enumeration: return QLatin1String("enumeration"); break; + case Assertion: return QLatin1String("assertion"); break; + case None: // fall through + default: return QLatin1String("none"); break; + } +} + +QT_END_NAMESPACE diff --git a/src/xmlpatterns/schema/qxsdfacet_p.h b/src/xmlpatterns/schema/qxsdfacet_p.h new file mode 100644 index 0000000..f1f8110 --- /dev/null +++ b/src/xmlpatterns/schema/qxsdfacet_p.h @@ -0,0 +1,183 @@ +/**************************************************************************** +** +** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the $MODULE$ of the Qt Toolkit. +** +** $TROLLTECH_DUAL_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_XsdFacet_H +#define Patternist_XsdFacet_H + +#include "qitem_p.h" +#include "qnamedschemacomponent_p.h" +#include "qxsdannotated_p.h" +#include "qxsdassertion_p.h" + +#include + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +namespace QPatternist +{ + /** + * @short Represents a XSD facet object. + * + * This class represents one of the following XML schema objects: + * + * + * + * @see XML Schema API reference + * @ingroup Patternist_schema + * @author Tobias Koenig + */ + class XsdFacet : public NamedSchemaComponent, public XsdAnnotated + { + public: + typedef QExplicitlySharedDataPointer Ptr; + + /** + * Describes the type of the facet. + */ + enum Type + { + None = 0, ///< An invalid facet. + Length = 1 << 0, ///< Match the exact length (Length Definition) + MinimumLength = 1 << 1, ///< Match the minimum length (Minimum Length Definition) + MaximumLength = 1 << 2, ///< Match the maximum length (Maximum Length Definition) + Pattern = 1 << 3, ///< Match a regular expression (Pattern Definition) + WhiteSpace = 1 << 4, ///< Match a whitespace rule (White Space Definition) + MaximumInclusive = 1 << 5, ///< Match a maximum inclusive (Maximum Inclusive Definition) + MaximumExclusive = 1 << 6, ///< Match a maximum exclusive (Maximum Exclusive Definition) + MinimumInclusive = 1 << 7, ///< Match a minimum inclusive (Minimum Inclusive Definition) + MinimumExclusive = 1 << 8, ///< Match a minimum exclusive (Minimum Exclusive Definition) + TotalDigits = 1 << 9, ///< Match some integer digits (Total Digits Definition) + FractionDigits = 1 << 10, ///< Match some double digits (Fraction Digits Definition) + Enumeration = 1 << 11, ///< Match an enumeration (Enumeration Definition) + Assertion = 1 << 12, ///< Match an assertion (Assertion Definition) + }; + typedef QHash Hash; + typedef QHashIterator HashIterator; + + /** + * Creates a new facet object of type None. + */ + XsdFacet(); + + /** + * Sets the @p type of the facet. + * + * @see Type + */ + void setType(Type type); + + /** + * Returns the type of the facet. + */ + Type type() const; + + /** + * Sets the @p value of the facet. + * + * Depending on the type of the facet the + * value can be a string, interger, double etc. + * + * @note This method should be used for all types of facets + * except Pattern, Enumeration and Assertion. + */ + void setValue(const AtomicValue::Ptr &value); + + /** + * Returns the value of the facet or an empty pointer if facet + * type is Pattern, Enumeration or Assertion. + */ + AtomicValue::Ptr value() const; + + /** + * Sets the @p value of the facet. + * + * @note This method should be used for if the type of the + * facet is Pattern or Enumeration. + */ + void setMultiValue(const AtomicValue::List &value); + + /** + * Returns the value of the facet or an empty pointer if facet + * type is not of type Pattern or Enumeration. + */ + AtomicValue::List multiValue() const; + + /** + * Sets the @p assertions of the facet. + * + * @note This method should be used if the type of the + * facet is Assertion. + */ + void setAssertions(const XsdAssertion::List &assertions); + + /** + * Returns the assertions of the facet or an empty pointer if facet + * type is not of type Assertion. + */ + XsdAssertion::List assertions() const; + + /** + * Sets whether the facet is @p fixed. + * + * All facets except pattern, enumeration and assertion can be fixed. + */ + void setFixed(bool fixed); + + /** + * Returns whether the facet is fixed. + */ + bool fixed() const; + + /** + * Returns the textual description of the facet @p type. + */ + static QString typeName(Type type); + + private: + Type m_type; + AtomicValue::Ptr m_value; + AtomicValue::List m_multiValue; + XsdAssertion::List m_assertions; + bool m_fixed; + }; +} + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif diff --git a/src/xmlpatterns/schema/qxsdidcache.cpp b/src/xmlpatterns/schema/qxsdidcache.cpp new file mode 100644 index 0000000..d4a7b64 --- /dev/null +++ b/src/xmlpatterns/schema/qxsdidcache.cpp @@ -0,0 +1,36 @@ +/**************************************************************************** +** +** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the $MODULE$ of the Qt Toolkit. +** +** $TROLLTECH_DUAL_LICENSE$ +** +****************************************************************************/ + +#include "qxsdidcache_p.h" + +#include +#include + +QT_BEGIN_NAMESPACE + +using namespace QPatternist; + +void XsdIdCache::addId(const QString &id) +{ + const QWriteLocker locker(&m_lock); + Q_ASSERT(!m_ids.contains(id)); + + m_ids.insert(id); +} + +bool XsdIdCache::hasId(const QString &id) const +{ + const QReadLocker locker(&m_lock); + + return m_ids.contains(id); +} + +QT_END_NAMESPACE diff --git a/src/xmlpatterns/schema/qxsdidcache_p.h b/src/xmlpatterns/schema/qxsdidcache_p.h new file mode 100644 index 0000000..b1d3c0f --- /dev/null +++ b/src/xmlpatterns/schema/qxsdidcache_p.h @@ -0,0 +1,69 @@ +/**************************************************************************** +** +** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the $MODULE$ of the Qt Toolkit. +** +** $TROLLTECH_DUAL_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_XsdIdCache_H +#define Patternist_XsdIdCache_H + +#include "qschemacomponent_p.h" + +#include +#include +#include +#include + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +namespace QPatternist +{ + /** + * @short Helper class for keeping track of all existing IDs in a schema. + * + * @ingroup Patternist_schema + * @author Tobias Koenig + */ + class XsdIdCache : public QSharedData + { + public: + typedef QExplicitlySharedDataPointer Ptr; + + /** + * Adds an @p id to the id cache. + */ + void addId(const QString &id); + + /** + * Returns whether the id cache contains the given @p id already. + */ + bool hasId(const QString &id) const; + + private: + QSet m_ids; + mutable QReadWriteLock m_lock; + }; +} + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif diff --git a/src/xmlpatterns/schema/qxsdidchelper.cpp b/src/xmlpatterns/schema/qxsdidchelper.cpp new file mode 100644 index 0000000..70980cb --- /dev/null +++ b/src/xmlpatterns/schema/qxsdidchelper.cpp @@ -0,0 +1,107 @@ +/**************************************************************************** +** +** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the $MODULE$ of the Qt Toolkit. +** +** $TROLLTECH_DUAL_LICENSE$ +** +****************************************************************************/ + +#include "qxsdidchelper_p.h" + +#include "qderivedstring_p.h" +#include "qxsdschemahelper_p.h" + +QT_BEGIN_NAMESPACE + +using namespace QPatternist; + +FieldNode::FieldNode() +{ +} + +FieldNode::FieldNode(const QXmlItem &item, const QString &data, const SchemaType::Ptr &type) + : m_item(item) + , m_data(data) + , m_type(type) +{ +} + +bool FieldNode::isEmpty() const +{ + return m_item.isNull(); +} + +bool FieldNode::isEqualTo(const FieldNode &other, const NamePool::Ptr &namePool, const ReportContext::Ptr &context, const SourceLocationReflection *const reflection) const +{ + if (m_type != other.m_type) + return false; + + const DerivedString::Ptr string = DerivedString::fromLexical(namePool, m_data); + const DerivedString::Ptr otherString = DerivedString::fromLexical(namePool, other.m_data); + + return XsdSchemaHelper::constructAndCompare(string, AtomicComparator::OperatorEqual, otherString, m_type, context, reflection); +} + +QXmlItem FieldNode::item() const +{ + return m_item; +} + +TargetNode::TargetNode(const QXmlItem &item) + : m_item(item) +{ +} + +QXmlItem TargetNode::item() const +{ + return m_item; +} + +QVector TargetNode::fieldItems() const +{ + QVector items; + + for (int i = 0; i < m_fields.count(); ++i) + items.append(m_fields.at(i).item()); + + return items; +} + +int TargetNode::emptyFieldsCount() const +{ + int counter = 0; + for (int i = 0; i < m_fields.count(); ++i) { + if (m_fields.at(i).isEmpty()) + ++counter; + } + + return counter; +} + +bool TargetNode::fieldsAreEqual(const TargetNode &other, const NamePool::Ptr &namePool, const ReportContext::Ptr &context, const SourceLocationReflection *const reflection) const +{ + if (m_fields.count() != other.m_fields.count()) + return false; + + for (int i = 0; i < m_fields.count(); ++i) { + if (!m_fields.at(i).isEqualTo(other.m_fields.at(i), namePool, context, reflection)) + return false; + } + + return true; +} + +void TargetNode::addField(const QXmlItem &item, const QString &data, const SchemaType::Ptr &type) +{ + m_fields.append(FieldNode(item, data, type)); +} + +bool TargetNode::operator==(const TargetNode &other) const +{ + return (m_item.toNodeModelIndex() == other.m_item.toNodeModelIndex()); +} + +QT_END_NAMESPACE diff --git a/src/xmlpatterns/schema/qxsdidchelper_p.h b/src/xmlpatterns/schema/qxsdidchelper_p.h new file mode 100644 index 0000000..3034292 --- /dev/null +++ b/src/xmlpatterns/schema/qxsdidchelper_p.h @@ -0,0 +1,156 @@ +/**************************************************************************** +** +** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the $MODULE$ of the Qt Toolkit. +** +** $TROLLTECH_DUAL_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_XsdIdcHelper_H +#define Patternist_XsdIdcHelper_H + +#include "qreportcontext_p.h" +#include "qschematype_p.h" + +#include + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +namespace QPatternist +{ + + /** + * @short A helper class for validating identity constraints. + * + * This class represents a field node from the key-sequence as defined in + * the validation rules at http://www.w3.org/TR/xmlschema11-1/#d0e32243. + */ + class FieldNode + { + public: + /** + * Creates an empty field node. + */ + FieldNode(); + + /** + * Creates a field node that is bound to a xml node. + * + * @param item The xml node the field is bound to. + * @param data The string content of that field. + * @param type The type that is bound to that field. + */ + FieldNode(const QXmlItem &item, const QString &data, const SchemaType::Ptr &type); + + /** + * Returns whether this field is empty. + * + * A field can be empty, if the xpath expression selects an absent attribute + * or element. + */ + bool isEmpty() const; + + /** + * Returns whether this field is equal to the @p other field. + * + * Equal means that both have the same type and there content is equal in the + * types value space. + */ + bool isEqualTo(const FieldNode &other, const NamePool::Ptr &namePool, const ReportContext::Ptr &context, const SourceLocationReflection *const reflection) const; + + /** + * Returns the xml node item the field is bound to. + */ + QXmlItem item() const; + + private: + QXmlItem m_item; + QString m_data; + SchemaType::Ptr m_type; + }; + + /** + * @short A helper class for validating identity constraints. + * + * This class represents a target or qualified node from the target or qualified + * node set as defined in the validation rules at http://www.w3.org/TR/xmlschema11-1/#d0e32243. + * + * A target node is part of the qualified node set, if all of its fields are not empty. + */ + class TargetNode + { + public: + /** + * Defines a set of target nodes. + */ + typedef QSet Set; + + /** + * Creates a new target node that is bound to the xml node @p item. + */ + explicit TargetNode(const QXmlItem &item); + + /** + * Returns the xml node item the target node is bound to. + */ + QXmlItem item() const; + + /** + * Returns all xml node items, the fields of that target node are bound to. + */ + QVector fieldItems() const; + + /** + * Returns the number of fields that are empty. + */ + int emptyFieldsCount() const; + + /** + * Returns whether the target node has the same fields as the @p other target node. + */ + bool fieldsAreEqual(const TargetNode &other, const NamePool::Ptr &namePool, const ReportContext::Ptr &context, const SourceLocationReflection *const reflection) const; + + /** + * Adds a new field to the target node with the given values. + */ + void addField(const QXmlItem &item, const QString &data, const SchemaType::Ptr &type); + + /** + * Returns whether the target node is equal to the @p other target node. + */ + bool operator==(const TargetNode &other) const; + + private: + QXmlItem m_item; + QVector m_fields; + }; + + /** + * Creates a hash value for the given target @p node. + */ + inline uint qHash(const QPatternist::TargetNode &node) + { + return qHash(node.item().toNodeModelIndex()); + } +} + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif diff --git a/src/xmlpatterns/schema/qxsdidentityconstraint.cpp b/src/xmlpatterns/schema/qxsdidentityconstraint.cpp new file mode 100644 index 0000000..e72a005 --- /dev/null +++ b/src/xmlpatterns/schema/qxsdidentityconstraint.cpp @@ -0,0 +1,63 @@ +/**************************************************************************** +** +** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the $MODULE$ of the Qt Toolkit. +** +** $TROLLTECH_DUAL_LICENSE$ +** +****************************************************************************/ + +#include "qxsdidentityconstraint_p.h" + +QT_BEGIN_NAMESPACE + +using namespace QPatternist; + +void XsdIdentityConstraint::setCategory(Category category) +{ + m_category = category; +} + +XsdIdentityConstraint::Category XsdIdentityConstraint::category() const +{ + return m_category; +} + +void XsdIdentityConstraint::setSelector(const XsdXPathExpression::Ptr &selector) +{ + m_selector = selector; +} + +XsdXPathExpression::Ptr XsdIdentityConstraint::selector() const +{ + return m_selector; +} + +void XsdIdentityConstraint::setFields(const XsdXPathExpression::List &fields) +{ + m_fields = fields; +} + +void XsdIdentityConstraint::addField(const XsdXPathExpression::Ptr &field) +{ + m_fields.append(field); +} + +XsdXPathExpression::List XsdIdentityConstraint::fields() const +{ + return m_fields; +} + +void XsdIdentityConstraint::setReferencedKey(const XsdIdentityConstraint::Ptr &referencedKey) +{ + m_referencedKey = referencedKey; +} + +XsdIdentityConstraint::Ptr XsdIdentityConstraint::referencedKey() const +{ + return m_referencedKey; +} + +QT_END_NAMESPACE diff --git a/src/xmlpatterns/schema/qxsdidentityconstraint_p.h b/src/xmlpatterns/schema/qxsdidentityconstraint_p.h new file mode 100644 index 0000000..6870b1e --- /dev/null +++ b/src/xmlpatterns/schema/qxsdidentityconstraint_p.h @@ -0,0 +1,143 @@ +/**************************************************************************** +** +** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the $MODULE$ of the Qt Toolkit. +** +** $TROLLTECH_DUAL_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_XsdIdentityConstraint_H +#define Patternist_XsdIdentityConstraint_H + +#include "qnamedschemacomponent_p.h" +#include "qxsdannotated_p.h" +#include "qxsdxpathexpression_p.h" + +#include + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +namespace QPatternist +{ + /** + * @short Represents a XSD identity constraint object. + * + * This class represents the identity constraint object of a XML schema as described + * here. + * + * It contains information from either a key object, a keyref object or an + * unique object. + * + * @see XML Schema API reference + * @ingroup Patternist_schema + * @author Tobias Koenig + */ + class XsdIdentityConstraint : public NamedSchemaComponent, public XsdAnnotated + { + public: + typedef QExplicitlySharedDataPointer Ptr; + typedef QList List; + + /** + * Describes the category of the identity constraint. + */ + enum Category + { + Key = 1, ///< The constraint is a key constraint + KeyReference, ///< The constraint is a keyref constraint + Unique ///< The constraint is an unique constraint + }; + + /** + * Sets the @p category of the identity constraint. + * + * @see Category + */ + void setCategory(Category category); + + /** + * Returns the category of the identity constraint. + */ + Category category() const; + + /** + * Sets the @p selector of the identity constraint. + * + * The selector is a restricted XPath 1.0 expression, + * that selects a set of nodes. + * + * @see + */ + void setSelector(const XsdXPathExpression::Ptr &selector); + + /** + * Returns the selector of the identity constraint. + */ + XsdXPathExpression::Ptr selector() const; + + /** + * Sets the @p fields of the identity constraint. + * + * Each field is a restricted XPath 1.0 expression, + * that selects a set of nodes. + * + * @see + */ + void setFields(const XsdXPathExpression::List &fields); + + /** + * Adds a new @p field to the identity constraint. + */ + void addField(const XsdXPathExpression::Ptr &field); + + /** + * Returns all fields of the identity constraint. + */ + XsdXPathExpression::List fields() const; + + /** + * Sets the referenced @p key of the identity constraint. + * + * The key points to a identity constraint of type Key or Unique. + * + * The identity constraint has only a referenced key if its + * type is KeyReference. + * + * @see + */ + void setReferencedKey(const XsdIdentityConstraint::Ptr &key); + + /** + * Returns the referenced key of the identity constraint or an empty + * pointer if its type is not KeyReference. + */ + XsdIdentityConstraint::Ptr referencedKey() const; + + private: + Category m_category; + XsdXPathExpression::Ptr m_selector; + XsdXPathExpression::List m_fields; + XsdIdentityConstraint::Ptr m_referencedKey; + }; +} + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif diff --git a/src/xmlpatterns/schema/qxsdinstancereader.cpp b/src/xmlpatterns/schema/qxsdinstancereader.cpp new file mode 100644 index 0000000..81c40c9 --- /dev/null +++ b/src/xmlpatterns/schema/qxsdinstancereader.cpp @@ -0,0 +1,166 @@ +/**************************************************************************** +** +** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the $MODULE$ of the Qt Toolkit. +** +** $TROLLTECH_DUAL_LICENSE$ +** +****************************************************************************/ + +#include "qxsdinstancereader_p.h" + +QT_BEGIN_NAMESPACE + +using namespace QPatternist; + +XsdInstanceReader::XsdInstanceReader(const QAbstractXmlNodeModel *model, const XsdSchemaContext::Ptr &context) + : m_context(context) + , m_model(model->iterate(model->root(QXmlNodeModelIndex()), QXmlNodeModelIndex::AxisChild)) +{ +} + +bool XsdInstanceReader::atEnd() const +{ + return (m_model.current() == AbstractXmlPullProvider::EndOfInput); +} + +void XsdInstanceReader::readNext() +{ + m_model.next(); + + if (m_model.current() == AbstractXmlPullProvider::StartElement) { + m_cachedAttributes = m_model.attributes(); + m_cachedAttributeItems = m_model.attributeItems(); + m_cachedSourceLocation = m_model.sourceLocation(); + m_cachedItem = QXmlItem(m_model.index()); + } +} + +bool XsdInstanceReader::isStartElement() const +{ + return (m_model.current() == AbstractXmlPullProvider::StartElement); +} + +bool XsdInstanceReader::isEndElement() const +{ + return (m_model.current() == AbstractXmlPullProvider::EndElement); +} + +bool XsdInstanceReader::hasChildText() const +{ + const QXmlNodeModelIndex index = m_model.index(); + QXmlNodeModelIndex::Iterator::Ptr it = index.model()->iterate(index, QXmlNodeModelIndex::AxisChild); + + QXmlNodeModelIndex currentIndex = it->next(); + while (!currentIndex.isNull()) { + if (currentIndex.kind() == QXmlNodeModelIndex::Text) + return true; + + currentIndex = it->next(); + } + + return false; +} + +bool XsdInstanceReader::hasChildElement() const +{ + const QXmlNodeModelIndex index = m_model.index(); + QXmlNodeModelIndex::Iterator::Ptr it = index.model()->iterate(index, QXmlNodeModelIndex::AxisChild); + + QXmlNodeModelIndex currentIndex = it->next(); + while (!currentIndex.isNull()) { + if (currentIndex.kind() == QXmlNodeModelIndex::Element) + return true; + + currentIndex = it->next(); + } + + return false; +} + +QXmlName XsdInstanceReader::name() const +{ + return m_model.name(); +} + +QXmlName XsdInstanceReader::convertToQName(const QString &name) const +{ + const int pos = name.indexOf(QLatin1Char(':')); + + QXmlName::PrefixCode prefixCode = 0; + QXmlName::NamespaceCode namespaceCode; + QXmlName::LocalNameCode localNameCode; + if (pos != -1) { + prefixCode = m_context->namePool()->allocatePrefix(name.left(pos)); + namespaceCode = m_cachedItem.toNodeModelIndex().namespaceForPrefix(prefixCode); + localNameCode = m_context->namePool()->allocateLocalName(name.mid(pos + 1)); + } else { + prefixCode = StandardPrefixes::empty; + namespaceCode = m_cachedItem.toNodeModelIndex().namespaceForPrefix(prefixCode); + if (namespaceCode == -1) + namespaceCode = StandardNamespaces::empty; + localNameCode = m_context->namePool()->allocateLocalName(name); + } + + return QXmlName(namespaceCode, localNameCode, prefixCode); +} + +bool XsdInstanceReader::hasAttribute(const QXmlName &name) const +{ + return m_cachedAttributes.contains(name); +} + +QString XsdInstanceReader::attribute(const QXmlName &name) const +{ + Q_ASSERT(m_cachedAttributes.contains(name)); + + return m_cachedAttributes.value(name); +} + +QSet XsdInstanceReader::attributeNames() const +{ + return m_cachedAttributes.keys().toSet(); +} + +QString XsdInstanceReader::text() const +{ + const QXmlNodeModelIndex index = m_model.index(); + QXmlNodeModelIndex::Iterator::Ptr it = index.model()->iterate(index, QXmlNodeModelIndex::AxisChild); + + QString result; + + QXmlNodeModelIndex currentIndex = it->next(); + while (!currentIndex.isNull()) { + if (currentIndex.kind() == QXmlNodeModelIndex::Text) { + result.append(Item(currentIndex).stringValue()); + } + + currentIndex = it->next(); + } + + return result; +} + +QXmlItem XsdInstanceReader::item() const +{ + return m_cachedItem; +} + +QXmlItem XsdInstanceReader::attributeItem(const QXmlName &name) const +{ + return m_cachedAttributeItems.value(name); +} + +QSourceLocation XsdInstanceReader::sourceLocation() const +{ + return m_cachedSourceLocation; +} + +QVector XsdInstanceReader::namespaceBindings(const QXmlNodeModelIndex &index) const +{ + return index.namespaceBindings(); +} + +QT_END_NAMESPACE diff --git a/src/xmlpatterns/schema/qxsdinstancereader_p.h b/src/xmlpatterns/schema/qxsdinstancereader_p.h new file mode 100644 index 0000000..9df02d6 --- /dev/null +++ b/src/xmlpatterns/schema/qxsdinstancereader_p.h @@ -0,0 +1,159 @@ +/**************************************************************************** +** +** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the $MODULE$ of the Qt Toolkit. +** +** $TROLLTECH_DUAL_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_XsdInstanceReader_H +#define Patternist_XsdInstanceReader_H + +#include "qabstractxmlnodemodel.h" +#include "qpullbridge_p.h" +#include "qxsdschemacontext_p.h" + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +namespace QPatternist +{ + /** + * @short The schema instance reader. + * + * This class reads in a xml instance document from a QAbstractXmlNodeModel + * and provides a QXmlStreamReader like interface with some additional context + * information. + * + * @ingroup Patternist_schema + * @author Tobias Koenig + */ + class XsdInstanceReader + { + public: + typedef QExplicitlySharedDataPointer Ptr; + + /** + * Creates a new instance reader that will read the data from + * the given @p model. + * + * @param model The model the data are read from. + * @param context The context that is used for error reporting etc. + */ + XsdInstanceReader(const QAbstractXmlNodeModel *model, const XsdSchemaContext::Ptr &context); + + protected: + /** + * Returns @c true if the end of the document is reached, @c false otherwise. + */ + bool atEnd() const; + + /** + * Reads the next node from the document. + */ + void readNext(); + + /** + * Returns whether the current node is a start element. + */ + bool isStartElement() const; + + /** + * Returns whether the current node is an end element. + */ + bool isEndElement() const; + + /** + * Returns whether the current node has a text node among its children. + */ + bool hasChildText() const; + + /** + * Returns whether the current node has an element node among its children. + */ + bool hasChildElement() const; + + /** + * Returns the name of the current node. + */ + QXmlName name() const; + + /** + * Returns whether the current node has an attribute with the given @p name. + */ + bool hasAttribute(const QXmlName &name) const; + + /** + * Returns the attribute with the given @p name of the current node. + */ + QString attribute(const QXmlName &name) const; + + /** + * Returns the list of attribute names of the current node. + */ + QSet attributeNames() const; + + /** + * Returns the concatenated text of all direct child text nodes. + */ + QString text() const; + + /** + * Converts a qualified name into a QXmlName according to the namespace + * mappings of the current node. + */ + QXmlName convertToQName(const QString &name) const; + + /** + * Returns a source location object for the current position. + */ + QSourceLocation sourceLocation() const; + + /** + * Returns the QXmlItem for the current position. + */ + QXmlItem item() const; + + /** + * Returns the QXmlItem for the attribute with the given @p name at the current position. + */ + QXmlItem attributeItem(const QXmlName &name) const; + + /** + * Returns the namespace bindings for the given node model @p index. + */ + QVector namespaceBindings(const QXmlNodeModelIndex &index) const; + + /** + * The shared schema context. + */ + XsdSchemaContext::Ptr m_context; + + private: + PullBridge m_model; + QHash m_cachedAttributes; + QHash m_cachedAttributeItems; + QSourceLocation m_cachedSourceLocation; + QXmlItem m_cachedItem; + }; +} + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif diff --git a/src/xmlpatterns/schema/qxsdmodelgroup.cpp b/src/xmlpatterns/schema/qxsdmodelgroup.cpp new file mode 100644 index 0000000..1245822 --- /dev/null +++ b/src/xmlpatterns/schema/qxsdmodelgroup.cpp @@ -0,0 +1,48 @@ +/**************************************************************************** +** +** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the $MODULE$ of the Qt Toolkit. +** +** $TROLLTECH_DUAL_LICENSE$ +** +****************************************************************************/ + +#include "qxsdmodelgroup_p.h" + +QT_BEGIN_NAMESPACE + +using namespace QPatternist; + +XsdModelGroup::XsdModelGroup() + : m_compositor(SequenceCompositor) +{ +} + +bool XsdModelGroup::isModelGroup() const +{ + return true; +} + +void XsdModelGroup::setCompositor(ModelCompositor compositor) +{ + m_compositor = compositor; +} + +XsdModelGroup::ModelCompositor XsdModelGroup::compositor() const +{ + return m_compositor; +} + +void XsdModelGroup::setParticles(const XsdParticle::List &particles) +{ + m_particles = particles; +} + +XsdParticle::List XsdModelGroup::particles() const +{ + return m_particles; +} + +QT_END_NAMESPACE diff --git a/src/xmlpatterns/schema/qxsdmodelgroup_p.h b/src/xmlpatterns/schema/qxsdmodelgroup_p.h new file mode 100644 index 0000000..b7b59ac --- /dev/null +++ b/src/xmlpatterns/schema/qxsdmodelgroup_p.h @@ -0,0 +1,109 @@ +/**************************************************************************** +** +** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the $MODULE$ of the Qt Toolkit. +** +** $TROLLTECH_DUAL_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_XsdModelGroup_H +#define Patternist_XsdModelGroup_H + +#include "qxsdparticle_p.h" +#include "qxsdterm_p.h" + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +template class QList; + +namespace QPatternist +{ + /** + * @short Represents a XSD model group object. + * + * This class represents the model group object of a XML schema as described + * here. + * + * It contains information from either a sequence object, a choice object or an + * all object. + * + * @see XML Schema API reference + * @ingroup Patternist_schema + * @author Tobias Koenig + */ + class XsdModelGroup : public XsdTerm + { + public: + typedef QExplicitlySharedDataPointer Ptr; + typedef QList List; + + /** + * Describes the compositor of the model group. + */ + enum ModelCompositor + { + SequenceCompositor, ///< The model group is a sequence. + ChoiceCompositor, ///< The model group is a choice. + AllCompositor ///< The model group contains elements only. + }; + + /** + * Creates a new model group object. + */ + XsdModelGroup(); + + /** + * Returns always @c true, used to avoid dynamic casts. + */ + virtual bool isModelGroup() const; + + /** + * Sets the @p compositor of the model group. + * + * @see ModelCompositor + */ + void setCompositor(ModelCompositor compositor); + + /** + * Returns the compositor of the model group. + */ + ModelCompositor compositor() const; + + /** + * Sets the list of @p particles of the model group. + * + * @see Particles Definition + */ + void setParticles(const XsdParticle::List &particles); + + /** + * Returns the list of particles of the model group. + */ + XsdParticle::List particles() const; + + private: + ModelCompositor m_compositor; + XsdParticle::List m_particles; + }; +} + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif diff --git a/src/xmlpatterns/schema/qxsdnotation.cpp b/src/xmlpatterns/schema/qxsdnotation.cpp new file mode 100644 index 0000000..cfa0cd3 --- /dev/null +++ b/src/xmlpatterns/schema/qxsdnotation.cpp @@ -0,0 +1,38 @@ +/**************************************************************************** +** +** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the $MODULE$ of the Qt Toolkit. +** +** $TROLLTECH_DUAL_LICENSE$ +** +****************************************************************************/ + +#include "qxsdnotation_p.h" + +QT_BEGIN_NAMESPACE + +using namespace QPatternist; + +void XsdNotation::setPublicId(const DerivedString::Ptr &id) +{ + m_publicId = id; +} + +DerivedString::Ptr XsdNotation::publicId() const +{ + return m_publicId; +} + +void XsdNotation::setSystemId(const AnyURI::Ptr &id) +{ + m_systemId = id; +} + +AnyURI::Ptr XsdNotation::systemId() const +{ + return m_systemId; +} + +QT_END_NAMESPACE diff --git a/src/xmlpatterns/schema/qxsdnotation_p.h b/src/xmlpatterns/schema/qxsdnotation_p.h new file mode 100644 index 0000000..dc1d597 --- /dev/null +++ b/src/xmlpatterns/schema/qxsdnotation_p.h @@ -0,0 +1,89 @@ +/**************************************************************************** +** +** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the $MODULE$ of the Qt Toolkit. +** +** $TROLLTECH_DUAL_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_XsdNotation_H +#define Patternist_XsdNotation_H + +#include "qanyuri_p.h" +#include "qderivedstring_p.h" +#include "qnamedschemacomponent_p.h" +#include "qxsdannotated_p.h" + +#include + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +namespace QPatternist +{ + /** + * @short Represents a XSD notation object, which should not + * be confused with the atomic type @c xs:NOTATION. + * + * This class represents the notation object of a XML schema as described + * here. + * + * @see XML Schema API reference + * @ingroup Patternist_schema + * @author Tobias Koenig + */ + class XsdNotation : public NamedSchemaComponent, public XsdAnnotated + { + public: + typedef QExplicitlySharedDataPointer Ptr; + typedef QList List; + + /** + * Sets the public @p identifier of the notation. + * + * @see Public Identifier Definition + */ + void setPublicId(const DerivedString::Ptr &identifier); + + /** + * Returns the public identifier of the notation. + */ + DerivedString::Ptr publicId() const; + + /** + * Sets the system @p identifier of the notation. + * + * @see System Identifier Definition + */ + void setSystemId(const AnyURI::Ptr &identifier); + + /** + * Returns the system identifier of the notation. + */ + AnyURI::Ptr systemId() const; + + private: + DerivedString::Ptr m_publicId; + AnyURI::Ptr m_systemId; + }; +} + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif diff --git a/src/xmlpatterns/schema/qxsdparticle.cpp b/src/xmlpatterns/schema/qxsdparticle.cpp new file mode 100644 index 0000000..a2671fa --- /dev/null +++ b/src/xmlpatterns/schema/qxsdparticle.cpp @@ -0,0 +1,65 @@ +/**************************************************************************** +** +** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the $MODULE$ of the Qt Toolkit. +** +** $TROLLTECH_DUAL_LICENSE$ +** +****************************************************************************/ + +#include "qxsdparticle_p.h" + +QT_BEGIN_NAMESPACE + +using namespace QPatternist; + +XsdParticle::XsdParticle() + : m_minimumOccurs(1) + , m_maximumOccurs(1) + , m_maximumOccursUnbounded(false) +{ +} + +void XsdParticle::setMinimumOccurs(unsigned int occurs) +{ + m_minimumOccurs = occurs; +} + +unsigned int XsdParticle::minimumOccurs() const +{ + return m_minimumOccurs; +} + +void XsdParticle::setMaximumOccurs(unsigned int occurs) +{ + m_maximumOccurs = occurs; +} + +unsigned int XsdParticle::maximumOccurs() const +{ + return m_maximumOccurs; +} + +void XsdParticle::setMaximumOccursUnbounded(bool unbounded) +{ + m_maximumOccursUnbounded = unbounded; +} + +bool XsdParticle::maximumOccursUnbounded() const +{ + return m_maximumOccursUnbounded; +} + +void XsdParticle::setTerm(const XsdTerm::Ptr &term) +{ + m_term = term; +} + +XsdTerm::Ptr XsdParticle::term() const +{ + return m_term; +} + +QT_END_NAMESPACE diff --git a/src/xmlpatterns/schema/qxsdparticle_p.h b/src/xmlpatterns/schema/qxsdparticle_p.h new file mode 100644 index 0000000..61e3eb3 --- /dev/null +++ b/src/xmlpatterns/schema/qxsdparticle_p.h @@ -0,0 +1,124 @@ +/**************************************************************************** +** +** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the $MODULE$ of the Qt Toolkit. +** +** $TROLLTECH_DUAL_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_XsdParticle_H +#define Patternist_XsdParticle_H + +#include "qnamedschemacomponent_p.h" +#include "qxsdterm_p.h" + +#include + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +namespace QPatternist +{ + /** + * @short Represents a XSD particle object. + * + * This class represents the particle object of a XML schema as described + * here. + * + * It contains information about the number of occurrence and a reference to + * either an element object, a group object or an any object. + * + * @see XML Schema API reference + * @ingroup Patternist_schema + * @author Tobias Koenig + */ + class XsdParticle : public NamedSchemaComponent + { + public: + typedef QExplicitlySharedDataPointer Ptr; + typedef QList List; + + /** + * Creates a new particle object. + */ + XsdParticle(); + + /** + * Sets the minimum @p occurrence of the particle. + * + * @see Minimum Occurrence Definition + */ + void setMinimumOccurs(unsigned int occurrence); + + /** + * Returns the minimum occurrence of the particle. + */ + unsigned int minimumOccurs() const; + + /** + * Sets the maximum @p occurrence of the particle. + * + * @see Maximum Occurrence Definition + */ + void setMaximumOccurs(unsigned int occurrence); + + /** + * Returns the maximum occurrence of the particle. + * + * @note This value has only a meaning if maximumOccursUnbounded is @c false. + */ + unsigned int maximumOccurs() const; + + /** + * Sets whether the maximum occurrence of the particle is unbounded. + * + * @see Maximum Occurrence Definition + */ + void setMaximumOccursUnbounded(bool unbounded); + + /** + * Returns whether the maximum occurrence of the particle is unbounded. + */ + bool maximumOccursUnbounded() const; + + /** + * Sets the @p term of the particle. + * + * The term can be an element, a model group or an element wildcard. + * + * @see Term Definition + */ + void setTerm(const XsdTerm::Ptr &term); + + /** + * Returns the term of the particle. + */ + XsdTerm::Ptr term() const; + + private: + unsigned int m_minimumOccurs; + unsigned int m_maximumOccurs; + bool m_maximumOccursUnbounded; + XsdTerm::Ptr m_term; + }; +} + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif diff --git a/src/xmlpatterns/schema/qxsdparticlechecker.cpp b/src/xmlpatterns/schema/qxsdparticlechecker.cpp new file mode 100644 index 0000000..1bdef00 --- /dev/null +++ b/src/xmlpatterns/schema/qxsdparticlechecker.cpp @@ -0,0 +1,510 @@ +/**************************************************************************** +** +** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the $MODULE$ of the Qt Toolkit. +** +** $TROLLTECH_DUAL_LICENSE$ +** +****************************************************************************/ + +#include "qxsdparticlechecker_p.h" + +#include "qxsdelement_p.h" +#include "qxsdmodelgroup_p.h" +#include "qxsdschemahelper_p.h" +#include "qxsdstatemachine_p.h" +#include "qxsdstatemachinebuilder_p.h" +#include "qxsdtypechecker_p.h" + +#include + +QT_BEGIN_NAMESPACE + +using namespace QPatternist; + +namespace QPatternist +{ + /** + * This template specialization is picked up by XsdStateMachine and allows us + * to print nice edge labels. + */ + template <> + QString XsdStateMachine::transitionTypeToString(XsdTerm::Ptr term) const + { + if (!term) + return QLatin1String("(empty)"); + + if (term->isElement()) { + return XsdElement::Ptr(term)->displayName(m_namePool); + } else if (term->isWildcard()) { + const XsdWildcard::Ptr wildcard(term); + return QLatin1String("(wildcard)"); + } else { + return QString(); + } + } +} + +/** + * This method is used by the isUPAConform method to check whether @p term and @p otherTerm + * are the same resp. match each other. + */ +static bool termMatches(const XsdTerm::Ptr &term, const XsdTerm::Ptr &otherTerm, const NamePool::Ptr &namePool) +{ + if (term->isElement()) { + const XsdElement::Ptr element(term); + + if (otherTerm->isElement()) { + // both, the term and the other term are elements + + const XsdElement::Ptr otherElement(otherTerm); + + // if they have the same name they match + if (element->name(namePool) == otherElement->name(namePool)) + return true; + + } else if (otherTerm->isWildcard()) { + // the term is an element and the other term a wildcard + + const XsdWildcard::Ptr wildcard(otherTerm); + + // wildcards using XsdWildcard::absentNamespace, so we have to fix that here + QXmlName name = element->name(namePool); + if (name.namespaceURI() == StandardNamespaces::empty) + name.setNamespaceURI(namePool->allocateNamespace(XsdWildcard::absentNamespace())); + + // if the wildcards namespace constraint allows the elements name, they match + if (XsdSchemaHelper::wildcardAllowsExpandedName(name, wildcard, namePool)) + return true; + } + } else if (term->isWildcard()) { + const XsdWildcard::Ptr wildcard(term); + + if (otherTerm->isElement()) { + // the term is a wildcard and the other term an element + + const XsdElement::Ptr otherElement(otherTerm); + + // wildcards using XsdWildcard::absentNamespace, so we have to fix that here + QXmlName name = otherElement->name(namePool); + if (name.namespaceURI() == StandardNamespaces::empty) + name.setNamespaceURI(namePool->allocateNamespace(XsdWildcard::absentNamespace())); + + // if the wildcards namespace constraint allows the elements name, they match + if (XsdSchemaHelper::wildcardAllowsExpandedName(name, wildcard, namePool)) + return true; + + } else if (otherTerm->isWildcard()) { + // both, the term and the other term are wildcards + + const XsdWildcard::Ptr otherWildcard(otherTerm); + + // check if the range of the wildcard overlaps. + const XsdWildcard::Ptr intersectionWildcard = XsdSchemaHelper::wildcardIntersection(wildcard, otherWildcard); + if (!intersectionWildcard || + (intersectionWildcard && !(intersectionWildcard->namespaceConstraint()->variety() != XsdWildcard::NamespaceConstraint::Not && intersectionWildcard->namespaceConstraint()->namespaces().isEmpty()))) + return true; + } + } + + return false; +} + +/** + * This method is used by the subsumes algorithm to check whether the @p derivedTerm is validly derived from the @p baseTerm. + * + * @param baseTerm The term of the base component (type or group). + * @param derivedTerm The term of the derived component (type or group). + * @param particles A hash to map the passed base and derived term to the particles they belong to. + * @param context The schema context. + * @param errorMsg The error message in the case that an error occurs. + */ +static bool derivedTermValid(const XsdTerm::Ptr &baseTerm, const XsdTerm::Ptr &derivedTerm, const QHash &particles, const XsdSchemaContext::Ptr &context, QString &errorMsg) +{ + const NamePool::Ptr namePool(context->namePool()); + + // find the particles where the base and derived term belongs to + const XsdParticle::Ptr baseParticle = particles.value(baseTerm); + const XsdParticle::Ptr derivedParticle = particles.value(derivedTerm); + + // check that an empty particle can not be derived from a non-empty particle + if (derivedParticle && baseParticle) { + if (XsdSchemaHelper::isParticleEmptiable(derivedParticle) && !XsdSchemaHelper::isParticleEmptiable(baseParticle)) { + errorMsg = QtXmlPatterns::tr("empty particle cannot be derived from non-empty particle"); + return false; + } + } + + if (baseTerm->isElement()) { + const XsdElement::Ptr element(baseTerm); + + if (derivedTerm->isElement()) { + // if both terms are elements + + const XsdElement::Ptr derivedElement(derivedTerm); + + // check names are equal + if (element->name(namePool) != derivedElement->name(namePool)) { + errorMsg = QtXmlPatterns::tr("derived particle is missing element %1").arg(formatKeyword(element->displayName(namePool))); + return false; + } + + // check value constraints are equal (if available) + if (element->valueConstraint() && element->valueConstraint()->variety() == XsdElement::ValueConstraint::Fixed) { + if (!derivedElement->valueConstraint()) { + errorMsg = QtXmlPatterns::tr("derived element %1 is missing value constraint as defined in base particle").arg(formatKeyword(derivedElement->displayName(namePool))); + return false; + } + + if (derivedElement->valueConstraint()->variety() != XsdElement::ValueConstraint::Fixed) { + errorMsg = QtXmlPatterns::tr("derived element %1 has weaker value constraint than base particle").arg(formatKeyword(derivedElement->displayName(namePool))); + return false; + } + + const QSourceLocation dummyLocation(QUrl(QLatin1String("http://dummy.org")), 1, 1); + const XsdTypeChecker checker(context, QVector(), dummyLocation); + if (!checker.valuesAreEqual(element->valueConstraint()->value(), derivedElement->valueConstraint()->value(), derivedElement->type())) { + errorMsg = QtXmlPatterns::tr("fixed value constraint of element %1 differs from value constraint in base particle").arg(formatKeyword(derivedElement->displayName(namePool))); + return false; + } + } + + // check that a derived element can not be nillable if the base element is not nillable + if (!element->isNillable() && derivedElement->isNillable()) { + errorMsg = QtXmlPatterns::tr("derived element %1 cannot be nillable as base element is not nillable").arg(formatKeyword(derivedElement->displayName(namePool))); + return false; + } + + // check that the constraints of the derived element are more strict then the constraints of the base element + const XsdElement::BlockingConstraints baseConstraints = element->disallowedSubstitutions(); + const XsdElement::BlockingConstraints derivedConstraints = derivedElement->disallowedSubstitutions(); + if ((baseConstraints & XsdElement::RestrictionConstraint) && !(derivedConstraints & XsdElement::RestrictionConstraint) || + (baseConstraints & XsdElement::ExtensionConstraint) && !(derivedConstraints & XsdElement::ExtensionConstraint) || + (baseConstraints & XsdElement::SubstitutionConstraint) && !(derivedConstraints & XsdElement::SubstitutionConstraint)) { + errorMsg = QtXmlPatterns::tr("block constraints of derived element %1 must not be more weaker than in the base element").arg(formatKeyword(derivedElement->displayName(namePool))); + return false; + } + + // if the type of both elements is the same we can stop testing here + if (element->type()->name(namePool) == derivedElement->type()->name(namePool)) + return true; + + // check that the type of the derived element can validly derived from the type of the base element + if (derivedElement->type()->isSimpleType()) { + if (!XsdSchemaHelper::isSimpleDerivationOk(derivedElement->type(), element->type(), SchemaType::DerivationConstraints())) { + errorMsg = QtXmlPatterns::tr("simple type of derived element %1 cannot be validly derived from base element").arg(formatKeyword(derivedElement->displayName(namePool))); + return false; + } + } else if (derivedElement->type()->isComplexType()) { + if (!XsdSchemaHelper::isComplexDerivationOk(derivedElement->type(), element->type(), SchemaType::DerivationConstraints())) { + errorMsg = QtXmlPatterns::tr("complex type of derived element %1 cannot be validly derived from base element").arg(formatKeyword(derivedElement->displayName(namePool))); + return false; + } + } + + // if both, derived and base element, have a complex type that contains a particle itself, apply the subsumes algorithm + // recursive on their particles + if (element->type()->isComplexType() && derivedElement->type()->isComplexType()) { + if (element->type()->isDefinedBySchema() && derivedElement->type()->isDefinedBySchema()) { + const XsdComplexType::Ptr baseType(element->type()); + const XsdComplexType::Ptr derivedType(derivedElement->type()); + if ((baseType->contentType()->variety() == XsdComplexType::ContentType::ElementOnly || + baseType->contentType()->variety() == XsdComplexType::ContentType::Mixed) && + (derivedType->contentType()->variety() == XsdComplexType::ContentType::ElementOnly || + derivedType->contentType()->variety() == XsdComplexType::ContentType::Mixed)) { + + return XsdParticleChecker::subsumes(baseType->contentType()->particle(), derivedType->contentType()->particle(), context, errorMsg); + } + } + } + + return true; + } else if (derivedTerm->isWildcard()) { + // derive a wildcard from an element is not allowed + errorMsg = QtXmlPatterns::tr("element %1 is missing in derived particle").arg(formatKeyword(element->displayName(namePool))); + return false; + } + } else if (baseTerm->isWildcard()) { + const XsdWildcard::Ptr wildcard(baseTerm); + + if (derivedTerm->isElement()) { + // the base term is a wildcard and derived term an element + + const XsdElement::Ptr derivedElement(derivedTerm); + + // wildcards using XsdWildcard::absentNamespace, so we have to fix that here + QXmlName name = derivedElement->name(namePool); + if (name.namespaceURI() == StandardNamespaces::empty) + name.setNamespaceURI(namePool->allocateNamespace(XsdWildcard::absentNamespace())); + + // check that name of the element is allowed by the wildcards namespace constraint + if (!XsdSchemaHelper::wildcardAllowsExpandedName(name, wildcard, namePool)) { + errorMsg = QtXmlPatterns::tr("element %1 does not match namespace constraint of wildcard in base particle").arg(formatKeyword(derivedElement->displayName(namePool))); + return false; + } + + } else if (derivedTerm->isWildcard()) { + // both, derived and base term are wildcards + + const XsdWildcard::Ptr derivedWildcard(derivedTerm); + + // check that the derived wildcard is a valid subset of the base wildcard + if (!XsdSchemaHelper::isWildcardSubset(derivedWildcard, wildcard)) { + errorMsg = QtXmlPatterns::tr("wildcard in derived particle is not a valid subset of wildcard in base particle"); + return false; + } + + if (!XsdSchemaHelper::checkWildcardProcessContents(wildcard, derivedWildcard)) { + errorMsg = QtXmlPatterns::tr("processContent of wildcard in derived particle is weaker than wildcard in base particle"); + return false; + } + } + + return true; + } + + return false; +} + +typedef QHash ElementHash; + +/** + * Internal helper method that checks if the given @p particle contains an element with the + * same name and type twice. + */ +static bool hasDuplicatedElementsInternal(const XsdParticle::Ptr &particle, const NamePool::Ptr &namePool, ElementHash &hash, XsdElement::Ptr &conflictingElement) +{ + const XsdTerm::Ptr term = particle->term(); + if (term->isElement()) { + const XsdElement::Ptr mainElement(term); + XsdElement::List substGroups = mainElement->substitutionGroups(); + if (substGroups.isEmpty()) + substGroups << mainElement; + + for (int i = 0; i < substGroups.count(); ++i) { + const XsdElement::Ptr element = substGroups.at(i); + if (hash.contains(element->name(namePool))) { + if (element->type()->name(namePool) != hash.value(element->name(namePool))->type()->name(namePool)) { + conflictingElement = element; + return true; + } + } else { + hash.insert(element->name(namePool), element); + } + } + } else if (term->isModelGroup()) { + const XsdModelGroup::Ptr group(term); + const XsdParticle::List particles = group->particles(); + for (int i = 0; i < particles.count(); ++i) { + if (hasDuplicatedElementsInternal(particles.at(i), namePool, hash, conflictingElement)) + return true; + } + } + + return false; +} + +bool XsdParticleChecker::hasDuplicatedElements(const XsdParticle::Ptr &particle, const NamePool::Ptr &namePool, XsdElement::Ptr &conflictingElement) +{ + ElementHash hash; + return hasDuplicatedElementsInternal(particle, namePool, hash, conflictingElement); +} + +bool XsdParticleChecker::isUPAConform(const XsdParticle::Ptr &particle, const NamePool::Ptr &namePool) +{ + /** + * The algorithm is implemented like described in http://www.ltg.ed.ac.uk/~ht/XML_Europe_2003.html#S2.2 + */ + + // create a state machine for the given particle + XsdStateMachine stateMachine(namePool); + + XsdStateMachineBuilder builder(&stateMachine, namePool); + const XsdStateMachine::StateId endState = builder.reset(); + const XsdStateMachine::StateId startState = builder.buildParticle(particle, endState); + builder.addStartState(startState); + +/* + static int counter = 0; + { + QFile file(QString("/tmp/file_upa%1.dot").arg(counter)); + file.open(QIODevice::WriteOnly); + stateMachine.outputGraph(&file, "Base"); + file.close(); + } + ::system(QString("dot -Tpng /tmp/file_upa%1.dot -o/tmp/file_upa%1.png").arg(counter).toLatin1().data()); +*/ + const XsdStateMachine dfa = stateMachine.toDFA(); +/* + { + QFile file(QString("/tmp/file_upa%1dfa.dot").arg(counter)); + file.open(QIODevice::WriteOnly); + dfa.outputGraph(&file, "Base"); + file.close(); + } + ::system(QString("dot -Tpng /tmp/file_upa%1dfa.dot -o/tmp/file_upa%1dfa.png").arg(counter).toLatin1().data()); +*/ + const QHash::StateId, XsdStateMachine::StateType> states = dfa.states(); + const QHash::StateId, QHash::StateId> > > transitions = dfa.transitions(); + + // the basic idea of that algorithm is to iterate over all states of that machine and check that no two edges + // that match on the same term leave a state, so for a given term it should always be obvious which edge to take + QHashIterator::StateId, XsdStateMachine::StateType> stateIt(states); + while (stateIt.hasNext()) { // iterate over all states + stateIt.next(); + + // fetch all transitions the current state allows + const QHash::StateId> > currentTransitions = transitions.value(stateIt.key()); + QHashIterator::StateId> > transitionIt(currentTransitions); + while (transitionIt.hasNext()) { // iterate over all transitions + transitionIt.next(); + + if (transitionIt.value().size() > 1) { + // we have one state with two edges leaving it, that means + // the XsdTerm::Ptr exists twice, that is an error + return false; + } + + QHashIterator::StateId> > innerTransitionIt(currentTransitions); + while (innerTransitionIt.hasNext()) { // iterate over all transitions again, as we have to compare all transitions with all + innerTransitionIt.next(); + + if (transitionIt.key() == innerTransitionIt.key()) // do no compare with ourself + continue; + + // use the helper method termMatches to check if both term matches + if (termMatches(transitionIt.key(), innerTransitionIt.key(), namePool)) + return false; + } + } + } + + return true; +} + +bool XsdParticleChecker::subsumes(const XsdParticle::Ptr &particle, const XsdParticle::Ptr &derivedParticle, const XsdSchemaContext::Ptr &context, QString &errorMsg) +{ + /** + * The algorithm is implemented like described in http://www.ltg.ed.ac.uk/~ht/XML_Europe_2003.html#S2.3 + */ + + const NamePool::Ptr namePool(context->namePool()); + + XsdStateMachine baseStateMachine(namePool); + XsdStateMachine derivedStateMachine(namePool); + + // build up state machines for both particles + { + XsdStateMachineBuilder builder(&baseStateMachine, namePool); + const XsdStateMachine::StateId endState = builder.reset(); + const XsdStateMachine::StateId startState = builder.buildParticle(particle, endState); + builder.addStartState(startState); + + baseStateMachine = baseStateMachine.toDFA(); + } + { + XsdStateMachineBuilder builder(&derivedStateMachine, namePool); + const XsdStateMachine::StateId endState = builder.reset(); + const XsdStateMachine::StateId startState = builder.buildParticle(derivedParticle, endState); + builder.addStartState(startState); + + derivedStateMachine = derivedStateMachine.toDFA(); + } + + QHash particlesHash = XsdStateMachineBuilder::particleLookupMap(particle); + particlesHash.unite(XsdStateMachineBuilder::particleLookupMap(derivedParticle)); + +/* + static int counter = 0; + { + QFile file(QString("/tmp/file_base%1.dot").arg(counter)); + file.open(QIODevice::WriteOnly); + baseStateMachine.outputGraph(&file, QLatin1String("Base")); + file.close(); + } + { + QFile file(QString("/tmp/file_derived%1.dot").arg(counter)); + file.open(QIODevice::WriteOnly); + derivedStateMachine.outputGraph(&file, QLatin1String("Base")); + file.close(); + } + ::system(QString("dot -Tpng /tmp/file_base%1.dot -o/tmp/file_base%1.png").arg(counter).toLatin1().data()); + ::system(QString("dot -Tpng /tmp/file_derived%1.dot -o/tmp/file_derived%1.png").arg(counter).toLatin1().data()); +*/ + + const XsdStateMachine::StateId baseStartState = baseStateMachine.startState(); + const QHash::StateId, XsdStateMachine::StateType> baseStates = baseStateMachine.states(); + const QHash::StateId, QHash::StateId> > > baseTransitions = baseStateMachine.transitions(); + + const XsdStateMachine::StateId derivedStartState = derivedStateMachine.startState(); + const QHash::StateId, XsdStateMachine::StateType> derivedStates = derivedStateMachine.states(); + const QHash::StateId, QHash::StateId> > > derivedTransitions = derivedStateMachine.transitions(); + + // @see http://www.ltg.ed.ac.uk/~ht/XML_Europe_2003.html#S2.3.1 + + // define working set + QList::StateId, XsdStateMachine::StateId> > workSet; + QList::StateId, XsdStateMachine::StateId> > processedSet; + + // 1) fill working set initially with start states + workSet.append(qMakePair::StateId, XsdStateMachine::StateId>(baseStartState, derivedStartState)); + processedSet.append(qMakePair::StateId, XsdStateMachine::StateId>(baseStartState, derivedStartState)); + + while (!workSet.isEmpty()) { // while there are state sets to process + + // 3) dequeue on state set + const QPair::StateId, XsdStateMachine::StateId> set = workSet.takeFirst(); + + const QHash::StateId> > derivedTrans = derivedTransitions.value(set.second); + QHashIterator::StateId> > derivedIt(derivedTrans); + + const QHash::StateId> > baseTrans = baseTransitions.value(set.first); + + while (derivedIt.hasNext()) { + derivedIt.next(); + + bool found = false; + QHashIterator::StateId> > baseIt(baseTrans); + while (baseIt.hasNext()) { + baseIt.next(); + if (derivedTermValid(baseIt.key(), derivedIt.key(), particlesHash, context, errorMsg)) { + const QPair::StateId, XsdStateMachine::StateId> endSet = + qMakePair::StateId, XsdStateMachine::StateId>(baseIt.value().first(), derivedIt.value().first()); + if (!processedSet.contains(endSet) && !workSet.contains(endSet)) { + workSet.append(endSet); + processedSet.append(endSet); + } + + found = true; + } + } + + if (!found) { + return false; + } + } + } + + // 5) + QHashIterator::StateId, XsdStateMachine::StateType> it(derivedStates); + while (it.hasNext()) { + it.next(); + + if (it.value() == XsdStateMachine::EndState || it.value() == XsdStateMachine::StartEndState) { + for (int i = 0; i < processedSet.count(); ++i) { + if (processedSet.at(i).second == it.key() && + (baseStates.value(processedSet.at(i).first) != XsdStateMachine::EndState && + baseStates.value(processedSet.at(i).first) != XsdStateMachine::StartEndState)) { + errorMsg = QtXmlPatterns::tr("derived particle allows content that is not allowed in the base particle"); + return false; + } + } + } + } + + return true; +} + +QT_END_NAMESPACE diff --git a/src/xmlpatterns/schema/qxsdparticlechecker_p.h b/src/xmlpatterns/schema/qxsdparticlechecker_p.h new file mode 100644 index 0000000..16a8d95 --- /dev/null +++ b/src/xmlpatterns/schema/qxsdparticlechecker_p.h @@ -0,0 +1,69 @@ +/**************************************************************************** +** +** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the $MODULE$ of the Qt Toolkit. +** +** $TROLLTECH_DUAL_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_XsdParticleChecker_H +#define Patternist_XsdParticleChecker_H + +#include "qxsdelement_p.h" +#include "qxsdparticle_p.h" +#include "qxsdschemacontext_p.h" +#include "qxsdwildcard_p.h" + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +namespace QPatternist +{ + /** + * @short A helper class to check validity of particles. + * + * @ingroup Patternist_schema + * @author Tobias Koenig + */ + class XsdParticleChecker + { + public: + /** + * Checks whether the given @p particle has two or more element + * declarations with the same name but different type definitions. + */ + static bool hasDuplicatedElements(const XsdParticle::Ptr &particle, const NamePool::Ptr &namePool, XsdElement::Ptr &conflictingElement); + + /** + * Checks whether the given @p particle is valid according the + * UPA (http://www.w3.org/TR/xmlschema-1/#cos-nonambig) constraint. + */ + static bool isUPAConform(const XsdParticle::Ptr &particle, const NamePool::Ptr &namePool); + + /** + * Checks whether the given @p particle subsumes the given @p derivedParticle. + * (http://www.w3.org/TR/xmlschema-1/#cos-particle-restrict) + */ + static bool subsumes(const XsdParticle::Ptr &particle, const XsdParticle::Ptr &derivedParticle, const XsdSchemaContext::Ptr &context, QString &errorMsg); + }; +} + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif diff --git a/src/xmlpatterns/schema/qxsdreference.cpp b/src/xmlpatterns/schema/qxsdreference.cpp new file mode 100644 index 0000000..0a934dd --- /dev/null +++ b/src/xmlpatterns/schema/qxsdreference.cpp @@ -0,0 +1,53 @@ +/**************************************************************************** +** +** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the $MODULE$ of the Qt Toolkit. +** +** $TROLLTECH_DUAL_LICENSE$ +** +****************************************************************************/ + +#include "qxsdreference_p.h" + +QT_BEGIN_NAMESPACE + +using namespace QPatternist; + +bool XsdReference::isReference() const +{ + return true; +} + +void XsdReference::setType(Type type) +{ + m_type = type; +} + +XsdReference::Type XsdReference::type() const +{ + return m_type; +} + +void XsdReference::setReferenceName(const QXmlName &referenceName) +{ + m_referenceName = referenceName; +} + +QXmlName XsdReference::referenceName() const +{ + return m_referenceName; +} + +void XsdReference::setSourceLocation(const QSourceLocation &location) +{ + m_sourceLocation = location; +} + +QSourceLocation XsdReference::sourceLocation() const +{ + return m_sourceLocation; +} + +QT_END_NAMESPACE diff --git a/src/xmlpatterns/schema/qxsdreference_p.h b/src/xmlpatterns/schema/qxsdreference_p.h new file mode 100644 index 0000000..afcca25 --- /dev/null +++ b/src/xmlpatterns/schema/qxsdreference_p.h @@ -0,0 +1,115 @@ +/**************************************************************************** +** +** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the $MODULE$ of the Qt Toolkit. +** +** $TROLLTECH_DUAL_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_XsdReference_H +#define Patternist_XsdReference_H + +#include "qxsdterm_p.h" + +#include + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +namespace QPatternist +{ + /** + * @short A helper class for element and group reference resolving. + * + * For easy resolving of element and group references, we have this class + * that can be used as a place holder for the real element or group + * object it is referring to. + * So whenever the parser detects an element or group reference, it creates + * a XsdReference and returns it instead of the XsdElement or XsdModelGroup. + * During a later phase, the resolver will look for all XsdReferences + * in the schema and will replace them with their referring XsdElement or + * XsdModelGroup objects. + * + * @ingroup Patternist_schema + * @author Tobias Koenig + */ + class XsdReference : public XsdTerm + { + public: + typedef QExplicitlySharedDataPointer Ptr; + + /** + * Describes the type of the reference. + */ + enum Type + { + Element, ///< The reference points to an element. + ModelGroup ///< The reference points to a model group. + }; + + /** + * Returns always @c true, used to avoid dynamic casts. + */ + virtual bool isReference() const; + + /** + * Sets the @p type of the reference. + * + * @see Type + */ + void setType(Type type); + + /** + * Returns the type of the reference. + */ + Type type() const; + + /** + * Sets the @p name of the referenced object. + * + * The name can either be a top-level element declaration + * or a top-level group declaration. + */ + void setReferenceName(const QXmlName &ame); + + /** + * Returns the name of the referenced object. + */ + QXmlName referenceName() const; + + /** + * Sets the source @p location where the reference is located. + */ + void setSourceLocation(const QSourceLocation &location); + + /** + * Returns the source location where the reference is located. + */ + QSourceLocation sourceLocation() const; + + private: + Type m_type; + QXmlName m_referenceName; + QSourceLocation m_sourceLocation; + }; +} + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif diff --git a/src/xmlpatterns/schema/qxsdschema.cpp b/src/xmlpatterns/schema/qxsdschema.cpp new file mode 100644 index 0000000..260b06b --- /dev/null +++ b/src/xmlpatterns/schema/qxsdschema.cpp @@ -0,0 +1,242 @@ +/**************************************************************************** +** +** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the $MODULE$ of the Qt Toolkit. +** +** $TROLLTECH_DUAL_LICENSE$ +** +****************************************************************************/ + +#include "qxsdschema_p.h" + +#include +#include + +QT_BEGIN_NAMESPACE + +using namespace QPatternist; + +XsdSchema::XsdSchema(const NamePool::Ptr &namePool) + : m_namePool(namePool) +{ +} + +XsdSchema::~XsdSchema() +{ +} + +NamePool::Ptr XsdSchema::namePool() const +{ + return m_namePool; +} + +void XsdSchema::setTargetNamespace(const QString &targetNamespace) +{ + m_targetNamespace = targetNamespace; +} + +QString XsdSchema::targetNamespace() const +{ + return m_targetNamespace; +} + +void XsdSchema::addElement(const XsdElement::Ptr &element) +{ + const QWriteLocker locker(&m_lock); + + m_elements.insert(element->name(m_namePool), element); +} + +XsdElement::Ptr XsdSchema::element(const QXmlName &name) const +{ + const QReadLocker locker(&m_lock); + + return m_elements.value(name); +} + +XsdElement::List XsdSchema::elements() const +{ + const QReadLocker locker(&m_lock); + + return m_elements.values(); +} + +void XsdSchema::addAttribute(const XsdAttribute::Ptr &attribute) +{ + const QWriteLocker locker(&m_lock); + + m_attributes.insert(attribute->name(m_namePool), attribute); +} + +XsdAttribute::Ptr XsdSchema::attribute(const QXmlName &name) const +{ + const QReadLocker locker(&m_lock); + + return m_attributes.value(name); +} + +XsdAttribute::List XsdSchema::attributes() const +{ + const QReadLocker locker(&m_lock); + + return m_attributes.values(); +} + +void XsdSchema::addType(const SchemaType::Ptr &type) +{ + const QWriteLocker locker(&m_lock); + + m_types.insert(type->name(m_namePool), type); +} + +SchemaType::Ptr XsdSchema::type(const QXmlName &name) const +{ + const QReadLocker locker(&m_lock); + + return m_types.value(name); +} + +SchemaType::List XsdSchema::types() const +{ + const QReadLocker locker(&m_lock); + + return m_types.values(); +} + +XsdSimpleType::List XsdSchema::simpleTypes() const +{ + QReadLocker locker(&m_lock); + + XsdSimpleType::List retval; + + const SchemaType::List types = m_types.values(); + for (int i = 0; i < types.count(); ++i) { + if (types.at(i)->isSimpleType() && types.at(i)->isDefinedBySchema()) + retval.append(types.at(i)); + } + + return retval; +} + +XsdComplexType::List XsdSchema::complexTypes() const +{ + QReadLocker locker(&m_lock); + + XsdComplexType::List retval; + + const SchemaType::List types = m_types.values(); + for (int i = 0; i < types.count(); ++i) { + if (types.at(i)->isComplexType() && types.at(i)->isDefinedBySchema()) + retval.append(types.at(i)); + } + + return retval; +} + +void XsdSchema::addAnonymousType(const SchemaType::Ptr &type) +{ + const QWriteLocker locker(&m_lock); + + // search for not used anonymous type name + QXmlName typeName = type->name(m_namePool); + while (m_anonymousTypes.contains(typeName)) { + typeName = m_namePool->allocateQName(QString(), QLatin1String("merged_") + m_namePool->stringForLocalName(typeName.localName()), QString()); + } + + m_anonymousTypes.insert(typeName, type); +} + +SchemaType::List XsdSchema::anonymousTypes() const +{ + const QReadLocker locker(&m_lock); + + return m_anonymousTypes.values(); +} + +void XsdSchema::addAttributeGroup(const XsdAttributeGroup::Ptr &group) +{ + const QWriteLocker locker(&m_lock); + + m_attributeGroups.insert(group->name(m_namePool), group); +} + +XsdAttributeGroup::Ptr XsdSchema::attributeGroup(const QXmlName name) const +{ + const QReadLocker locker(&m_lock); + + return m_attributeGroups.value(name); +} + +XsdAttributeGroup::List XsdSchema::attributeGroups() const +{ + const QReadLocker locker(&m_lock); + + return m_attributeGroups.values(); +} + +void XsdSchema::addElementGroup(const XsdModelGroup::Ptr &group) +{ + const QWriteLocker locker(&m_lock); + + m_elementGroups.insert(group->name(m_namePool), group); +} + +XsdModelGroup::Ptr XsdSchema::elementGroup(const QXmlName &name) const +{ + const QReadLocker locker(&m_lock); + + return m_elementGroups.value(name); +} + +XsdModelGroup::List XsdSchema::elementGroups() const +{ + const QReadLocker locker(&m_lock); + + return m_elementGroups.values(); +} + +void XsdSchema::addNotation(const XsdNotation::Ptr ¬ation) +{ + const QWriteLocker locker(&m_lock); + + m_notations.insert(notation->name(m_namePool), notation); +} + +XsdNotation::Ptr XsdSchema::notation(const QXmlName &name) const +{ + const QReadLocker locker(&m_lock); + + return m_notations.value(name); +} + +XsdNotation::List XsdSchema::notations() const +{ + const QReadLocker locker(&m_lock); + + return m_notations.values(); +} + +void XsdSchema::addIdentityConstraint(const XsdIdentityConstraint::Ptr &constraint) +{ + const QWriteLocker locker(&m_lock); + + m_identityConstraints.insert(constraint->name(m_namePool), constraint); +} + +XsdIdentityConstraint::Ptr XsdSchema::identityConstraint(const QXmlName &name) const +{ + const QReadLocker locker(&m_lock); + + return m_identityConstraints.value(name); +} + +XsdIdentityConstraint::List XsdSchema::identityConstraints() const +{ + const QReadLocker locker(&m_lock); + + return m_identityConstraints.values(); +} + +QT_END_NAMESPACE diff --git a/src/xmlpatterns/schema/qxsdschema_p.h b/src/xmlpatterns/schema/qxsdschema_p.h new file mode 100644 index 0000000..b41a2d5 --- /dev/null +++ b/src/xmlpatterns/schema/qxsdschema_p.h @@ -0,0 +1,271 @@ +/**************************************************************************** +** +** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the $MODULE$ of the Qt Toolkit. +** +** $TROLLTECH_DUAL_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_XsdSchema_H +#define Patternist_XsdSchema_H + +#include "qschematype_p.h" +#include "qxsdannotated_p.h" +#include "qxsdattribute_p.h" +#include "qxsdattributegroup_p.h" +#include "qxsdcomplextype_p.h" +#include "qxsdelement_p.h" +#include "qxsdidentityconstraint_p.h" +#include "qxsdmodelgroup_p.h" +#include "qxsdnotation_p.h" +#include "qxsdsimpletype_p.h" + +#include +#include + +/** + * @defgroup Patternist_schema XML Schema Processing + */ + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +namespace QPatternist +{ + /** + * @short Represents a XSD schema object. + * + * The class provides access to all components of a parsed XSD. + * + * @note In the documentation of this class objects, which are direct + * children of the schema object, are called top-level objects. + * + * @see XML Schema API reference + * @ingroup Patternist_schema + * @author Tobias Koenig + */ + class XsdSchema : public QSharedData, public XsdAnnotated + { + public: + typedef QExplicitlySharedDataPointer Ptr; + typedef QList List; + + /** + * Creates a new schema object. + * + * @param namePool The namepool that should be used for names of + * all schema components. + */ + XsdSchema(const NamePool::Ptr &namePool); + + /** + * Destroys the schema object. + */ + ~XsdSchema(); + + /** + * Returns the namepool that is used for names of + * all schema components. + */ + NamePool::Ptr namePool() const; + + /** + * Sets the @p targetNamespace of the schema. + */ + void setTargetNamespace(const QString &targetNamespace); + + /** + * Returns the target namespace of the schema. + */ + QString targetNamespace() const; + + /** + * Adds a new top-level @p element to the schema. + * + * @param element The new element. + * @see Element Declaration + */ + void addElement(const XsdElement::Ptr &element); + + /** + * Returns the top-level element of the schema with + * the given @p name or an empty pointer if none exist. + */ + XsdElement::Ptr element(const QXmlName &name) const; + + /** + * Returns the list of all top-level elements. + */ + XsdElement::List elements() const; + + /** + * Adds a new top-level @p attribute to the schema. + * + * @param attribute The new attribute. + * @see Attribute Declaration + */ + void addAttribute(const XsdAttribute::Ptr &attribute); + + /** + * Returns the top-level attribute of the schema with + * the given @p name or an empty pointer if none exist. + */ + XsdAttribute::Ptr attribute(const QXmlName &name) const; + + /** + * Returns the list of all top-level attributes. + */ + XsdAttribute::List attributes() const; + + /** + * Adds a new top-level @p type to the schema. + * That can be a simple or a complex type. + * + * @param type The new type. + * @see Simple Type Declaration + * @see Complex Type Declaration + */ + void addType(const SchemaType::Ptr &type); + + /** + * Returns the top-level type of the schema with + * the given @p name or an empty pointer if none exist. + */ + SchemaType::Ptr type(const QXmlName &name) const; + + /** + * Returns the list of all top-level types. + */ + SchemaType::List types() const; + + /** + * Returns the list of all top-level simple types. + */ + XsdSimpleType::List simpleTypes() const; + + /** + * Returns the list of all top-level complex types. + */ + XsdComplexType::List complexTypes() const; + + /** + * Adds an anonymous @p type to the schema. + * Anonymous types have no name and are declared + * locally inside an element object. + * + * @param type The new anonymous type. + */ + void addAnonymousType(const SchemaType::Ptr &type); + + /** + * Returns the list of all anonymous types. + */ + SchemaType::List anonymousTypes() const; + + /** + * Adds a new top-level attribute @p group to the schema. + * + * @param group The new attribute group. + * @see Attribute Group Declaration + */ + void addAttributeGroup(const XsdAttributeGroup::Ptr &group); + + /** + * Returns the top-level attribute group of the schema with + * the given @p name or an empty pointer if none exist. + */ + XsdAttributeGroup::Ptr attributeGroup(const QXmlName name) const; + + /** + * Returns the list of all top-level attribute groups. + */ + XsdAttributeGroup::List attributeGroups() const; + + /** + * Adds a new top-level element @p group to the schema. + * + * @param group The new element group. + * @see Element Group Declaration + */ + void addElementGroup(const XsdModelGroup::Ptr &group); + + /** + * Returns the top-level element group of the schema with + * the given @p name or an empty pointer if none exist. + */ + XsdModelGroup::Ptr elementGroup(const QXmlName &name) const; + + /** + * Returns the list of all top-level element groups. + */ + XsdModelGroup::List elementGroups() const; + + /** + * Adds a new top-level @p notation to the schema. + * + * @param notation The new notation. + * @see Notation Declaration + */ + void addNotation(const XsdNotation::Ptr ¬ation); + + /** + * Returns the top-level notation of the schema with + * the given @p name or an empty pointer if none exist. + */ + XsdNotation::Ptr notation(const QXmlName &name) const; + + /** + * Returns the list of all top-level notations. + */ + XsdNotation::List notations() const; + + /** + * Adds a new identity @p constraint to the schema. + */ + void addIdentityConstraint(const XsdIdentityConstraint::Ptr &constraint); + + /** + * Returns the identity constraint with the given @p name + * or an empty pointer if none exist. + */ + XsdIdentityConstraint::Ptr identityConstraint(const QXmlName &name) const; + + /** + * Returns the list of all identity constraints in this schema. + */ + XsdIdentityConstraint::List identityConstraints() const; + + private: + NamePool::Ptr m_namePool; + QString m_targetNamespace; + QHash m_elements; + QHash m_attributes; + QHash m_types; + QHash m_anonymousTypes; + QHash m_attributeGroups; + QHash m_elementGroups; + QHash m_notations; + QHash m_identityConstraints; + mutable QReadWriteLock m_lock; + }; +} + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif diff --git a/src/xmlpatterns/schema/qxsdschemachecker.cpp b/src/xmlpatterns/schema/qxsdschemachecker.cpp new file mode 100644 index 0000000..2a64327 --- /dev/null +++ b/src/xmlpatterns/schema/qxsdschemachecker.cpp @@ -0,0 +1,2031 @@ +/**************************************************************************** +** +** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the $MODULE$ of the Qt Toolkit. +** +** $TROLLTECH_DUAL_LICENSE$ +** +****************************************************************************/ + +#include "qxsdschemachecker_p.h" + +#include "qderivedinteger_p.h" +#include "qderivedstring_p.h" +#include "qpatternplatform_p.h" +#include "qqnamevalue_p.h" +#include "qsourcelocationreflection_p.h" +#include "qvaluefactory_p.h" +#include "qxsdattributereference_p.h" +#include "qxsdparticlechecker_p.h" +#include "qxsdreference_p.h" +#include "qxsdschemacontext_p.h" +#include "qxsdschemahelper_p.h" +#include "qxsdschemaparsercontext_p.h" +#include "qxsdschematypesfactory_p.h" +#include "qxsdtypechecker_p.h" + +#include "qxsdschemachecker_helper.cpp" + +QT_BEGIN_NAMESPACE + +using namespace QPatternist; + +XsdSchemaChecker::XsdSchemaChecker(const QExplicitlySharedDataPointer &context, const XsdSchemaParserContext *parserContext) + : m_context(context) + , m_namePool(parserContext->namePool()) + , m_schema(parserContext->schema()) +{ + setupAllowedAtomicFacets(); +} + +XsdSchemaChecker::~XsdSchemaChecker() +{ +} + +/* + * This method is called after the resolver has set the base type for every + * type and information about deriavtion and 'is simple type vs. is complex type' + * are available. + */ +void XsdSchemaChecker::basicCheck() +{ + // first check that there is no circular inheritance, only the + // wxsSuperType is used here + checkBasicCircularInheritances(); + + // check the basic constraints like simple type can not inherit from complex type etc. + checkBasicSimpleTypeConstraints(); + checkBasicComplexTypeConstraints(); +} + +void XsdSchemaChecker::check() +{ + checkCircularInheritances(); + checkInheritanceRestrictions(); + checkSimpleDerivationRestrictions(); + checkSimpleTypeConstraints(); + checkComplexTypeConstraints(); + checkDuplicatedAttributeUses(); + + checkElementConstraints(); + checkAttributeConstraints(); + checkAttributeUseConstraints(); +// checkElementDuplicates(); +} + +void XsdSchemaChecker::addComponentLocationHash(const ComponentLocationHash &hash) +{ + m_componentLocationHash.unite(hash); +} + +/** + * Checks whether the @p otherType is the same as @p myType or if one of its + * ancestors is the same as @p myType. + */ +static bool matchesType(const SchemaType::Ptr &myType, const SchemaType::Ptr &otherType, QSet visitedTypes) +{ + bool retval = false; + + if (otherType) { + if (visitedTypes.contains(otherType)) { + return true; + } else { + visitedTypes.insert(otherType); + } + // simple types can have different varieties, so we have to check each of them + if (otherType->isSimpleType()) { + const XsdSimpleType::Ptr simpleType = otherType; + if (simpleType->category() == XsdSimpleType::SimpleTypeAtomic) { + // for atomic type we use the same test as in SchemaType::wxsTypeMatches + retval = (myType == simpleType ? true : matchesType(myType, simpleType->wxsSuperType(), visitedTypes)); + } else if (simpleType->category() == XsdSimpleType::SimpleTypeList) { + // for list type we test against the itemType property + retval = (myType == simpleType->itemType() ? true : matchesType(myType, simpleType->itemType()->wxsSuperType(), visitedTypes)); + } else if (simpleType->category() == XsdSimpleType::SimpleTypeUnion) { + // for union type we test against each member type + const XsdSimpleType::List members = simpleType->memberTypes(); + for (int i = 0; i < members.count(); ++i) { + if (myType == members.at(i) ? true : matchesType(myType, members.at(i)->wxsSuperType(), visitedTypes)) { + retval = true; + break; + } + } + } else { + // reached xsAnySimple type whichs category is None + retval = false; + } + } else { + // if no simple type we handle it like in SchemaType::wxsTypeMatches + retval = (myType == otherType ? true : matchesType(myType, otherType->wxsSuperType(), visitedTypes)); + } + } else // if otherType is null it doesn't match + retval = false; + + return retval; +} + +/** + * Checks whether there is a circular inheritance for the union inheritance. + */ +static bool hasCircularUnionInheritance(const XsdSimpleType::Ptr &type, const SchemaType::Ptr &otherType, NamePool::Ptr &namePool) +{ + if (type == otherType) { + return true; + } + + if (!otherType->isSimpleType() || !otherType->isDefinedBySchema()) { + return false; + } + + const XsdSimpleType::Ptr simpleOtherType = otherType; + + if (simpleOtherType->category() == XsdSimpleType::SimpleTypeUnion) { + const XsdSimpleType::List memberTypes = simpleOtherType->memberTypes(); + for (int i = 0; i < memberTypes.count(); ++i) { + if (otherType->wxsSuperType() == type) { + return true; + } + if (hasCircularUnionInheritance(type, memberTypes.at(i), namePool)) { + return true; + } + } + } + + return false; +} + +static inline bool wxsTypeMatches(const SchemaType::Ptr &type, const SchemaType::Ptr &otherType, QSet &visitedTypes, SchemaType::Ptr &conflictingType) +{ + if (!otherType) + return false; + + if (visitedTypes.contains(otherType)) { // inheritance loop detected + conflictingType = otherType; + return true; + } else { + visitedTypes.insert(otherType); + } + + if (type == otherType) + return true; + + return wxsTypeMatches(type, otherType->wxsSuperType(), visitedTypes, conflictingType); +} + +void XsdSchemaChecker::checkBasicCircularInheritances() +{ + // check all global types... + SchemaType::List types = m_schema->types(); + + // .. and anonymous types + types << m_schema->anonymousTypes(); + + for (int i = 0; i < types.count(); ++i) { + const SchemaType::Ptr type = types.at(i); + const QSourceLocation location = sourceLocationForType(type); + + // @see http://www.w3.org/TR/xmlschema11-1/#ct-props-correct 3) + + // check normal base type inheritance + QSet visitedTypes; + SchemaType::Ptr conflictingType; + + if (wxsTypeMatches(type, type->wxsSuperType(), visitedTypes, conflictingType)) { + if (conflictingType) + m_context->error(QtXmlPatterns::tr("%1 has inheritance loop in its base type %2") + .arg(formatType(m_namePool, type)) + .arg(formatType(m_namePool, conflictingType)), + XsdSchemaContext::XSDError, location); + else + m_context->error(QtXmlPatterns::tr("circular inheritance of base type %1").arg(formatType(m_namePool, type)), XsdSchemaContext::XSDError, location); + + return; + } + } +} + +void XsdSchemaChecker::checkCircularInheritances() +{ + // check all global types... + SchemaType::List types = m_schema->types(); + + // .. and anonymous types + types << m_schema->anonymousTypes(); + + for (int i = 0; i < types.count(); ++i) { + const SchemaType::Ptr type = types.at(i); + const QSourceLocation location = sourceLocationForType(type); + + // @see http://www.w3.org/TR/xmlschema11-1/#ct-props-correct 3) + + // check normal base type inheritance + QSet visitedTypes; + if (matchesType(type, type->wxsSuperType(), visitedTypes)) { + m_context->error(QtXmlPatterns::tr("circular inheritance of base type %1").arg(formatType(m_namePool, type)), XsdSchemaContext::XSDError, location); + return; + } + + // check union member inheritance + if (type->isSimpleType() && type->isDefinedBySchema()) { + const XsdSimpleType::Ptr simpleType = type; + if (simpleType->category() == XsdSimpleType::SimpleTypeUnion) { + const XsdSimpleType::List memberTypes = simpleType->memberTypes(); + for (int j = 0; j < memberTypes.count(); ++j) { + if (hasCircularUnionInheritance(simpleType, memberTypes.at(j), m_namePool)) { + m_context->error(QtXmlPatterns::tr("circular inheritance of union %1").arg(formatType(m_namePool, type)), XsdSchemaContext::XSDError, location); + return; + } + } + } + } + } +} + +void XsdSchemaChecker::checkInheritanceRestrictions() +{ + // check all global types... + SchemaType::List types = m_schema->types(); + + // .. and anonymous types + types << m_schema->anonymousTypes(); + + for (int i = 0; i < types.count(); ++i) { + const SchemaType::Ptr type = types.at(i); + const QSourceLocation location = sourceLocationForType(type); + + // check inheritance restrictions given by final property of base class + const SchemaType::Ptr baseType = type->wxsSuperType(); + if (baseType->isDefinedBySchema()) { + if ((type->derivationMethod() == SchemaType::DerivationRestriction) && (baseType->derivationConstraints() & SchemaType::RestrictionConstraint)) { + m_context->error(QtXmlPatterns::tr("%1 is not allowed to derive from %2 by restriction as the latter defines it as final") + .arg(formatType(m_namePool, type)) + .arg(formatType(m_namePool, baseType)), XsdSchemaContext::XSDError, location); + return; + } else if ((type->derivationMethod() == SchemaType::DerivationExtension) && (baseType->derivationConstraints() & SchemaType::ExtensionConstraint)) { + m_context->error(QtXmlPatterns::tr("%1 is not allowed to derive from %2 by extension as the latter defines it as final") + .arg(formatType(m_namePool, type)) + .arg(formatType(m_namePool, baseType)), XsdSchemaContext::XSDError, location); + return; + } + } + } +} + +void XsdSchemaChecker::checkBasicSimpleTypeConstraints() +{ + // check all global types... + SchemaType::List types = m_schema->types(); + + // .. and anonymous types + types << m_schema->anonymousTypes(); + + for (int i = 0; i < types.count(); ++i) { + const SchemaType::Ptr type = types.at(i); + + if (!type->isSimpleType()) + continue; + + const XsdSimpleType::Ptr simpleType = type; + + const QSourceLocation location = sourceLocation(simpleType); + + // check inheritance restrictions of simple type defined by schema constraints + const SchemaType::Ptr baseType = simpleType->wxsSuperType(); + + if (baseType->isComplexType() && (simpleType->name(m_namePool) != BuiltinTypes::xsAnySimpleType->name(m_namePool))) { + m_context->error(QtXmlPatterns::tr("base type of simple type %1 cannot be complex type %2") + .arg(formatType(m_namePool, simpleType)) + .arg(formatType(m_namePool, baseType)), + XsdSchemaContext::XSDError, location); + return; + } + + if (baseType == BuiltinTypes::xsAnyType) { + if (type->name(m_namePool) != BuiltinTypes::xsAnySimpleType->name(m_namePool)) { + m_context->error(QtXmlPatterns::tr("simple type %1 cannot have direct base type %2") + .arg(formatType(m_namePool, simpleType)) + .arg(formatType(m_namePool, BuiltinTypes::xsAnyType)), + XsdSchemaContext::XSDError, location); + return; + } + } + } +} + +void XsdSchemaChecker::checkSimpleTypeConstraints() +{ + // check all global types... + SchemaType::List types = m_schema->types(); + + // .. and anonymous types + types << m_schema->anonymousTypes(); + + for (int i = 0; i < types.count(); ++i) { + const SchemaType::Ptr type = types.at(i); + + if (!type->isSimpleType()) + continue; + + const XsdSimpleType::Ptr simpleType = type; + + const QSourceLocation location = sourceLocation(simpleType); + + if (simpleType->category() == XsdSimpleType::None) { + // additional checks + // check that no user defined type has xs:AnySimpleType as base type (except xs:AnyAtomicType) + if (simpleType->wxsSuperType()->name(m_namePool) == BuiltinTypes::xsAnySimpleType->name(m_namePool)) { + if (simpleType->name(m_namePool) != BuiltinTypes::xsAnyAtomicType->name(m_namePool)) { + m_context->error(QtXmlPatterns::tr("simple type %1 is not allowed to have base type %2") + .arg(formatType(m_namePool, simpleType)) + .arg(formatType(m_namePool, simpleType->wxsSuperType())), + XsdSchemaContext::XSDError, location); + return; + } + } + // check that no user defined type has xs:AnyAtomicType as base type + if (simpleType->wxsSuperType()->name(m_namePool) == BuiltinTypes::xsAnyAtomicType->name(m_namePool)) { + m_context->error(QtXmlPatterns::tr("simple type %1 is not allowed to have base type %2") + .arg(formatType(m_namePool, simpleType)) + .arg(formatType(m_namePool, simpleType->wxsSuperType())), + XsdSchemaContext::XSDError, location); + return; + } + } + + // @see http://www.w3.org/TR/xmlschema11-1/#d0e37310 + if (simpleType->category() == XsdSimpleType::SimpleTypeAtomic) { + // 1.1 + if ((simpleType->wxsSuperType()->category() != XsdSimpleType::SimpleTypeAtomic) && (simpleType->name(m_namePool) != BuiltinTypes::xsAnyAtomicType->name(m_namePool))) { + m_context->error(QtXmlPatterns::tr("simple type %1 can only have simple atomic type as base type") + .arg(formatType(m_namePool, simpleType)), + XsdSchemaContext::XSDError, location); + } + // 1.2 + if (simpleType->wxsSuperType()->derivationConstraints() & SchemaType::RestrictionConstraint) { + m_context->error(QtXmlPatterns::tr("simple type %1 cannot derive from %2 as the latter defines restriction as final") + .arg(formatType(m_namePool, simpleType->wxsSuperType())) + .arg(formatType(m_namePool, simpleType)), + XsdSchemaContext::XSDError, location); + } + + // 1.3 + // checked by checkConstrainingFacets already + } else if (simpleType->category() == XsdSimpleType::SimpleTypeList) { + const AnySimpleType::Ptr itemType = simpleType->itemType(); + + // 2.1 or @see http://www.w3.org/TR/xmlschema-2/#cos-list-of-atomic + if (itemType->category() != SchemaType::SimpleTypeAtomic && itemType->category() != SchemaType::SimpleTypeUnion) { + m_context->error(QtXmlPatterns::tr("variety of item type of %1 must be either atomic or union").arg(formatType(m_namePool, simpleType)), XsdSchemaContext::XSDError, location); + return; + } + + // 2.1 second part + if (itemType->category() == SchemaType::SimpleTypeUnion && itemType->isDefinedBySchema()) { + const XsdSimpleType::Ptr simpleItemType = itemType; + const AnySimpleType::List memberTypes = simpleItemType->memberTypes(); + for (int j = 0; j < memberTypes.count(); ++j) { + if (memberTypes.at(j)->category() != SchemaType::SimpleTypeAtomic) { + m_context->error(QtXmlPatterns::tr("variety of member types of %1 must be atomic").arg(formatType(m_namePool, simpleItemType)), XsdSchemaContext::XSDError, location); + return; + } + } + } + + // 2.2.1 + if (simpleType->wxsSuperType()->name(m_namePool) == BuiltinTypes::xsAnySimpleType->name(m_namePool)) { + if (itemType->isSimpleType() && itemType->isDefinedBySchema()) { + const XsdSimpleType::Ptr simpleItemType = itemType; + + // 2.2.1.1 + if (simpleItemType->derivationConstraints() & XsdSimpleType::ListConstraint) { + m_context->error(QtXmlPatterns::tr("%1 is not allowed to derive from %2 by list as the latter defines it as final") + .arg(formatType(m_namePool, simpleType)) + .arg(formatType(m_namePool, simpleItemType)), XsdSchemaContext::XSDError, location); + return; + } + + // 2.2.1.2 + const XsdFacet::Hash facets = simpleType->facets(); + XsdFacet::HashIterator it(facets); + + bool invalidFacetFound = false; + while (it.hasNext()) { + it.next(); + if (it.key() != XsdFacet::WhiteSpace) { + invalidFacetFound = true; + break; + } + } + + if (invalidFacetFound) { + m_context->error(QtXmlPatterns::tr("simple type %1 is only allowed to have %2 facet") + .arg(formatType(m_namePool, simpleType)) + .arg(formatKeyword("whiteSpace")), + XsdSchemaContext::XSDError, location); + return; + } + } + } else { // 2.2.2 + // 2.2.2.1 + if (simpleType->wxsSuperType()->category() != XsdSimpleType::SimpleTypeList) { + m_context->error(QtXmlPatterns::tr("base type of simple type %1 must have variety of type list").arg(formatType(m_namePool, simpleType)), XsdSchemaContext::XSDError, location); + return; + } + + // 2.2.2.2 + if (simpleType->wxsSuperType()->derivationConstraints() & SchemaType::RestrictionConstraint) { + m_context->error(QtXmlPatterns::tr("base type of simple type %1 has defined derivation by restriction as final").arg(formatType(m_namePool, simpleType)), XsdSchemaContext::XSDError, location); + return; + } + + // 2.2.2.3 + if (!XsdSchemaHelper::isSimpleDerivationOk(itemType, XsdSimpleType::Ptr(simpleType->wxsSuperType())->itemType(), SchemaType::DerivationConstraints())) { + m_context->error(QtXmlPatterns::tr("item type of base type does not match item type of %1").arg(formatType(m_namePool, simpleType)), XsdSchemaContext::XSDError, location); + return; + } + + // 2.2.2.4 + const XsdFacet::Hash facets = simpleType->facets(); + XsdFacet::HashIterator it(facets); + + bool invalidFacetFound = false; + XsdFacet::Type invalidFacetType = XsdFacet::None; + while (it.hasNext()) { + it.next(); + const XsdFacet::Type facetType = it.key(); + if (facetType != XsdFacet::Length && + facetType != XsdFacet::MinimumLength && + facetType != XsdFacet::MaximumLength && + facetType != XsdFacet::WhiteSpace && + facetType != XsdFacet::Pattern && + facetType != XsdFacet::Enumeration) { + invalidFacetType = facetType; + invalidFacetFound = true; + break; + } + } + + if (invalidFacetFound) { + m_context->error(QtXmlPatterns::tr("simple type %1 contains not allowed facet type %2") + .arg(formatType(m_namePool, simpleType)) + .arg(formatKeyword(XsdFacet::typeName(invalidFacetType))), + XsdSchemaContext::XSDError, location); + return; + } + + // 2.2.2.5 + // TODO: check value constraints + } + + + } else if (simpleType->category() == XsdSimpleType::SimpleTypeUnion) { + const AnySimpleType::List memberTypes = simpleType->memberTypes(); + + if (simpleType->wxsSuperType()->name(m_namePool) == BuiltinTypes::xsAnySimpleType->name(m_namePool)) { // 3.1.1 + // 3.3.1.1 + for (int i = 0; i < memberTypes.count(); ++i) { + const AnySimpleType::Ptr memberType = memberTypes.at(i); + + if (memberType->derivationConstraints() & XsdSimpleType::UnionConstraint) { + m_context->error(QtXmlPatterns::tr("%1 is not allowed to derive from %2 by union as the latter defines it as final") + .arg(formatType(m_namePool, simpleType)) + .arg(formatType(m_namePool, memberType)), XsdSchemaContext::XSDError, location); + return; + } + } + + // 3.3.1.2 + if (!simpleType->facets().isEmpty()) { + m_context->error(QtXmlPatterns::tr("%1 is not allowed to have any facets") + .arg(formatType(m_namePool, simpleType)), + XsdSchemaContext::XSDError, location); + return; + } + } else { + // 3.1.2.1 + if (simpleType->wxsSuperType()->category() != SchemaType::SimpleTypeUnion) { + m_context->error(QtXmlPatterns::tr("base type %1 of simple type %2 must have variety of union") + .arg(formatType(m_namePool, simpleType->wxsSuperType())) + .arg(formatType(m_namePool, simpleType)), + XsdSchemaContext::XSDError, location); + return; + } + + // 3.1.2.2 + if (simpleType->wxsSuperType()->derivationConstraints() & SchemaType::DerivationRestriction) { + m_context->error(QtXmlPatterns::tr("base type %1 of simple type %2 is not allowed to have restriction in %3 attribute") + .arg(formatType(m_namePool, simpleType->wxsSuperType())) + .arg(formatType(m_namePool, simpleType)) + .arg(formatAttribute("final")), + XsdSchemaContext::XSDError, location); + return; + } + + //3.1.2.3 + if (simpleType->wxsSuperType()->isDefinedBySchema()) { + const XsdSimpleType::Ptr simpleBaseType(simpleType->wxsSuperType()); + + AnySimpleType::List baseMemberTypes = simpleBaseType->memberTypes(); + for (int i = 0; i < memberTypes.count(); ++i) { + const AnySimpleType::Ptr memberType = memberTypes.at(i); + const AnySimpleType::Ptr baseMemberType = baseMemberTypes.at(i); + + if (!XsdSchemaHelper::isSimpleDerivationOk(memberType, baseMemberType, SchemaType::DerivationConstraints())) { + m_context->error(QtXmlPatterns::tr("member type %1 cannot be derived from member type %2 of %3's base type %4") + .arg(formatType(m_namePool, memberType)) + .arg(formatType(m_namePool, baseMemberType)) + .arg(formatType(m_namePool, simpleType)) + .arg(formatType(m_namePool, simpleBaseType)), + XsdSchemaContext::XSDError, location); + } + } + } + + // 3.1.2.4 + const XsdFacet::Hash facets = simpleType->facets(); + XsdFacet::HashIterator it(facets); + + bool invalidFacetFound = false; + XsdFacet::Type invalidFacetType = XsdFacet::None; + while (it.hasNext()) { + it.next(); + const XsdFacet::Type facetType = it.key(); + if (facetType != XsdFacet::Pattern && + facetType != XsdFacet::Enumeration) { + invalidFacetType = facetType; + invalidFacetFound = true; + break; + } + } + + if (invalidFacetFound) { + m_context->error(QtXmlPatterns::tr("simple type %1 contains not allowed facet type %2") + .arg(formatType(m_namePool, simpleType)) + .arg(formatKeyword(XsdFacet::typeName(invalidFacetType))), + XsdSchemaContext::XSDError, location); + return; + } + + // 3.1.2.5 + // TODO: check value constraints + } + } + } +} + +void XsdSchemaChecker::checkBasicComplexTypeConstraints() +{ + // check all global types... + SchemaType::List types = m_schema->types(); + + // .. and anonymous types + types << m_schema->anonymousTypes(); + + for (int i = 0; i < types.count(); ++i) { + const SchemaType::Ptr type = types.at(i); + + if (!type->isComplexType() || !type->isDefinedBySchema()) + continue; + + const XsdComplexType::Ptr complexType = type; + + const QSourceLocation location = sourceLocation(complexType); + + // check inheritance restrictions of complex type defined by schema constraints + const SchemaType::Ptr baseType = complexType->wxsSuperType(); + + // @see http://www.w3.org/TR/xmlschema11-1/#ct-props-correct 2) + if (baseType->isSimpleType() && (complexType->derivationMethod() != XsdComplexType::DerivationExtension)) { + m_context->error(QtXmlPatterns::tr("derivation method of %1 must be extension because the base type %2 is a simple type") + .arg(formatType(m_namePool, complexType)) + .arg(formatType(m_namePool, baseType)), + XsdSchemaContext::XSDError, location); + return; + } + } +} + +void XsdSchemaChecker::checkComplexTypeConstraints() +{ + // check all global types... + SchemaType::List types = m_schema->types(); + + // .. and anonymous types + types << m_schema->anonymousTypes(); + + for (int i = 0; i < types.count(); ++i) { + const SchemaType::Ptr type = types.at(i); + + if (!type->isComplexType() || !type->isDefinedBySchema()) + continue; + + const XsdComplexType::Ptr complexType = type; + + const QSourceLocation location = sourceLocation(complexType); + + if (complexType->contentType()->particle()) { + XsdElement::Ptr duplicatedElement; + if (XsdParticleChecker::hasDuplicatedElements(complexType->contentType()->particle(), m_namePool, duplicatedElement)) { + m_context->error(QtXmlPatterns::tr("complex type %1 has duplicated element %2 in its content model") + .arg(formatType(m_namePool, complexType)) + .arg(formatKeyword(duplicatedElement->displayName(m_namePool))), + XsdSchemaContext::XSDError, location); + return; + } + + if (!XsdParticleChecker::isUPAConform(complexType->contentType()->particle(), m_namePool)) { + m_context->error(QtXmlPatterns::tr("complex type %1 has non-deterministic content") + .arg(formatType(m_namePool, complexType)), + XsdSchemaContext::XSDError, location); + return; + } + } + + // check inheritance restrictions of complex type defined by schema constraints + const SchemaType::Ptr baseType = complexType->wxsSuperType(); + + // @see http://www.w3.org/TR/xmlschema11-1/#cos-ct-extends + if (complexType->derivationMethod() == XsdComplexType::DerivationExtension) { + if (baseType->isComplexType() && baseType->isDefinedBySchema()) { + const XsdComplexType::Ptr complexBaseType = baseType; + + // we can skip 1.1 here, as it is tested in checkInheritanceRestrictions() already + + // 1.2 and 1.3 + QString errorMsg; + if (!XsdSchemaHelper::isValidAttributeUsesExtension(complexType->attributeUses(), complexBaseType->attributeUses(), + complexType->attributeWildcard(), complexBaseType->attributeWildcard(), m_context, errorMsg)) { + m_context->error(QtXmlPatterns::tr("attributes of complex type %1 are not a valid extension of the attributes of base type %2: %3") + .arg(formatType(m_namePool, complexType)) + .arg(formatType(m_namePool, baseType)) + .arg(errorMsg), + XsdSchemaContext::XSDError, location); + return; + } + + // 1.4 + bool validContentType = false; + if (complexType->contentType()->variety() == XsdComplexType::ContentType::Simple && complexBaseType->contentType()->variety() == XsdComplexType::ContentType::Simple) { + if (complexType->contentType()->simpleType() == complexBaseType->contentType()->simpleType()) { + validContentType = true; // 1.4.1 + } + } else if (complexType->contentType()->variety() == XsdComplexType::ContentType::Empty && complexBaseType->contentType()->variety() == XsdComplexType::ContentType::Empty) { + validContentType = true; // 1.4.2 + } else { // 1.4.3 + if (complexType->contentType()->variety() == XsdComplexType::ContentType::ElementOnly || complexType->contentType()->variety() == XsdComplexType::ContentType::Mixed) { // 1.4.3.1 + if (complexBaseType->contentType()->variety() == XsdComplexType::ContentType::Empty) { + validContentType = true; // 1.4.3.2.1 + } else { // 1.4.3.2.2 + if (complexType->contentType()->particle()) { // our own check + if ((complexType->contentType()->variety() == XsdComplexType::ContentType::ElementOnly && complexBaseType->contentType()->variety() == XsdComplexType::ContentType::ElementOnly) || + (complexType->contentType()->variety() == XsdComplexType::ContentType::Mixed && complexBaseType->contentType()->variety() == XsdComplexType::ContentType::Mixed)) { // 1.4.3.2.2.1 + if (isValidParticleExtension(complexType->contentType()->particle(), complexBaseType->contentType()->particle())) { + validContentType = true; // 1.4.3.2.2.2 + } + } + } + // 1.4.3.2.2.3 and 1.4.3.2.2.4 handle 'open content' that we do not support yet + } + } + } + + // 1.5 WTF?!? + + if (!validContentType) { + m_context->error(QtXmlPatterns::tr("content model of complex type %1 is not a valid extension of content model of %2") + .arg(formatType(m_namePool, complexType)) + .arg(formatType(m_namePool, complexBaseType)), + XsdSchemaContext::XSDError, location); + return; + } + + } else if (baseType->isSimpleType()) { + // 2.1 + if (complexType->contentType()->variety() != XsdComplexType::ContentType::Simple) { + m_context->error(QtXmlPatterns::tr("complex type %1 must have simple content") + .arg(formatType(m_namePool, complexType)), + XsdSchemaContext::XSDError, location); + return; + } + + if (complexType->contentType()->simpleType() != baseType) { + m_context->error(QtXmlPatterns::tr("complex type %1 must have the same simple type as its base class %2") + .arg(formatType(m_namePool, complexType)) + .arg(formatType(m_namePool, baseType)), + XsdSchemaContext::XSDError, location); + return; + } + + // 2.2 tested in checkInheritanceRestrictions() already + } + } else if (complexType->derivationMethod() == XsdComplexType::DerivationRestriction) { + // @see http://www.w3.org/TR/xmlschema11-1/#d0e21402 + const SchemaType::Ptr baseType(complexType->wxsSuperType()); + + bool derivationOk = false; + QString errorMsg; + + // we can partly skip 1 here, as it is tested in checkInheritanceRestrictions() already + if (baseType->isComplexType()) { + + // 2.1 + if (baseType->name(m_namePool) == BuiltinTypes::xsAnyType->name(m_namePool)) { + derivationOk = true; + } + + if (baseType->isDefinedBySchema()) { + const XsdComplexType::Ptr complexBaseType(baseType); + + // 2.2.1 + if (complexType->contentType()->variety() == XsdComplexType::ContentType::Simple) { + // 2.2.2.1 + if (XsdSchemaHelper::isSimpleDerivationOk(complexType->contentType()->simpleType(), complexBaseType->contentType()->simpleType(), SchemaType::DerivationConstraints())) + derivationOk = true; + + // 2.2.2.2 + if (complexBaseType->contentType()->variety() == XsdComplexType::ContentType::Mixed) { + if (XsdSchemaHelper::isParticleEmptiable(complexBaseType->contentType()->particle())) + derivationOk = true; + } + } + + // 2.3.1 + if (complexType->contentType()->variety() == XsdComplexType::ContentType::Empty) { + // 2.3.2.1 + if (complexBaseType->contentType()->variety() == XsdComplexType::ContentType::Empty) + derivationOk = true; + + // 2.3.2.2 + if (complexBaseType->contentType()->variety() == XsdComplexType::ContentType::ElementOnly || complexBaseType->contentType()->variety() == XsdComplexType::ContentType::Mixed) { + if (XsdSchemaHelper::isParticleEmptiable(complexBaseType->contentType()->particle())) + derivationOk = true; + } + } + + // 2.4.1.1 + if (((complexType->contentType()->variety() == XsdComplexType::ContentType::ElementOnly) && + (complexBaseType->contentType()->variety() == XsdComplexType::ContentType::ElementOnly || complexBaseType->contentType()->variety() == XsdComplexType::ContentType::Mixed)) || + // 2.4.1.2 + (complexType->contentType()->variety() == XsdComplexType::ContentType::Mixed && complexBaseType->contentType()->variety() == XsdComplexType::ContentType::Mixed)) { + + // 2.4.2 + if (XsdParticleChecker::subsumes(complexBaseType->contentType()->particle(), complexType->contentType()->particle(), m_context, errorMsg)) + derivationOk = true; + } + } + } + + if (!derivationOk) { + m_context->error(QtXmlPatterns::tr("complex type %1 cannot be derived from base type %2%3") + .arg(formatType(m_namePool, complexType)) + .arg(formatType(m_namePool, baseType)) + .arg(errorMsg.isEmpty() ? QString() : QLatin1String(": ") + errorMsg), + XsdSchemaContext::XSDError, location); + return; + } + + if (baseType->isDefinedBySchema()) { + const XsdComplexType::Ptr complexBaseType(baseType); + + QString errorMsg; + if (!XsdSchemaHelper::isValidAttributeUsesRestriction(complexType->attributeUses(), complexBaseType->attributeUses(), + complexType->attributeWildcard(), complexBaseType->attributeWildcard(), m_context, errorMsg)) { + m_context->error(QtXmlPatterns::tr("attributes of complex type %1 are not a valid restriction from the attributes of base type %2: %3") + .arg(formatType(m_namePool, complexType)) + .arg(formatType(m_namePool, baseType)) + .arg(errorMsg), + XsdSchemaContext::XSDError, location); + return; + } + } + } + + // check that complex type with simple content is not allowed to inherit from + // built in complex type xs:AnyType + if (complexType->contentType()->variety() == XsdComplexType::ContentType::Simple) { + if (baseType->name(m_namePool) == BuiltinTypes::xsAnyType->name(m_namePool)) { + m_context->error(QtXmlPatterns::tr("complex type %1 with simple content cannot be derived from complex base type %2") + .arg(formatType(m_namePool, complexType)) + .arg(formatType(m_namePool, baseType)), + XsdSchemaContext::XSDError, location); + return; + } + } + } +} + +void XsdSchemaChecker::checkSimpleDerivationRestrictions() +{ + // check all global types... + SchemaType::List types = m_schema->types(); + + // .. and anonymous types + types << m_schema->anonymousTypes(); + + for (int i = 0; i < types.count(); ++i) { + const SchemaType::Ptr type = types.at(i); + + if (type->isComplexType()) + continue; + + if (type->category() != SchemaType::SimpleTypeList && type->category() != SchemaType::SimpleTypeUnion) + continue; + + const XsdSimpleType::Ptr simpleType = type; + const QSourceLocation location = sourceLocation(simpleType); + + // check all simple types derived by list + if (simpleType->category() == XsdSimpleType::SimpleTypeList) { + const AnySimpleType::Ptr itemType = simpleType->itemType(); + + if (itemType->isComplexType()) { + m_context->error(QtXmlPatterns::tr("item type of simple type %1 cannot be a complex type") + .arg(formatType(m_namePool, simpleType)), + XsdSchemaContext::XSDError, location); + return; + } + + + if (itemType->isSimpleType() && itemType->isDefinedBySchema()) { + const XsdSimpleType::Ptr simpleItemType = itemType; + if (simpleItemType->derivationConstraints() & XsdSimpleType::ListConstraint) { + m_context->error(QtXmlPatterns::tr("%1 is not allowed to derive from %2 by list as the latter defines it as final") + .arg(formatType(m_namePool, simpleType)) + .arg(formatType(m_namePool, simpleItemType)), + XsdSchemaContext::XSDError, location); + return; + } + } + + // @see http://www.w3.org/TR/xmlschema-2/#cos-list-of-atomic + if (itemType->category() != SchemaType::SimpleTypeAtomic && itemType->category() != SchemaType::SimpleTypeUnion) { + m_context->error(QtXmlPatterns::tr("variety of item type of %1 must be either atomic or union").arg(formatType(m_namePool, simpleType)), XsdSchemaContext::XSDError, location); + return; + } + + if (itemType->category() == SchemaType::SimpleTypeUnion && itemType->isDefinedBySchema()) { + const XsdSimpleType::Ptr simpleItemType = itemType; + const AnySimpleType::List memberTypes = simpleItemType->memberTypes(); + for (int j = 0; j < memberTypes.count(); ++j) { + if (memberTypes.at(j)->category() != SchemaType::SimpleTypeAtomic) { + m_context->error(QtXmlPatterns::tr("variety of member types of %1 must be atomic").arg(formatType(m_namePool, simpleItemType)), XsdSchemaContext::XSDError, location); + return; + } + } + } + } + + // check all simple types derived by union + if (simpleType->category() == XsdSimpleType::SimpleTypeUnion) { + const AnySimpleType::List memberTypes = simpleType->memberTypes(); + + for (int i = 0; i < memberTypes.count(); ++i) { + const AnySimpleType::Ptr memberType = memberTypes.at(i); + + if (memberType->isComplexType()) { + m_context->error(QtXmlPatterns::tr("member type of simple type %1 cannot be a complex type") + .arg(formatType(m_namePool, simpleType)), + XsdSchemaContext::XSDError, location); + return; + } + + // @see http://www.w3.org/TR/xmlschema-2/#cos-no-circular-unions + if (simpleType->name(m_namePool) == memberType->name(m_namePool)) { + m_context->error(QtXmlPatterns::tr("%1 is not allowed to have a member type with the same name as itself") + .arg(formatType(m_namePool, simpleType)), + XsdSchemaContext::XSDError, location); + return; + } + + if (memberType->isSimpleType() && memberType->isDefinedBySchema()) { + const XsdSimpleType::Ptr simpleMemberType = memberType; + if (simpleMemberType->derivationConstraints() & XsdSimpleType::UnionConstraint) { + m_context->error(QtXmlPatterns::tr("%1 is not allowed to derive from %2 by union as the latter defines it as final") + .arg(formatType(m_namePool, simpleType)) + .arg(formatType(m_namePool, simpleMemberType)), + XsdSchemaContext::XSDError, location); + return; + } + } + } + } + } +} + +void XsdSchemaChecker::checkConstrainingFacets() +{ + // first the global simple types + const SchemaType::List types = m_schema->types(); + for (int i = 0; i < types.count(); ++i) { + if (!(types.at(i)->isSimpleType()) || !(types.at(i)->isDefinedBySchema())) + continue; + + const XsdSimpleType::Ptr simpleType = types.at(i); + checkConstrainingFacets(simpleType->facets(), simpleType); + } + + // and afterwards all anonymous simple types + const SchemaType::List anonymousTypes = m_schema->anonymousTypes(); + for (int i = 0; i < anonymousTypes.count(); ++i) { + if (!(anonymousTypes.at(i)->isSimpleType()) || !(anonymousTypes.at(i)->isDefinedBySchema())) + continue; + + const XsdSimpleType::Ptr simpleType = anonymousTypes.at(i); + checkConstrainingFacets(simpleType->facets(), simpleType); + } +} + +void XsdSchemaChecker::checkConstrainingFacets(const XsdFacet::Hash &facets, const XsdSimpleType::Ptr &simpleType) +{ + if (facets.isEmpty()) + return; + + SchemaType::Ptr comparableBaseType; + if (!simpleType->wxsSuperType()->isDefinedBySchema()) + comparableBaseType = simpleType->wxsSuperType(); + else + comparableBaseType = simpleType->primitiveType(); + + const XsdSchemaSourceLocationReflection reflection(sourceLocation(simpleType)); + + // start checks + if (facets.contains(XsdFacet::Length)) { + const XsdFacet::Ptr lengthFacet = facets.value(XsdFacet::Length); + const DerivedInteger::Ptr lengthValue = lengthFacet->value(); + + // @see http://www.w3.org/TR/xmlschema-2/#length-minLength-maxLength + if (facets.contains(XsdFacet::MinimumLength)) { + const XsdFacet::Ptr minLengthFacet = facets.value(XsdFacet::MinimumLength); + const DerivedInteger::Ptr minLengthValue = minLengthFacet->value(); + + bool foundSuperMinimumLength = false; + SchemaType::Ptr baseType = simpleType->wxsSuperType(); + while (baseType) { + const XsdFacet::Hash baseFacets = m_context->facetsForType(baseType); + if (baseFacets.contains(XsdFacet::MinimumLength) && !baseFacets.contains(XsdFacet::Length)) { + const DerivedInteger::Ptr superValue(baseFacets.value(XsdFacet::MinimumLength)->value()); + if (minLengthValue->toInteger() == superValue->toInteger()) { + foundSuperMinimumLength = true; + break; + } + } + + baseType = baseType->wxsSuperType(); + } + + if ((minLengthValue->toInteger() > lengthValue->toInteger()) || !foundSuperMinimumLength) { + m_context->error(QtXmlPatterns::tr("%1 facet collides with %2 facet") + .arg(formatKeyword("length")) + .arg(formatKeyword("minLength")), + XsdSchemaContext::XSDError, sourceLocation(simpleType)); + return; + } + } + + // @see http://www.w3.org/TR/xmlschema-2/#length-minLength-maxLength + if (facets.contains(XsdFacet::MaximumLength)) { + const XsdFacet::Ptr maxLengthFacet = facets.value(XsdFacet::MaximumLength); + const DerivedInteger::Ptr maxLengthValue = maxLengthFacet->value(); + + bool foundSuperMaximumLength = false; + SchemaType::Ptr baseType = simpleType->wxsSuperType(); + while (baseType) { + const XsdFacet::Hash baseFacets = m_context->facetsForType(baseType); + if (baseFacets.contains(XsdFacet::MaximumLength) && !baseFacets.contains(XsdFacet::Length)) { + const DerivedInteger::Ptr superValue(baseFacets.value(XsdFacet::MaximumLength)->value()); + if (maxLengthValue->toInteger() == superValue->toInteger()) { + foundSuperMaximumLength = true; + break; + } + } + + baseType = baseType->wxsSuperType(); + } + + if ((maxLengthValue->toInteger() < lengthValue->toInteger()) || !foundSuperMaximumLength) { + m_context->error(QtXmlPatterns::tr("%1 facet collides with %2 facet") + .arg(formatKeyword("length")) + .arg(formatKeyword("maxLength")), + XsdSchemaContext::XSDError, sourceLocation(simpleType)); + return; + } + } + + // @see http://www.w3.org/TR/xmlschema-2/#length-valid-restriction + if (simpleType->derivationMethod() == XsdSimpleType::DerivationRestriction) { + const XsdFacet::Hash baseFacets = m_context->facetsForType(simpleType->wxsSuperType()); + if (baseFacets.contains(XsdFacet::Length)) { + const DerivedInteger::Ptr baseValue = baseFacets.value(XsdFacet::Length)->value(); + if (lengthValue->toInteger() != baseValue->toInteger()) { + m_context->error(QtXmlPatterns::tr("%1 facet must have the same value as %2 facet of base type") + .arg(formatKeyword("length")) + .arg(formatKeyword("length")), + XsdSchemaContext::XSDError, sourceLocation(simpleType)); + return; + } + } + } + } + + if (facets.contains(XsdFacet::MinimumLength)) { + const XsdFacet::Ptr minLengthFacet = facets.value(XsdFacet::MinimumLength); + const DerivedInteger::Ptr minLengthValue = minLengthFacet->value(); + + if (facets.contains(XsdFacet::MaximumLength)) { + const XsdFacet::Ptr maxLengthFacet = facets.value(XsdFacet::MaximumLength); + const DerivedInteger::Ptr maxLengthValue = maxLengthFacet->value(); + + // @see http://www.w3.org/TR/xmlschema-2/#minLength-less-than-equal-to-maxLength + if (maxLengthValue->toInteger() < minLengthValue->toInteger()) { + m_context->error(QtXmlPatterns::tr("%1 facet collides with %2 facet") + .arg(formatKeyword("minLength")) + .arg(formatKeyword("maxLength")), + XsdSchemaContext::XSDError, sourceLocation(simpleType)); + return; + } + + // @see http://www.w3.org/TR/xmlschema-2/#minLength-valid-restriction + //TODO: check parent facets + } + + // @see http://www.w3.org/TR/xmlschema-2/#minLength-valid-restriction + if (simpleType->derivationMethod() == XsdSimpleType::DerivationRestriction) { + const XsdFacet::Hash baseFacets = m_context->facetsForType(simpleType->wxsSuperType()); + if (baseFacets.contains(XsdFacet::MinimumLength)) { + const DerivedInteger::Ptr baseValue = baseFacets.value(XsdFacet::MinimumLength)->value(); + if (minLengthValue->toInteger() < baseValue->toInteger()) { + m_context->error(QtXmlPatterns::tr("%1 facet must be equal or greater than %2 facet of base type") + .arg(formatKeyword("minLength")) + .arg(formatKeyword("minLength")), + XsdSchemaContext::XSDError, sourceLocation(simpleType)); + return; + } + } + } + } + if (facets.contains(XsdFacet::MaximumLength)) { + const XsdFacet::Ptr maxLengthFacet = facets.value(XsdFacet::MaximumLength); + const DerivedInteger::Ptr maxLengthValue = maxLengthFacet->value(); + + // @see http://www.w3.org/TR/xmlschema-2/#maxLength-valid-restriction + if (simpleType->derivationMethod() == XsdSimpleType::DerivationRestriction) { + const XsdFacet::Hash baseFacets = m_context->facetsForType(simpleType->wxsSuperType()); + if (baseFacets.contains(XsdFacet::MaximumLength)) { + const DerivedInteger::Ptr baseValue(baseFacets.value(XsdFacet::MaximumLength)->value()); + if (maxLengthValue->toInteger() > baseValue->toInteger()) { + m_context->error(QtXmlPatterns::tr("%1 facet must be less than or equal to %2 facet of base type") + .arg(formatKeyword("maxLength")) + .arg(formatKeyword("maxLength")), + XsdSchemaContext::XSDError, sourceLocation(simpleType)); + return; + } + } + } + } + if (facets.contains(XsdFacet::Pattern)) { + // we keep the patterns in separated facets + // @see http://www.w3.org/TR/xmlschema-2/#src-multiple-patterns + + // @see http://www.w3.org/TR/xmlschema-2/#cvc-pattern-valid + const XsdFacet::Ptr patternFacet = facets.value(XsdFacet::Pattern); + const AtomicValue::List multiValue = patternFacet->multiValue(); + + for (int i = 0; i < multiValue.count(); ++i) { + const DerivedString::Ptr value = multiValue.at(i); + const QRegExp exp = PatternPlatform::parsePattern(value->stringValue(), m_context, &reflection); + if (!exp.isValid()) { + m_context->error(QtXmlPatterns::tr("%1 facet contains invalid regular expression").arg(formatKeyword("pattern")), XsdSchemaContext::XSDError, sourceLocation(simpleType)); + return; + } + } + } + if (facets.contains(XsdFacet::Enumeration)) { + // @see http://www.w3.org/TR/xmlschema-2/#src-multiple-enumerations + + const XsdFacet::Ptr facet = facets.value(XsdFacet::Enumeration); + + if (BuiltinTypes::xsNOTATION->wxsTypeMatches(simpleType)) { + const AtomicValue::List notationNames = facet->multiValue(); + for (int k = 0; k < notationNames.count(); ++k) { + const QNameValue::Ptr notationName = notationNames.at(k); + if (!m_schema->notation(notationName->qName())) { + m_context->error(QtXmlPatterns::tr("unknown notation %1 used in %2 facet") + .arg(formatKeyword(m_namePool, notationName->qName())) + .arg(formatKeyword("enumeration")), + XsdSchemaContext::XSDError, sourceLocation(simpleType)); + } + } + } else if (BuiltinTypes::xsQName->wxsTypeMatches(simpleType)) { + } else { + const XsdTypeChecker checker(m_context, QVector(), sourceLocation(simpleType)); + + const AnySimpleType::Ptr baseType = simpleType->wxsSuperType(); + const XsdFacet::Hash baseFacets = XsdTypeChecker::mergedFacetsForType(baseType, m_context); + + const AtomicValue::List multiValue = facet->multiValue(); + for (int k = 0; k < multiValue.count(); ++k) { + const QString stringValue = multiValue.at(k)->as >()->stringValue(); + const QString actualValue = XsdTypeChecker::normalizedValue(stringValue, baseFacets); + + QString errorMsg; + if (!checker.isValidString(actualValue, baseType, errorMsg)) { + m_context->error(QtXmlPatterns::tr("%1 facet contains invalid value %2: %3") + .arg(formatKeyword("enumeration")) + .arg(formatData(stringValue)) + .arg(errorMsg), + XsdSchemaContext::XSDError, sourceLocation(simpleType)); + return; + } + } + } + } + if (facets.contains(XsdFacet::WhiteSpace)) { + const XsdFacet::Ptr whiteSpaceFacet = facets.value(XsdFacet::WhiteSpace); + const DerivedString::Ptr whiteSpaceValue = whiteSpaceFacet->value(); + + // @see http://www.w3.org/TR/xmlschema-2/#whiteSpace-valid-restriction + if (simpleType->derivationMethod() == XsdSimpleType::DerivationRestriction) { + const XsdFacet::Hash baseFacets = m_context->facetsForType(simpleType->wxsSuperType()); + if (baseFacets.contains(XsdFacet::WhiteSpace)) { + const QString value = whiteSpaceValue->stringValue(); + const QString baseValue = DerivedString::Ptr(baseFacets.value(XsdFacet::WhiteSpace)->value())->stringValue(); + if (value == XsdSchemaToken::toString(XsdSchemaToken::Replace) || value == XsdSchemaToken::toString(XsdSchemaToken::Preserve)) { + if (baseValue == XsdSchemaToken::toString(XsdSchemaToken::Collapse)) { + m_context->error(QtXmlPatterns::tr("%1 facet cannot be %2 or %3 if %4 facet of base type is %5") + .arg(formatKeyword("whiteSpace")) + .arg(formatData("replace")) + .arg(formatData("preserve")) + .arg(formatKeyword("whiteSpace")) + .arg(formatData("collapse")), + XsdSchemaContext::XSDError, sourceLocation(simpleType)); + return; + } + } + if (value == XsdSchemaToken::toString(XsdSchemaToken::Preserve) && baseValue == XsdSchemaToken::toString(XsdSchemaToken::Replace)) { + m_context->error(QtXmlPatterns::tr("%1 facet cannot be %2 if %3 facet of base type is %4") + .arg(formatKeyword("whiteSpace")) + .arg(formatData("preserve")) + .arg(formatKeyword("whiteSpace")) + .arg(formatData("replace")), + XsdSchemaContext::XSDError, sourceLocation(simpleType)); + return; + } + } + } + } + if (facets.contains(XsdFacet::MaximumInclusive)) { + const XsdFacet::Ptr maxFacet = facets.value(XsdFacet::MaximumInclusive); + + // @see http://www.w3.org/TR/xmlschema-2/#minInclusive-less-than-equal-to-maxInclusive + if (facets.contains(XsdFacet::MinimumInclusive)) { + const XsdFacet::Ptr minFacet = facets.value(XsdFacet::MinimumInclusive); + + if (comparableBaseType) { + if (XsdSchemaHelper::constructAndCompare(minFacet->value(), AtomicComparator::OperatorGreaterThan, maxFacet->value(), comparableBaseType, m_context, &reflection)) { + m_context->error(QtXmlPatterns::tr("%1 facet must be less than or equal to %2 facet") + .arg(formatKeyword("minInclusive")) + .arg(formatKeyword("maxInclusive")), + XsdSchemaContext::XSDError, sourceLocation(simpleType)); + return; + } + } + } + + // @see http://www.w3.org/TR/xmlschema-2/#maxInclusive-valid-restriction + if (simpleType->derivationMethod() == XsdSimpleType::DerivationRestriction) { + const XsdFacet::Hash baseFacets = m_context->facetsForType(simpleType->wxsSuperType()); + if (baseFacets.contains(XsdFacet::MaximumInclusive)) { + const XsdFacet::Ptr baseFacet = baseFacets.value(XsdFacet::MaximumInclusive); + if (comparableBaseType) { + if (XsdSchemaHelper::constructAndCompare(maxFacet->value(), AtomicComparator::OperatorGreaterThan, baseFacet->value(), comparableBaseType, m_context, &reflection)) { + m_context->error(QtXmlPatterns::tr("%1 facet must be less than or equal to %2 facet of base type") + .arg(formatKeyword("maxInclusive")) + .arg(formatKeyword("maxInclusive")), + XsdSchemaContext::XSDError, sourceLocation(simpleType)); + return; + } + } + } + if (baseFacets.contains(XsdFacet::MaximumExclusive)) { + const XsdFacet::Ptr baseFacet = baseFacets.value(XsdFacet::MaximumExclusive); + if (comparableBaseType) { + if (XsdSchemaHelper::constructAndCompare(maxFacet->value(), AtomicComparator::OperatorGreaterOrEqual, baseFacet->value(), comparableBaseType, m_context, &reflection)) { + m_context->error(QtXmlPatterns::tr("%1 facet must be less than %2 facet of base type") + .arg(formatKeyword("maxInclusive")) + .arg(formatKeyword("maxExclusive")), + XsdSchemaContext::XSDError, sourceLocation(simpleType)); + return; + } + } + } + } + } + if (facets.contains(XsdFacet::MaximumExclusive)) { + const XsdFacet::Ptr maxFacet = facets.value(XsdFacet::MaximumExclusive); + + // @see http://www.w3.org/TR/xmlschema-2/#maxInclusive-maxExclusive + if (facets.contains(XsdFacet::MaximumInclusive)) { + m_context->error(QtXmlPatterns::tr("%1 facet and %2 facet cannot appear together") + .arg(formatKeyword("maxExclusive")) + .arg(formatKeyword("maxInclusive")), + XsdSchemaContext::XSDError, sourceLocation(simpleType)); + return; + } + + // @see http://www.w3.org/TR/xmlschema-2/#minExclusive-less-than-equal-to-maxExclusive + if (facets.contains(XsdFacet::MinimumExclusive)) { + const XsdFacet::Ptr minFacet = facets.value(XsdFacet::MinimumExclusive); + if (comparableBaseType) { + if (XsdSchemaHelper::constructAndCompare(minFacet->value(), AtomicComparator::OperatorGreaterThan, maxFacet->value(), comparableBaseType, m_context, &reflection)) { + m_context->error(QtXmlPatterns::tr("%1 facet must be less than or equal to %2 facet") + .arg(formatKeyword("minExclusive")) + .arg(formatKeyword("maxExclusive")), + XsdSchemaContext::XSDError, sourceLocation(simpleType)); + return; + } + } + } + + // @see http://www.w3.org/TR/xmlschema-2/#maxExclusive-valid-restriction + if (simpleType->derivationMethod() == XsdSimpleType::DerivationRestriction) { + const XsdFacet::Hash baseFacets = m_context->facetsForType(simpleType->wxsSuperType()); + if (baseFacets.contains(XsdFacet::MaximumExclusive)) { + const XsdFacet::Ptr baseFacet = baseFacets.value(XsdFacet::MaximumExclusive); + if (comparableBaseType) { + if (XsdSchemaHelper::constructAndCompare(maxFacet->value(), AtomicComparator::OperatorGreaterThan, baseFacet->value(), comparableBaseType, m_context, &reflection)) { + m_context->error(QtXmlPatterns::tr("%1 facet must be less than or equal to %2 facet of base type") + .arg(formatKeyword("maxExclusive")) + .arg(formatKeyword("maxExclusive")), + XsdSchemaContext::XSDError, sourceLocation(simpleType)); + return; + } + } + } + if (baseFacets.contains(XsdFacet::MaximumInclusive)) { + const XsdFacet::Ptr baseFacet = baseFacets.value(XsdFacet::MaximumInclusive); + if (comparableBaseType) { + if (XsdSchemaHelper::constructAndCompare(maxFacet->value(), AtomicComparator::OperatorGreaterThan, baseFacet->value(), comparableBaseType, m_context, &reflection)) { + m_context->error(QtXmlPatterns::tr("%1 facet must be less than or equal to %2 facet of base type") + .arg(formatKeyword("maxExclusive")) + .arg(formatKeyword("maxInclusive")), + XsdSchemaContext::XSDError, sourceLocation(simpleType)); + return; + } + } + } + if (baseFacets.contains(XsdFacet::MinimumInclusive)) { + const XsdFacet::Ptr baseFacet = baseFacets.value(XsdFacet::MinimumInclusive); + if (comparableBaseType) { + if (XsdSchemaHelper::constructAndCompare(maxFacet->value(), AtomicComparator::OperatorLessOrEqual, baseFacet->value(), comparableBaseType, m_context, &reflection)) { + m_context->error(QtXmlPatterns::tr("%1 facet must be greater than %2 facet of base type") + .arg(formatKeyword("maxExclusive")) + .arg(formatKeyword("minInclusive")), + XsdSchemaContext::XSDError, sourceLocation(simpleType)); + return; + } + } + } + if (baseFacets.contains(XsdFacet::MinimumExclusive)) { + const XsdFacet::Ptr baseFacet = baseFacets.value(XsdFacet::MinimumExclusive); + if (comparableBaseType) { + if (XsdSchemaHelper::constructAndCompare(maxFacet->value(), AtomicComparator::OperatorLessOrEqual, baseFacet->value(), comparableBaseType, m_context, &reflection)) { + m_context->error(QtXmlPatterns::tr("%1 facet must be greater than %2 facet of base type") + .arg(formatKeyword("maxExclusive")) + .arg(formatKeyword("minExclusive")), + XsdSchemaContext::XSDError, sourceLocation(simpleType)); + return; + } + } + } + } + } + if (facets.contains(XsdFacet::MinimumExclusive)) { + const XsdFacet::Ptr minFacet = facets.value(XsdFacet::MinimumExclusive); + + // @see http://www.w3.org/TR/xmlschema-2/#minInclusive-minExclusive + if (facets.contains(XsdFacet::MinimumInclusive)) { + m_context->error(QtXmlPatterns::tr("%1 facet and %2 facet cannot appear together") + .arg(formatKeyword("minExclusive")) + .arg(formatKeyword("minInclusive")), + XsdSchemaContext::XSDError, sourceLocation(simpleType)); + return; + } + + // @see http://www.w3.org/TR/xmlschema-2/#minExclusive-less-than-maxInclusive + if (facets.contains(XsdFacet::MaximumInclusive)) { + const XsdFacet::Ptr maxFacet = facets.value(XsdFacet::MaximumInclusive); + if (comparableBaseType) { + if (XsdSchemaHelper::constructAndCompare(minFacet->value(), AtomicComparator::OperatorGreaterOrEqual, maxFacet->value(), comparableBaseType, m_context, &reflection)) { + m_context->error(QtXmlPatterns::tr("%1 facet must be less than %2 facet") + .arg(formatKeyword("minExclusive")) + .arg(formatKeyword("maxInclusive")), + XsdSchemaContext::XSDError, sourceLocation(simpleType)); + return; + } + } + } + + // @see http://www.w3.org/TR/xmlschema-2/#minExclusive-valid-restriction + if (simpleType->derivationMethod() == XsdSimpleType::DerivationRestriction) { + const XsdFacet::Hash baseFacets = m_context->facetsForType(simpleType->wxsSuperType()); + if (baseFacets.contains(XsdFacet::MinimumExclusive)) { + const XsdFacet::Ptr baseFacet = baseFacets.value(XsdFacet::MinimumExclusive); + if (comparableBaseType) { + if (XsdSchemaHelper::constructAndCompare(minFacet->value(), AtomicComparator::OperatorLessThan, baseFacet->value(), comparableBaseType, m_context, &reflection)) { + m_context->error(QtXmlPatterns::tr("%1 facet must be greater than or equal to %2 facet of base type") + .arg(formatKeyword("minExclusive")) + .arg(formatKeyword("minExclusive")), + XsdSchemaContext::XSDError, sourceLocation(simpleType)); + return; + } + } + } + if (baseFacets.contains(XsdFacet::MaximumExclusive)) { + const XsdFacet::Ptr baseFacet = baseFacets.value(XsdFacet::MaximumExclusive); + if (comparableBaseType) { + if (XsdSchemaHelper::constructAndCompare(minFacet->value(), AtomicComparator::OperatorGreaterOrEqual, baseFacet->value(), comparableBaseType, m_context, &reflection)) { + m_context->error(QtXmlPatterns::tr("%1 facet must be less than %2 facet of base type") + .arg(formatKeyword("minExclusive")) + .arg(formatKeyword("maxExclusive")), + XsdSchemaContext::XSDError, sourceLocation(simpleType)); + return; + } + } + } + if (baseFacets.contains(XsdFacet::MaximumInclusive)) { + const XsdFacet::Ptr baseFacet = baseFacets.value(XsdFacet::MaximumInclusive); + if (comparableBaseType) { + if (XsdSchemaHelper::constructAndCompare(minFacet->value(), AtomicComparator::OperatorGreaterThan, baseFacet->value(), comparableBaseType, m_context, &reflection)) { + m_context->error(QtXmlPatterns::tr("%1 facet must be less than or equal to %2 facet of base type") + .arg(formatKeyword("minExclusive")) + .arg(formatKeyword("maxInclusive")), + XsdSchemaContext::XSDError, sourceLocation(simpleType)); + return; + } + } + } + } + } + if (facets.contains(XsdFacet::MinimumInclusive)) { + const XsdFacet::Ptr minFacet = facets.value(XsdFacet::MinimumInclusive); + + // @see http://www.w3.org/TR/xmlschema-2/#minInclusive-less-than-maxExclusive + if (facets.contains(XsdFacet::MaximumExclusive)) { + const XsdFacet::Ptr maxFacet = facets.value(XsdFacet::MaximumExclusive); + if (comparableBaseType) { + if (XsdSchemaHelper::constructAndCompare(minFacet->value(), AtomicComparator::OperatorGreaterOrEqual, maxFacet->value(), comparableBaseType, m_context, &reflection)) { + m_context->error(QtXmlPatterns::tr("%1 facet must be less than %2 facet") + .arg(formatKeyword("minInclusive")) + .arg(formatKeyword("maxExclusive")), + XsdSchemaContext::XSDError, sourceLocation(simpleType)); + return; + } + } + } + + // @see http://www.w3.org/TR/xmlschema-2/#minInclusive-valid-restriction + if (simpleType->derivationMethod() == XsdSimpleType::DerivationRestriction) { + const XsdFacet::Hash baseFacets = m_context->facetsForType(simpleType->wxsSuperType()); + if (baseFacets.contains(XsdFacet::MinimumInclusive)) { + const XsdFacet::Ptr baseFacet = baseFacets.value(XsdFacet::MinimumInclusive); + if (comparableBaseType) { + if (XsdSchemaHelper::constructAndCompare(minFacet->value(), AtomicComparator::OperatorLessThan, baseFacet->value(), comparableBaseType, m_context, &reflection)) { + m_context->error(QtXmlPatterns::tr("%1 facet must be greater than or equal to %2 facet of base type") + .arg(formatKeyword("minInclusive")) + .arg(formatKeyword("minInclusive")), + XsdSchemaContext::XSDError, sourceLocation(simpleType)); + return; + } + } + } + if (baseFacets.contains(XsdFacet::MinimumExclusive)) { + const XsdFacet::Ptr baseFacet = baseFacets.value(XsdFacet::MinimumExclusive); + if (comparableBaseType) { + if (XsdSchemaHelper::constructAndCompare(minFacet->value(), AtomicComparator::OperatorLessOrEqual, baseFacet->value(), comparableBaseType, m_context, &reflection)) { + m_context->error(QtXmlPatterns::tr("%1 facet must be greater than %2 facet of base type") + .arg(formatKeyword("minInclusive")) + .arg(formatKeyword("minExclusive")), + XsdSchemaContext::XSDError, sourceLocation(simpleType)); + return; + } + } + } + if (baseFacets.contains(XsdFacet::MaximumInclusive)) { + const XsdFacet::Ptr baseFacet = baseFacets.value(XsdFacet::MaximumInclusive); + if (comparableBaseType) { + if (XsdSchemaHelper::constructAndCompare(minFacet->value(), AtomicComparator::OperatorGreaterThan, baseFacet->value(), comparableBaseType, m_context, &reflection)) { + m_context->error(QtXmlPatterns::tr("%1 facet must be less than or equal to %2 facet of base type") + .arg(formatKeyword("minInclusive")) + .arg(formatKeyword("maxInclusive")), + XsdSchemaContext::XSDError, sourceLocation(simpleType)); + return; + } + } + } + if (baseFacets.contains(XsdFacet::MaximumExclusive)) { + const XsdFacet::Ptr baseFacet = baseFacets.value(XsdFacet::MaximumExclusive); + if (comparableBaseType) { + if (XsdSchemaHelper::constructAndCompare(minFacet->value(), AtomicComparator::OperatorGreaterOrEqual, baseFacet->value(), comparableBaseType, m_context, &reflection)) { + m_context->error(QtXmlPatterns::tr("%1 facet must be less than %2 facet of base type") + .arg(formatKeyword("minInclusive")) + .arg(formatKeyword("maxExclusive")), + XsdSchemaContext::XSDError, sourceLocation(simpleType)); + return; + } + } + } + } + } + if (facets.contains(XsdFacet::TotalDigits)) { + const XsdFacet::Ptr totalDigitsFacet = facets.value(XsdFacet::TotalDigits); + const DerivedInteger::Ptr totalDigitsValue = totalDigitsFacet->value(); + + // @see http://www.w3.org/TR/xmlschema-2/#totalDigits-valid-restriction + if (simpleType->derivationMethod() == XsdSimpleType::DerivationRestriction) { + const XsdFacet::Hash baseFacets = m_context->facetsForType(simpleType->wxsSuperType()); + if (baseFacets.contains(XsdFacet::TotalDigits)) { + const XsdFacet::Ptr baseFacet = baseFacets.value(XsdFacet::TotalDigits); + const DerivedInteger::Ptr baseValue = baseFacet->value(); + + if (totalDigitsValue->toInteger() > baseValue->toInteger()) { + m_context->error(QtXmlPatterns::tr("%1 facet must be less than or equal to %2 facet of base type") + .arg(formatKeyword("totalDigits")) + .arg(formatKeyword("totalDigits")), + XsdSchemaContext::XSDError, sourceLocation(simpleType)); + return; + } + } + } + } + if (facets.contains(XsdFacet::FractionDigits)) { + const XsdFacet::Ptr fractionDigitsFacet = facets.value(XsdFacet::FractionDigits); + const DerivedInteger::Ptr fractionDigitsValue = fractionDigitsFacet->value(); + + // http://www.w3.org/TR/xmlschema-2/#fractionDigits-totalDigits + if (facets.contains(XsdFacet::TotalDigits)) { + const XsdFacet::Ptr totalDigitsFacet = facets.value(XsdFacet::TotalDigits); + const DerivedInteger::Ptr totalDigitsValue = totalDigitsFacet->value(); + + if (fractionDigitsValue->toInteger() > totalDigitsValue->toInteger()) { + m_context->error(QtXmlPatterns::tr("%1 facet must be less than or equal to %2 facet") + .arg(formatKeyword("fractionDigits")) + .arg(formatKeyword("totalDigits")), + XsdSchemaContext::XSDError, sourceLocation(simpleType)); + return; + } + } + + // @see http://www.w3.org/TR/xmlschema-2/#fractionDigits-valid-restriction + if (simpleType->derivationMethod() == XsdSimpleType::DerivationRestriction) { + const XsdFacet::Hash baseFacets = m_context->facetsForType(simpleType->wxsSuperType()); + if (baseFacets.contains(XsdFacet::FractionDigits)) { + const XsdFacet::Ptr baseFacet = baseFacets.value(XsdFacet::FractionDigits); + const DerivedInteger::Ptr baseValue = baseFacet->value(); + + if (fractionDigitsValue->toInteger() > baseValue->toInteger()) { + m_context->error(QtXmlPatterns::tr("%1 facet must be less than or equal to %2 facet of base type") + .arg(formatKeyword("fractionDigits")) + .arg(formatKeyword("fractionDigits")), + XsdSchemaContext::XSDError, sourceLocation(simpleType)); + return; + } + } + } + } + + + // check whether facets are allowed for simple types variety + if (simpleType->wxsSuperType()->category() == SchemaType::SimpleTypeAtomic) { + if (simpleType->primitiveType()) { + const QXmlName primitiveTypeName = simpleType->primitiveType()->name(m_namePool); + if (m_allowedAtomicFacets.contains(primitiveTypeName)) { + const QSet allowedFacets = m_allowedAtomicFacets.value(primitiveTypeName); + QSet availableFacets = facets.keys().toSet(); + + if (!availableFacets.subtract(allowedFacets).isEmpty()) { + m_context->error(QtXmlPatterns::tr("simple type contains not allowed facet %1") + .arg(formatKeyword(XsdFacet::typeName(availableFacets.toList().first()))), + XsdSchemaContext::XSDError, sourceLocation(simpleType)); + return; + } + } + } + } else if (simpleType->wxsSuperType()->category() == SchemaType::SimpleTypeList) { + if (facets.contains(XsdFacet::MaximumInclusive) || facets.contains(XsdFacet::MinimumInclusive) || + facets.contains(XsdFacet::MaximumExclusive) || facets.contains(XsdFacet::MinimumExclusive) || + facets.contains(XsdFacet::TotalDigits) || facets.contains(XsdFacet::FractionDigits)) + { + m_context->error(QtXmlPatterns::tr("%1, %2, %3, %4, %5 and %6 facets are not allowed when derived by list") + .arg(formatKeyword("maxInclusive")) + .arg(formatKeyword("maxExclusive")) + .arg(formatKeyword("minInclusive")) + .arg(formatKeyword("minExclusive")) + .arg(formatKeyword("totalDigits")) + .arg(formatKeyword("fractionDigits")), + XsdSchemaContext::XSDError, sourceLocation(simpleType)); + } + } else if (simpleType->wxsSuperType()->category() == SchemaType::SimpleTypeUnion) { + if (facets.contains(XsdFacet::MaximumInclusive) || facets.contains(XsdFacet::MinimumInclusive) || + facets.contains(XsdFacet::MaximumExclusive) || facets.contains(XsdFacet::MinimumExclusive) || + facets.contains(XsdFacet::TotalDigits) || facets.contains(XsdFacet::FractionDigits) || + facets.contains(XsdFacet::MinimumLength) || facets.contains(XsdFacet::MaximumLength) || + facets.contains(XsdFacet::Length) || facets.contains(XsdFacet::WhiteSpace)) + { + m_context->error(QtXmlPatterns::tr("only %1 and %2 facets are allowed when derived by union") + .arg(formatKeyword("pattern")) + .arg(formatKeyword("enumeration")), + XsdSchemaContext::XSDError, sourceLocation(simpleType)); + } + } + + // check whether value of facet matches the value space of the simple types base type + const SchemaType::Ptr baseType = simpleType->wxsSuperType(); + if (!baseType->isDefinedBySchema()) { + const XsdSchemaSourceLocationReflection reflection(sourceLocation(simpleType)); + + XsdFacet::HashIterator it(facets); + while (it.hasNext()) { + it.next(); + const XsdFacet::Ptr facet = it.value(); + if (facet->type() == XsdFacet::MaximumInclusive || + facet->type() == XsdFacet::MaximumExclusive || + facet->type() == XsdFacet::MinimumInclusive || + facet->type() == XsdFacet::MinimumExclusive) { + const DerivedString::Ptr stringValue = facet->value(); + const AtomicValue::Ptr value = ValueFactory::fromLexical(stringValue->stringValue(), baseType, m_context, &reflection); + if (value->hasError()) { + m_context->error(QtXmlPatterns::tr("%1 contains %2 facet with invalid data: %3") + .arg(formatType(m_namePool, simpleType)) + .arg(formatKeyword(XsdFacet::typeName(facet->type()))) + .arg(formatData(stringValue->stringValue())), + XsdSchemaContext::XSDError, sourceLocation(simpleType)); + return; + } + } + + // @see http://www.w3.org/TR/xmlschema-2/#enumeration-valid-restriction + if (facet->type() == XsdFacet::Enumeration && baseType != BuiltinTypes::xsNOTATION) { + const AtomicValue::List multiValue = facet->multiValue(); + for (int j = 0; j < multiValue.count(); ++j) { + const QString stringValue = DerivedString::Ptr(multiValue.at(j))->stringValue(); + const AtomicValue::Ptr value = ValueFactory::fromLexical(stringValue, baseType, m_context, &reflection); + if (value->hasError()) { + m_context->error(QtXmlPatterns::tr("%1 contains %2 facet with invalid data: %3") + .arg(formatType(m_namePool, simpleType)) + .arg(formatKeyword(XsdFacet::typeName(XsdFacet::Enumeration))) + .arg(formatData(stringValue)), + XsdSchemaContext::XSDError, sourceLocation(simpleType)); + return; + } + } + } + } + } +} + +void XsdSchemaChecker::checkDuplicatedAttributeUses() +{ + // first all global attribute groups + const XsdAttributeGroup::List attributeGroups = m_schema->attributeGroups(); + for (int i = 0; i < attributeGroups.count(); ++i) { + const XsdAttributeGroup::Ptr attributeGroup = attributeGroups.at(i); + const XsdAttributeUse::List uses = attributeGroup->attributeUses(); + + // @see http://www.w3.org/TR/xmlschema11-1/#ct-props-correct 4) + XsdAttribute::Ptr conflictingAttribute; + if (hasDuplicatedAttributeUses(uses, conflictingAttribute)) { + m_context->error(QtXmlPatterns::tr("attribute group %1 contains attribute %2 twice") + .arg(formatKeyword(attributeGroup->displayName(m_namePool))) + .arg(formatKeyword(conflictingAttribute->displayName(m_namePool))), + XsdSchemaContext::XSDError, sourceLocation(attributeGroup)); + return; + } + + // @see http://www.w3.org/TR/xmlschema11-1/#ct-props-correct 5) + if (hasMultipleIDAttributeUses(uses)) { + m_context->error(QtXmlPatterns::tr("attribute group %1 contains two different attributes that both have types derived from %2") + .arg(formatKeyword(attributeGroup->displayName(m_namePool))) + .arg(formatType(m_namePool, BuiltinTypes::xsID)), + XsdSchemaContext::XSDError, sourceLocation(attributeGroup)); + return; + } + + if (hasConstraintIDAttributeUse(uses, conflictingAttribute)) { + m_context->error(QtXmlPatterns::tr("attribute group %1 contains attribute %2 that has value constraint but type that inherits from %3") + .arg(formatKeyword(attributeGroup->displayName(m_namePool))) + .arg(formatKeyword(conflictingAttribute->displayName(m_namePool))) + .arg(formatType(m_namePool, BuiltinTypes::xsID)), + XsdSchemaContext::XSDError, sourceLocation(attributeGroup)); + return; + } + } + + // then the global and anonymous complex types + SchemaType::List types = m_schema->types(); + types << m_schema->anonymousTypes(); + + for (int i = 0; i < types.count(); ++i) { + if (!(types.at(i)->isComplexType()) || !types.at(i)->isDefinedBySchema()) + continue; + + const XsdComplexType::Ptr complexType = types.at(i); + const XsdAttributeUse::List attributeUses = complexType->attributeUses(); + + // @see http://www.w3.org/TR/xmlschema11-1/#ct-props-correct 4) + XsdAttribute::Ptr conflictingAttribute; + if (hasDuplicatedAttributeUses(attributeUses, conflictingAttribute)) { + m_context->error(QtXmlPatterns::tr("complex type %1 contains attribute %2 twice") + .arg(formatType(m_namePool, complexType)) + .arg(formatKeyword(conflictingAttribute->displayName(m_namePool))), + XsdSchemaContext::XSDError, sourceLocation(complexType)); + return; + } + + // @see http://www.w3.org/TR/xmlschema11-1/#ct-props-correct 5) + if (hasMultipleIDAttributeUses(attributeUses)) { + m_context->error(QtXmlPatterns::tr("complex type %1 contains two different attributes that both have types derived from %2") + .arg(formatType(m_namePool, complexType)) + .arg(formatType(m_namePool, BuiltinTypes::xsID)), + XsdSchemaContext::XSDError, sourceLocation(complexType)); + return; + } + + if (hasConstraintIDAttributeUse(attributeUses, conflictingAttribute)) { + m_context->error(QtXmlPatterns::tr("complex type %1 contains attribute %2 that has value constraint but type that inherits from %3") + .arg(formatType(m_namePool, complexType)) + .arg(formatKeyword(conflictingAttribute->displayName(m_namePool))) + .arg(formatType(m_namePool, BuiltinTypes::xsID)), + XsdSchemaContext::XSDError, sourceLocation(complexType)); + return; + } + } +} + +void XsdSchemaChecker::checkElementConstraints() +{ + const QSet elements = collectAllElements(m_schema); + QSetIterator it(elements); + while (it.hasNext()) { + const XsdElement::Ptr element = it.next(); + + // @see http://www.w3.org/TR/xmlschema11-1/#e-props-correct + + // 2 and xs:ID check + if (element->valueConstraint()) { + const SchemaType::Ptr type = element->type(); + + AnySimpleType::Ptr targetType; + if (type->isSimpleType() && type->category() == SchemaType::SimpleTypeAtomic) { + targetType = type; + + // if it is a XsdSimpleType, use its primitive type as target type + if (type->isDefinedBySchema()) + targetType = XsdSimpleType::Ptr(type)->primitiveType(); + + } else if (type->isComplexType() && type->isDefinedBySchema()) { + const XsdComplexType::Ptr complexType(type); + + if (complexType->contentType()->variety() == XsdComplexType::ContentType::Simple) { + const AnySimpleType::Ptr simpleType = complexType->contentType()->simpleType(); + if (simpleType->category() == AnySimpleType::SimpleTypeAtomic) { + targetType = simpleType; + + if (simpleType->isDefinedBySchema()) + targetType = XsdSimpleType::Ptr(simpleType)->primitiveType(); + } + } else if (complexType->contentType()->variety() != XsdComplexType::ContentType::Mixed) { + m_context->error(QtXmlPatterns::tr("element %1 is not allowed to have a value constraint if its base type is complex") + .arg(formatKeyword(element->displayName(m_namePool))), + XsdSchemaContext::XSDError, sourceLocation(element)); + return; + } + } + if ((targetType == BuiltinTypes::xsID) || BuiltinTypes::xsID->wxsTypeMatches(type)) { + m_context->error(QtXmlPatterns::tr("element %1 is not allowed to have a value constraint if its type is derived from %2") + .arg(formatKeyword(element->displayName(m_namePool))) + .arg(formatType(m_namePool, BuiltinTypes::xsID)), + XsdSchemaContext::XSDError, sourceLocation(element)); + return; + } + + if (type->isSimpleType()) { + QString errorMsg; + if (!isValidValue(element->valueConstraint()->value(), type, errorMsg)) { + m_context->error(QtXmlPatterns::tr("value constraint of element %1 is not of elements type: %2") + .arg(formatKeyword(element->displayName(m_namePool))) + .arg(errorMsg), + XsdSchemaContext::XSDError, sourceLocation(element)); + return; + } + } else if (type->isComplexType() && type->isDefinedBySchema()) { + const XsdComplexType::Ptr complexType(type); + if (complexType->contentType()->variety() == XsdComplexType::ContentType::Simple) { + QString errorMsg; + if (!isValidValue(element->valueConstraint()->value(), complexType->contentType()->simpleType(), errorMsg)) { + m_context->error(QtXmlPatterns::tr("value constraint of element %1 is not of elements type: %2") + .arg(formatKeyword(element->displayName(m_namePool))) + .arg(errorMsg), + XsdSchemaContext::XSDError, sourceLocation(element)); + return; + } + } + } + } + + if (!element->substitutionGroupAffiliations().isEmpty()) { + // 3 + if (!element->scope() || element->scope()->variety() != XsdElement::Scope::Global) { + m_context->error(QtXmlPatterns::tr("element %1 is not allowed to have substitution group affiliation as it is no global element").arg(formatKeyword(element->displayName(m_namePool))), + XsdSchemaContext::XSDError, sourceLocation(element)); + return; + } + + // 4 + const XsdElement::List affiliations = element->substitutionGroupAffiliations(); + for (int i = 0; i < affiliations.count(); ++i) { + const XsdElement::Ptr affiliation = affiliations.at(i); + + bool derivationOk = false; + if (element->type()->isComplexType() && affiliation->type()->isComplexType()) { + if (XsdSchemaHelper::isComplexDerivationOk(element->type(), affiliation->type(), affiliation->substitutionGroupExclusions())) { + derivationOk = true; + } + } + if (element->type()->isComplexType() && affiliation->type()->isSimpleType()) { + if (XsdSchemaHelper::isComplexDerivationOk(element->type(), affiliation->type(), affiliation->substitutionGroupExclusions())) { + derivationOk = true; + } + } + if (element->type()->isSimpleType()) { + if (XsdSchemaHelper::isSimpleDerivationOk(element->type(), affiliation->type(), affiliation->substitutionGroupExclusions())) { + derivationOk = true; + } + } + + if (!derivationOk) { + m_context->error(QtXmlPatterns::tr("type of element %1 cannot be derived from type of substitution group affiliation").arg(formatKeyword(element->displayName(m_namePool))), + XsdSchemaContext::XSDError, sourceLocation(element)); + return; + } + } + + // 5 was checked in XsdSchemaResolver::resolveSubstitutionGroupAffiliations() already + } + } +} + +void XsdSchemaChecker::checkAttributeConstraints() +{ + // all global attributes + XsdAttribute::List attributes = m_schema->attributes(); + + // and all local attributes + SchemaType::List types = m_schema->types(); + types << m_schema->anonymousTypes(); + + for (int i = 0; i < types.count(); ++i) { + if (!types.at(i)->isComplexType() || !types.at(i)->isDefinedBySchema()) + continue; + + const XsdComplexType::Ptr complexType(types.at(i)); + const XsdAttributeUse::List uses = complexType->attributeUses(); + for (int j = 0; j < uses.count(); ++j) + attributes.append(uses.at(j)->attribute()); + } + + for (int i = 0; i < attributes.count(); ++i) { + const XsdAttribute::Ptr attribute = attributes.at(i); + + if (!attribute->valueConstraint()) + continue; + + if (attribute->valueConstraint()->variety() == XsdAttribute::ValueConstraint::Default || attribute->valueConstraint()->variety() == XsdAttribute::ValueConstraint::Fixed) { + const SchemaType::Ptr type = attribute->type(); + + QString errorMsg; + if (!isValidValue(attribute->valueConstraint()->value(), attribute->type(), errorMsg)) { + m_context->error(QtXmlPatterns::tr("value constraint of attribute %1 is not of attributes type: %2") + .arg(formatKeyword(attribute->displayName(m_namePool))) + .arg(errorMsg), + XsdSchemaContext::XSDError, sourceLocation(attribute)); + return; + } + } + + if (BuiltinTypes::xsID->wxsTypeMatches(attribute->type())) { + m_context->error(QtXmlPatterns::tr("attribute %1 has value constraint but has type derived from %2") + .arg(formatKeyword(attribute->displayName(m_namePool))) + .arg(formatType(m_namePool, BuiltinTypes::xsID)), + XsdSchemaContext::XSDError, sourceLocation(attribute)); + return; + } + } +} + +bool XsdSchemaChecker::isValidValue(const QString &stringValue, const AnySimpleType::Ptr &type, QString &errorMsg) const +{ + if (BuiltinTypes::xsAnySimpleType->name(m_namePool) == type->name(m_namePool)) + return true; // no need to check xs:anyType content + + const XsdFacet::Hash facets = XsdTypeChecker::mergedFacetsForType(type, m_context); + const QString actualValue = XsdTypeChecker::normalizedValue(stringValue, facets); + + const XsdTypeChecker checker(m_context, QVector(), QSourceLocation(QUrl(QLatin1String("http://dummy.org")), 1, 1)); + return checker.isValidString(actualValue, type, errorMsg); +} + +void XsdSchemaChecker::checkAttributeUseConstraints() +{ + XsdComplexType::List complexTypes; + + SchemaType::List types = m_schema->types(); + types << m_schema->anonymousTypes(); + + for (int i = 0; i < types.count(); ++i) { + const SchemaType::Ptr type = types.at(i); + if (type->isComplexType() && type->isDefinedBySchema()) + complexTypes.append(XsdComplexType::Ptr(type)); + } + + for (int i = 0; i < complexTypes.count(); ++i) { + const XsdComplexType::Ptr complexType(complexTypes.at(i)); + const SchemaType::Ptr baseType = complexType->wxsSuperType(); + if (!baseType || !baseType->isComplexType() || !baseType->isDefinedBySchema()) + continue; + + const XsdComplexType::Ptr complexBaseType(baseType); + + const XsdAttributeUse::List attributeUses = complexType->attributeUses(); + QHash lookupHash; + for (int j = 0; j < attributeUses.count(); ++j) + lookupHash.insert(attributeUses.at(j)->attribute()->name(m_namePool), attributeUses.at(j)); + + const XsdAttributeUse::List baseAttributeUses = complexBaseType->attributeUses(); + for (int j = 0; j < baseAttributeUses.count(); ++j) { + const XsdAttributeUse::Ptr baseAttributeUse = baseAttributeUses.at(j); + + if (lookupHash.contains(baseAttributeUse->attribute()->name(m_namePool))) { + const XsdAttributeUse::Ptr attributeUse = lookupHash.value(baseAttributeUse->attribute()->name(m_namePool)); + + if (baseAttributeUse->useType() == XsdAttributeUse::RequiredUse) { + if (attributeUse->useType() == XsdAttributeUse::OptionalUse || attributeUse->useType() == XsdAttributeUse::ProhibitedUse) { + m_context->error(QtXmlPatterns::tr("%1 attribute in derived complex type must be %2 like in base type") + .arg(formatAttribute("use")) + .arg(formatData("required")), + XsdSchemaContext::XSDError, sourceLocation(complexType)); + return; + } + } + + if (baseAttributeUse->valueConstraint()) { + if (baseAttributeUse->valueConstraint()->variety() == XsdAttributeUse::ValueConstraint::Fixed) { + if (!attributeUse->valueConstraint()) { + m_context->error(QtXmlPatterns::tr("attribute %1 in derived complex type must have %2 value constraint like in base type") + .arg(formatKeyword(attributeUse->attribute()->displayName(m_namePool))) + .arg(formatData("fixed")), + XsdSchemaContext::XSDError, sourceLocation(complexType)); + return; + } else { + if (attributeUse->valueConstraint()->variety() == XsdAttributeUse::ValueConstraint::Fixed) { + const XsdTypeChecker checker(m_context, QVector(), sourceLocation(complexType)); + if (!checker.valuesAreEqual(attributeUse->valueConstraint()->value(), baseAttributeUse->valueConstraint()->value(), attributeUse->attribute()->type())) { + m_context->error(QtXmlPatterns::tr("attribute %1 in derived complex type must have the same %2 value constraint like in base type") + .arg(formatKeyword(attributeUse->attribute()->displayName(m_namePool))) + .arg(formatData("fixed")), + XsdSchemaContext::XSDError, sourceLocation(complexType)); + return; + } + } else { + m_context->error(QtXmlPatterns::tr("attribute %1 in derived complex type must have %2 value constraint") + .arg(formatKeyword(attributeUse->attribute()->displayName(m_namePool))) + .arg(formatData("fixed")), + XsdSchemaContext::XSDError, sourceLocation(complexType)); + return; + } + } + } + } + } + } + + // additional check that process content property of attribute wildcard in derived type is + // not weaker than the wildcard in base type + const XsdWildcard::Ptr baseWildcard(complexBaseType->attributeWildcard()); + const XsdWildcard::Ptr derivedWildcard(complexType->attributeWildcard()); + if (baseWildcard && derivedWildcard) { + if (!XsdSchemaHelper::checkWildcardProcessContents(baseWildcard, derivedWildcard)) { + m_context->error(QtXmlPatterns::tr("processContent of base wildcard must be weaker than derived wildcard"), XsdSchemaContext::XSDError, sourceLocation(complexType)); + return; + } + } + } +} + +void XsdSchemaChecker::checkElementDuplicates() +{ + // check all global types... + SchemaType::List types = m_schema->types(); + + // .. and anonymous types + types << m_schema->anonymousTypes(); + + for (int i = 0; i < types.count(); ++i) { + const SchemaType::Ptr type = types.at(i); + + if (!type->isComplexType() || !type->isDefinedBySchema()) + continue; + + const XsdComplexType::Ptr complexType(type); + + if ((complexType->contentType()->variety() == XsdComplexType::ContentType::ElementOnly) || (complexType->contentType()->variety() == XsdComplexType::ContentType::Mixed)) { + DuplicatedElementMap elementMap; + DuplicatedWildcardMap wildcardMap; + + checkElementDuplicates(complexType->contentType()->particle(), elementMap, wildcardMap); + } + } +} + +void XsdSchemaChecker::checkElementDuplicates(const XsdParticle::Ptr &particle, DuplicatedElementMap &elementMap, DuplicatedWildcardMap &wildcardMap) +{ + if (particle->term()->isElement()) { + const XsdElement::Ptr element(particle->term()); + + if (elementMap.contains(element->name(m_namePool))) { + if (element->type() != elementMap.value(element->name(m_namePool))) { + m_context->error(QtXmlPatterns::tr("element %1 exists twice with different types") + .arg(formatKeyword(element->displayName(m_namePool))), + XsdSchemaContext::XSDError, sourceLocation(element)); + return; + } + } else { + elementMap.insert(element->name(m_namePool), element->type()); + } + + // check substitution group affiliation + const XsdElement::List substElements = element->substitutionGroupAffiliations(); + for (int i = 0; i < substElements.count(); ++i) { + const XsdElement::Ptr substElement = substElements.at(i); + if (elementMap.contains(substElement->name(m_namePool))) { + if (substElement->type() != elementMap.value(substElement->name(m_namePool))) { + m_context->error(QtXmlPatterns::tr("element %1 exists twice with different types") + .arg(formatKeyword(substElement->displayName(m_namePool))), + XsdSchemaContext::XSDError, sourceLocation(element)); + return; + } + } else { + elementMap.insert(substElement->name(m_namePool), substElement->type()); + } + } + } else if (particle->term()->isModelGroup()) { + const XsdModelGroup::Ptr group(particle->term()); + const XsdParticle::List particles = group->particles(); + for (int i = 0; i < particles.count(); ++i) + checkElementDuplicates(particles.at(i), elementMap, wildcardMap); + } else if (particle->term()->isWildcard()) { + const XsdWildcard::Ptr wildcard(particle->term()); + + bool error = false; + if (!wildcardMap.contains(wildcard->namespaceConstraint()->variety())) { + if (!wildcardMap.isEmpty()) + error = true; + } else { + const XsdWildcard::Ptr otherWildcard = wildcardMap.value(wildcard->namespaceConstraint()->variety()); + if ((wildcard->processContents() != otherWildcard->processContents()) || (wildcard->namespaceConstraint()->namespaces() != otherWildcard->namespaceConstraint()->namespaces())) + error = true; + } + + if (error) { + m_context->error(QtXmlPatterns::tr("particle contains non-deterministic wildcards"), XsdSchemaContext::XSDError, sourceLocation(wildcard)); + return; + } else { + wildcardMap.insert(wildcard->namespaceConstraint()->variety(), wildcard); + } + } +} + +QSourceLocation XsdSchemaChecker::sourceLocation(const NamedSchemaComponent::Ptr &component) const +{ + if (m_componentLocationHash.contains(component)) { + return m_componentLocationHash.value(component); + } else { + QSourceLocation location; + location.setLine(1); + location.setColumn(1); + location.setUri(QString::fromLatin1("dummyUri")); + + return location; + } +} + +QSourceLocation XsdSchemaChecker::sourceLocationForType(const SchemaType::Ptr &type) const +{ + if (type->isSimpleType()) + return sourceLocation(XsdSimpleType::Ptr(type)); + else + return sourceLocation(XsdComplexType::Ptr(type)); +} + +QT_END_NAMESPACE diff --git a/src/xmlpatterns/schema/qxsdschemachecker_helper.cpp b/src/xmlpatterns/schema/qxsdschemachecker_helper.cpp new file mode 100644 index 0000000..98c4c63 --- /dev/null +++ b/src/xmlpatterns/schema/qxsdschemachecker_helper.cpp @@ -0,0 +1,276 @@ +/**************************************************************************** +** +** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the $MODULE$ of the Qt Toolkit. +** +** $TROLLTECH_DUAL_LICENSE$ +** +****************************************************************************/ + +QT_BEGIN_NAMESPACE + +using namespace QPatternist; + +bool XsdSchemaChecker::hasDuplicatedAttributeUses(const XsdAttributeUse::List &list, XsdAttribute::Ptr &conflictingAttribute) const +{ + const int length = list.count(); + + for (int i = 0; i < length; ++i) { + for (int j = 0; j < length; ++j) { + if (i == j) + continue; + + if (list.at(i)->attribute()->name(m_namePool) == list.at(j)->attribute()->name(m_namePool)) { + conflictingAttribute = list.at(i)->attribute(); + return true; + } + } + } + + return false; +} + +bool XsdSchemaChecker::hasMultipleIDAttributeUses(const XsdAttributeUse::List &list) const +{ + const int length = list.count(); + + bool hasIdDerivedAttribute = false; + for (int i = 0; i < length; ++i) { + if (BuiltinTypes::xsID->wxsTypeMatches(list.at(i)->attribute()->type())) { + if (hasIdDerivedAttribute) + return true; + else + hasIdDerivedAttribute = true; + } + } + + return false; +} + +bool XsdSchemaChecker::hasConstraintIDAttributeUse(const XsdAttributeUse::List &list, XsdAttribute::Ptr &conflictingAttribute) const +{ + const int length = list.count(); + + for (int i = 0; i < length; ++i) { + const XsdAttributeUse::Ptr attributeUse(list.at(i)); + if (BuiltinTypes::xsID->wxsTypeMatches(attributeUse->attribute()->type())) { + if (attributeUse->valueConstraint()) { + conflictingAttribute = attributeUse->attribute(); + return true; + } + } + } + + return false; +} + +bool XsdSchemaChecker::particleEqualsRecursively(const XsdParticle::Ptr &particle, const XsdParticle::Ptr &otherParticle) const +{ + // @see http://www.w3.org/TR/xmlschema11-1/#cos-particle-extend + //TODO: find out what 'properties' of a particle should be checked here... + + if (particle->minimumOccurs() != otherParticle->minimumOccurs()) + return false; + + if (particle->maximumOccursUnbounded() != otherParticle->maximumOccursUnbounded()) + return false; + + if (particle->maximumOccurs() != otherParticle->maximumOccurs()) + return false; + + const XsdTerm::Ptr term = particle->term(); + const XsdTerm::Ptr otherTerm = otherParticle->term(); + + if (term->isElement() && !(otherTerm->isElement())) + return false; + + if (term->isModelGroup() && !(otherTerm->isModelGroup())) + return false; + + if (term->isWildcard() && !(otherTerm->isWildcard())) + return false; + + if (term->isElement()) { + const XsdElement::Ptr element = term; + const XsdElement::Ptr otherElement = otherTerm; + + if (element->name(m_namePool) != otherElement->name(m_namePool)) + return false; + + if (element->type()->name(m_namePool) != otherElement->type()->name(m_namePool)) + return false; + } + + if (term->isModelGroup()) { + const XsdModelGroup::Ptr group = term; + const XsdModelGroup::Ptr otherGroup = otherTerm; + + if (group->particles().count() != otherGroup->particles().count()) + return false; + + for (int i = 0; i < group->particles().count(); ++i) { + if (!particleEqualsRecursively(group->particles().at(i), otherGroup->particles().at(i))) + return false; + } + } + + if (term->isWildcard()) { + } + + return true; +} + +bool XsdSchemaChecker::isValidParticleExtension(const XsdParticle::Ptr &extension, const XsdParticle::Ptr &base) const +{ + // @see http://www.w3.org/TR/xmlschema11-1/#cos-particle-extend + + // 1 + if (extension == base) + return true; + + // 2 + if (extension->minimumOccurs() == 1 && extension->maximumOccurs() == 1 && extension->maximumOccursUnbounded() == false) { + if (extension->term()->isModelGroup()) { + const XsdModelGroup::Ptr modelGroup = extension->term(); + if (modelGroup->compositor() == XsdModelGroup::SequenceCompositor) { + if (particleEqualsRecursively(modelGroup->particles().first(), base)) + return true; + } + } + } + + // 3 + if (extension->minimumOccurs() == base->minimumOccurs()) { // 3.1 + if (extension->term()->isModelGroup() && base->term()->isModelGroup()) { + const XsdModelGroup::Ptr extensionGroup(extension->term()); + const XsdModelGroup::Ptr baseGroup(base->term()); + + if (extensionGroup->compositor() == XsdModelGroup::AllCompositor && baseGroup->compositor() == XsdModelGroup::AllCompositor) { + const XsdParticle::List extensionParticles = extensionGroup->particles(); + const XsdParticle::List baseParticles = baseGroup->particles(); + for (int i = 0; i < baseParticles.count() && i < extensionParticles.count(); ++i) { + if (baseParticles.at(i) != extensionParticles.at(i)) + return false; + } + } + } + } + + return false; +} + +QSet collectAllElements(const XsdParticle::Ptr &particle) +{ + QSet elements; + + const XsdTerm::Ptr term(particle->term()); + if (term->isElement()) { + elements.insert(XsdElement::Ptr(term)); + } else if (term->isModelGroup()) { + const XsdModelGroup::Ptr group(term); + + for (int i = 0; i < group->particles().count(); ++i) + elements.unite(collectAllElements(group->particles().at(i))); + } + + return elements; +} + +QSet collectAllElements(const XsdSchema::Ptr &schema) +{ + QSet elements; + + // collect global elements + const XsdElement::List elementList = schema->elements(); + for (int i = 0; i < elementList.count(); ++i) + elements.insert(elementList.at(i)); + + // collect all elements from global groups + const XsdModelGroup::List groupList = schema->elementGroups(); + for (int i = 0; i < groupList.count(); ++i) { + const XsdModelGroup::Ptr group(groupList.at(i)); + + for (int j = 0; j < group->particles().count(); ++j) + elements.unite(collectAllElements(group->particles().at(j))); + } + + // collect all elements from complex type definitions + SchemaType::List types; + types << schema->types() << schema->anonymousTypes(); + + for (int i = 0; i < types.count(); ++i) { + if (types.at(i)->isComplexType() && types.at(i)->isDefinedBySchema()) { + const XsdComplexType::Ptr complexType(types.at(i)); + if (complexType->contentType()->particle()) + elements.unite(collectAllElements(complexType->contentType()->particle())); + } + } + + return elements; +} + +bool XsdSchemaChecker::elementSequenceAccepted(const XsdModelGroup::Ptr &sequence, const XsdParticle::Ptr &particle) const +{ + // @see http://www.w3.org/TR/xmlschema11-1/#cvc-accept + + if (particle->term()->isWildcard()) { // 1 + const XsdWildcard::Ptr wildcard(particle->term()); + + // 1.1 + if ((unsigned int)sequence->particles().count() < particle->minimumOccurs()) + return false; + + // 1.2 + if (!particle->maximumOccursUnbounded()) { + if ((unsigned int)sequence->particles().count() > particle->maximumOccurs()) + return false; + } + + // 1.3 + const XsdParticle::List particles(sequence->particles()); + for (int i = 0; i < particles.count(); ++i) { + if (particles.at(i)->term()->isElement()) { + if (!XsdSchemaHelper::wildcardAllowsExpandedName(XsdElement::Ptr(particles.at(i)->term())->name(m_namePool), wildcard, m_namePool)) + return false; + } + } + } else if (particle->term()->isElement()) { // 2 + const XsdElement::Ptr element(particle->term()); + + // 2.1 + if ((unsigned int)sequence->particles().count() < particle->minimumOccurs()) + return false; + + // 2.2 + if (!particle->maximumOccursUnbounded()) { + if ((unsigned int)sequence->particles().count() > particle->maximumOccurs()) + return false; + } + + // 2.3 + const XsdParticle::List particles(sequence->particles()); + for (int i = 0; i < particles.count(); ++i) { + bool isValid = false; + if (particles.at(i)->term()->isElement()) { + const XsdElement::Ptr seqElement(particles.at(i)->term()); + + // 2.3.1 + if (element->name(m_namePool) == seqElement->name(m_namePool)) + isValid = true; + + // 2.3.2 + if (element->scope() && element->scope()->variety() == XsdElement::Scope::Global) { + if (!(element->disallowedSubstitutions() & NamedSchemaComponent::SubstitutionConstraint)) { + //TODO: continue + } + } + } + } + } + + return true; +} + +QT_END_NAMESPACE diff --git a/src/xmlpatterns/schema/qxsdschemachecker_p.h b/src/xmlpatterns/schema/qxsdschemachecker_p.h new file mode 100644 index 0000000..65fb87f --- /dev/null +++ b/src/xmlpatterns/schema/qxsdschemachecker_p.h @@ -0,0 +1,254 @@ +/**************************************************************************** +** +** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the $MODULE$ of the Qt Toolkit. +** +** $TROLLTECH_DUAL_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_XsdSchemaChecker_H +#define Patternist_XsdSchemaChecker_H + +#include "qschematype_p.h" +#include "qxsdattribute_p.h" +#include "qxsdattributegroup_p.h" +#include "qxsdelement_p.h" +#include "qxsdmodelgroup_p.h" +#include "qxsdnotation_p.h" +#include "qxsdschema_p.h" +#include "qxsdsimpletype_p.h" + +#include + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +namespace QPatternist +{ + class XsdSchemaContext; + class XsdSchemaParserContext; + + /** + * @short Encapsulates the checking of schema valitity after reference resolving has finished. + * + * @ingroup Patternist_schema + * @author Tobias Koenig + */ + class XsdSchemaChecker : public QSharedData + { + public: + typedef QExplicitlySharedDataPointer Ptr; + + /** + * Creates a new schema checker. + * + * @param context The context that is used for customization. + * @param parserContext The context that contains all the data structures. + */ + XsdSchemaChecker(const QExplicitlySharedDataPointer &context, const XsdSchemaParserContext *parserContext); + + /** + * Destroys the schema checker. + */ + ~XsdSchemaChecker(); + + /** + * Starts a basic check process. + * + * This check only validates the basic super type inheritance + * of simple and complex types. + */ + void basicCheck(); + + /** + * Starts the real check process. + */ + void check(); + + /** + * Checks the constraining facets of all global and anonymous simple types for validity. + */ + void checkConstrainingFacets(); + + /** + * Adds the component location hash, so the checker is able to report meaning full + * error messages. + */ + void addComponentLocationHash(const QHash &hash); + + private: + void checkSimpleRestrictionBaseType(); + + /** + * Checks that no simple or complex type inherits itself. + */ + void checkBasicCircularInheritances(); + + /** + * Checks the advanced circular inheritance. + */ + void checkCircularInheritances(); + + /** + * Checks for inheritance restrictions given by final or finalDefault + * attributes. + */ + void checkInheritanceRestrictions(); + + /** + * Checks for various constraints for simple types defined by schema. + */ + void checkBasicSimpleTypeConstraints(); + void checkSimpleTypeConstraints(); + + /** + * Checks for various constraints for complex types defined by schema. + */ + void checkBasicComplexTypeConstraints(); + void checkComplexTypeConstraints(); + + /** + * Checks for list and union derivation restrictions given by final or finalDefault + * attributes. + */ + void checkSimpleDerivationRestrictions(); + + /** + * Checks the set of constraining @p facets that belongs to @p simpleType for validity. + */ + void checkConstrainingFacets(const XsdFacet::Hash &facets, const XsdSimpleType::Ptr &simpleType); + + /** + * Checks for duplicated attribute uses (attributes with the same name) inside a complex type. + */ + void checkDuplicatedAttributeUses(); + + /** + * Check the element constraints. + */ + void checkElementConstraints(); + + /** + * Check the attribute constraints. + */ + void checkAttributeConstraints(); + + /** + * Check the attribute use constraints. + */ + void checkAttributeUseConstraints(); + + /** + * A map used to find duplicated elements inside a model group. + */ + typedef QHash DuplicatedElementMap; + + /** + * A map used to find duplicated wildcards inside a model group. + */ + typedef QHash DuplicatedWildcardMap; + + /** + * Check for duplicated elements and element wildcards in all complex type particles. + */ + void checkElementDuplicates(); + + /** + * Check for duplicated elements and element wildcards in the given @p particle. + * + * @param particle The particle to check. + * @param elementMap A map to find the duplicated elements. + * @param wildcardMap A map to find the duplicated element wildcards. + */ + void checkElementDuplicates(const XsdParticle::Ptr &particle, DuplicatedElementMap &elementMap, DuplicatedWildcardMap &wildcardMap); + + /** + * Setup fast lookup list for allowed facets of atomic simple types. + */ + void setupAllowedAtomicFacets(); + + /** + * Returns the source location of the given schema @p component or a dummy + * source location if the component is not found in the component location hash. + */ + QSourceLocation sourceLocation(const NamedSchemaComponent::Ptr &component) const; + + /** + * Returns the source location of the given schema @p type or a dummy + * source location if the type is not found in the component location hash. + */ + QSourceLocation sourceLocationForType(const SchemaType::Ptr &type) const; + + /** + * Checks that the string @p value is valid according the value space of @p type + * for the given @p component. + */ + bool isValidValue(const QString &value, const AnySimpleType::Ptr &type, QString &errorMsg) const; + + /** + * Returns the list of facets for the given @p type. + */ + XsdFacet::Hash facetsForType(const SchemaType::Ptr &type) const; + + /** + * Returns whether the given @p list of attribute uses contains two (or more) attribute + * uses that point to attributes with the same name. @p conflictingAttribute + * will contain the conflicting attribute in that case. + */ + bool hasDuplicatedAttributeUses(const XsdAttributeUse::List &list, XsdAttribute::Ptr &conflictingAttribute) const; + + /** + * Returns whether the given @p list of attribute uses contains two (or more) attribute + * uses that have a type inherited by xs:ID. + */ + bool hasMultipleIDAttributeUses(const XsdAttributeUse::List &list) const; + + /** + * Returns whether the given @p list of attribute uses contains an attribute + * uses that has a type inherited by xs:ID with a value constraint. @p conflictingAttribute + * will contain the conflicting attribute in that case. + */ + bool hasConstraintIDAttributeUse(const XsdAttributeUse::List &list, XsdAttribute::Ptr &conflictingAttribute) const; + + /** + * Checks whether the @p particle equals the @p otherParticle recursively. + */ + bool particleEqualsRecursively(const XsdParticle::Ptr &particle, const XsdParticle::Ptr &otherParticle) const; + + /** + * Checks whether the @p extension particle is a valid extension of the @p base particle. + */ + bool isValidParticleExtension(const XsdParticle::Ptr &extension, const XsdParticle::Ptr &base) const; + + /** + * Checks whether the @p sequence of elements is accepted by the given @p particle. + */ + bool elementSequenceAccepted(const XsdModelGroup::Ptr &sequence, const XsdParticle::Ptr &particle) const; + + QExplicitlySharedDataPointer m_context; + NamePool::Ptr m_namePool; + XsdSchema::Ptr m_schema; + QHash > m_allowedAtomicFacets; + QHash m_componentLocationHash; + }; +} + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif diff --git a/src/xmlpatterns/schema/qxsdschemachecker_setup.cpp b/src/xmlpatterns/schema/qxsdschemachecker_setup.cpp new file mode 100644 index 0000000..b027129 --- /dev/null +++ b/src/xmlpatterns/schema/qxsdschemachecker_setup.cpp @@ -0,0 +1,287 @@ + +#include "qxsdschemachecker_p.h" + +QT_BEGIN_NAMESPACE + +using namespace QPatternist; + +void XsdSchemaChecker::setupAllowedAtomicFacets() +{ + // string + { + QSet facets; + facets << XsdFacet::Length + << XsdFacet::MinimumLength + << XsdFacet::MaximumLength + << XsdFacet::Pattern + << XsdFacet::Enumeration + << XsdFacet::WhiteSpace + << XsdFacet::Assertion; + + m_allowedAtomicFacets.insert(BuiltinTypes::xsString->name(m_namePool), facets); + } + + // boolean + { + QSet facets; + facets << XsdFacet::Pattern + << XsdFacet::WhiteSpace + << XsdFacet::Assertion; + + m_allowedAtomicFacets.insert(BuiltinTypes::xsBoolean->name(m_namePool), facets); + } + + // float + { + QSet facets; + facets << XsdFacet::Pattern + << XsdFacet::Enumeration + << XsdFacet::WhiteSpace + << XsdFacet::MaximumInclusive + << XsdFacet::MaximumExclusive + << XsdFacet::MinimumInclusive + << XsdFacet::MinimumExclusive + << XsdFacet::Assertion; + + m_allowedAtomicFacets.insert(BuiltinTypes::xsFloat->name(m_namePool), facets); + } + + // double + { + QSet facets; + facets << XsdFacet::Pattern + << XsdFacet::Enumeration + << XsdFacet::WhiteSpace + << XsdFacet::MaximumInclusive + << XsdFacet::MaximumExclusive + << XsdFacet::MinimumInclusive + << XsdFacet::MinimumExclusive + << XsdFacet::Assertion; + + m_allowedAtomicFacets.insert(BuiltinTypes::xsDouble->name(m_namePool), facets); + } + + // decimal + { + QSet facets; + facets << XsdFacet::TotalDigits + << XsdFacet::FractionDigits + << XsdFacet::Pattern + << XsdFacet::Enumeration + << XsdFacet::WhiteSpace + << XsdFacet::MaximumInclusive + << XsdFacet::MaximumExclusive + << XsdFacet::MinimumInclusive + << XsdFacet::MinimumExclusive + << XsdFacet::Assertion; + + m_allowedAtomicFacets.insert(BuiltinTypes::xsDecimal->name(m_namePool), facets); + } + + // duration + { + QSet facets; + facets << XsdFacet::Pattern + << XsdFacet::Enumeration + << XsdFacet::WhiteSpace + << XsdFacet::MaximumInclusive + << XsdFacet::MaximumExclusive + << XsdFacet::MinimumInclusive + << XsdFacet::MinimumExclusive + << XsdFacet::Assertion; + + m_allowedAtomicFacets.insert(BuiltinTypes::xsDuration->name(m_namePool), facets); + } + + // dateTime + { + QSet facets; + facets << XsdFacet::Pattern + << XsdFacet::Enumeration + << XsdFacet::WhiteSpace + << XsdFacet::MaximumInclusive + << XsdFacet::MaximumExclusive + << XsdFacet::MinimumInclusive + << XsdFacet::MinimumExclusive + << XsdFacet::Assertion; + + m_allowedAtomicFacets.insert(BuiltinTypes::xsDateTime->name(m_namePool), facets); + } + + // time + { + QSet facets; + facets << XsdFacet::Pattern + << XsdFacet::Enumeration + << XsdFacet::WhiteSpace + << XsdFacet::MaximumInclusive + << XsdFacet::MaximumExclusive + << XsdFacet::MinimumInclusive + << XsdFacet::MinimumExclusive + << XsdFacet::Assertion; + + m_allowedAtomicFacets.insert(BuiltinTypes::xsTime->name(m_namePool), facets); + } + + // date + { + QSet facets; + facets << XsdFacet::Pattern + << XsdFacet::Enumeration + << XsdFacet::WhiteSpace + << XsdFacet::MaximumInclusive + << XsdFacet::MaximumExclusive + << XsdFacet::MinimumInclusive + << XsdFacet::MinimumExclusive + << XsdFacet::Assertion; + + m_allowedAtomicFacets.insert(BuiltinTypes::xsDate->name(m_namePool), facets); + } + + // gYearMonth + { + QSet facets; + facets << XsdFacet::Pattern + << XsdFacet::Enumeration + << XsdFacet::WhiteSpace + << XsdFacet::MaximumInclusive + << XsdFacet::MaximumExclusive + << XsdFacet::MinimumInclusive + << XsdFacet::MinimumExclusive + << XsdFacet::Assertion; + + m_allowedAtomicFacets.insert(BuiltinTypes::xsGYearMonth->name(m_namePool), facets); + } + + // gYear + { + QSet facets; + facets << XsdFacet::Pattern + << XsdFacet::Enumeration + << XsdFacet::WhiteSpace + << XsdFacet::MaximumInclusive + << XsdFacet::MaximumExclusive + << XsdFacet::MinimumInclusive + << XsdFacet::MinimumExclusive + << XsdFacet::Assertion; + + m_allowedAtomicFacets.insert(BuiltinTypes::xsGYear->name(m_namePool), facets); + } + + // gMonthDay + { + QSet facets; + facets << XsdFacet::Pattern + << XsdFacet::Enumeration + << XsdFacet::WhiteSpace + << XsdFacet::MaximumInclusive + << XsdFacet::MaximumExclusive + << XsdFacet::MinimumInclusive + << XsdFacet::MinimumExclusive + << XsdFacet::Assertion; + + m_allowedAtomicFacets.insert(BuiltinTypes::xsGMonthDay->name(m_namePool), facets); + } + + // gDay + { + QSet facets; + facets << XsdFacet::Pattern + << XsdFacet::Enumeration + << XsdFacet::WhiteSpace + << XsdFacet::MaximumInclusive + << XsdFacet::MaximumExclusive + << XsdFacet::MinimumInclusive + << XsdFacet::MinimumExclusive + << XsdFacet::Assertion; + + m_allowedAtomicFacets.insert(BuiltinTypes::xsGDay->name(m_namePool), facets); + } + + // gMonth + { + QSet facets; + facets << XsdFacet::Pattern + << XsdFacet::Enumeration + << XsdFacet::WhiteSpace + << XsdFacet::MaximumInclusive + << XsdFacet::MaximumExclusive + << XsdFacet::MinimumInclusive + << XsdFacet::MinimumExclusive + << XsdFacet::Assertion; + + m_allowedAtomicFacets.insert(BuiltinTypes::xsGMonth->name(m_namePool), facets); + } + + // hexBinary + { + QSet facets; + facets << XsdFacet::Length + << XsdFacet::MinimumLength + << XsdFacet::MaximumLength + << XsdFacet::Pattern + << XsdFacet::Enumeration + << XsdFacet::WhiteSpace + << XsdFacet::Assertion; + + m_allowedAtomicFacets.insert(BuiltinTypes::xsHexBinary->name(m_namePool), facets); + } + + // base64Binary + { + QSet facets; + facets << XsdFacet::Length + << XsdFacet::MinimumLength + << XsdFacet::MaximumLength + << XsdFacet::Pattern + << XsdFacet::Enumeration + << XsdFacet::WhiteSpace + << XsdFacet::Assertion; + + m_allowedAtomicFacets.insert(BuiltinTypes::xsBase64Binary->name(m_namePool), facets); + } + + // anyURI + { + QSet facets; + facets << XsdFacet::Length + << XsdFacet::MinimumLength + << XsdFacet::MaximumLength + << XsdFacet::Pattern + << XsdFacet::Enumeration + << XsdFacet::WhiteSpace + << XsdFacet::Assertion; + + m_allowedAtomicFacets.insert(BuiltinTypes::xsAnyURI->name(m_namePool), facets); + } + + // QName + { + QSet facets; + facets << XsdFacet::Length + << XsdFacet::MinimumLength + << XsdFacet::MaximumLength + << XsdFacet::Pattern + << XsdFacet::Enumeration + << XsdFacet::WhiteSpace + << XsdFacet::Assertion; + + m_allowedAtomicFacets.insert(BuiltinTypes::xsQName->name(m_namePool), facets); + } + + // NOTATION + { + QSet facets; + facets << XsdFacet::Length + << XsdFacet::MinimumLength + << XsdFacet::MaximumLength + << XsdFacet::Pattern + << XsdFacet::Enumeration + << XsdFacet::WhiteSpace + << XsdFacet::Assertion; + + m_allowedAtomicFacets.insert(BuiltinTypes::xsNOTATION->name(m_namePool), facets); + } +} + +QT_END_NAMESPACE diff --git a/src/xmlpatterns/schema/qxsdschemacontext.cpp b/src/xmlpatterns/schema/qxsdschemacontext.cpp new file mode 100644 index 0000000..57736bd --- /dev/null +++ b/src/xmlpatterns/schema/qxsdschemacontext.cpp @@ -0,0 +1,498 @@ +/**************************************************************************** +** +** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the $MODULE$ of the Qt Toolkit. +** +** $TROLLTECH_DUAL_LICENSE$ +** +****************************************************************************/ + +#include "qxsdschemacontext_p.h" + +#include "qderivedinteger_p.h" +#include "qderivedstring_p.h" +#include "qxsdschematypesfactory_p.h" + +QT_BEGIN_NAMESPACE + +using namespace QPatternist; + +XsdSchemaContext::XsdSchemaContext(const NamePool::Ptr &namePool) + : m_namePool(namePool) + , m_networkAccessManager(0) + , m_uriResolver(0) + , m_messageHandler(0) +{ +} + +NamePool::Ptr XsdSchemaContext::namePool() const +{ + return m_namePool; +} + +QUrl XsdSchemaContext::baseURI() const +{ + return m_baseURI; +} + +void XsdSchemaContext::setBaseURI(const QUrl &uri) +{ + m_baseURI = uri; +} + +void XsdSchemaContext::setNetworkAccessManager(QNetworkAccessManager *accessManager) +{ + m_networkAccessManager = accessManager; +} + +QNetworkAccessManager* XsdSchemaContext::networkAccessManager() const +{ + return m_networkAccessManager; +} + +void XsdSchemaContext::setMessageHandler(QAbstractMessageHandler *handler) +{ + m_messageHandler = handler; +} + +QAbstractMessageHandler* XsdSchemaContext::messageHandler() const +{ + return m_messageHandler; +} + +QSourceLocation XsdSchemaContext::locationFor(const SourceLocationReflection *const) const +{ + return QSourceLocation(); +} + +void XsdSchemaContext::setUriResolver(QAbstractUriResolver *uriResolver) +{ + m_uriResolver = uriResolver; +} + +const QAbstractUriResolver* XsdSchemaContext::uriResolver() const +{ + return m_uriResolver; +} + +XsdFacet::Hash XsdSchemaContext::facetsForType(const AnySimpleType::Ptr &type) const +{ + if (type->isDefinedBySchema()) + return XsdSimpleType::Ptr(type)->facets(); + else { + if (m_builtinTypesFacetList.isEmpty()) + m_builtinTypesFacetList = setupBuiltinTypesFacetList(); + + return m_builtinTypesFacetList.value(type); + } +} + +SchemaTypeFactory::Ptr XsdSchemaContext::schemaTypeFactory() const +{ + if (!m_schemaTypeFactory) + m_schemaTypeFactory = SchemaTypeFactory::Ptr(new XsdSchemaTypesFactory(m_namePool)); + + return m_schemaTypeFactory; +} + +QHash XsdSchemaContext::setupBuiltinTypesFacetList() const +{ + QHash hash; + + const XsdFacet::Ptr fixedCollapseWhiteSpace(new XsdFacet()); + fixedCollapseWhiteSpace->setType(XsdFacet::WhiteSpace); + fixedCollapseWhiteSpace->setValue(DerivedString::fromLexical(m_namePool, XsdSchemaToken::toString(XsdSchemaToken::Collapse))); + fixedCollapseWhiteSpace->setFixed(true); + + const XsdFacet::Ptr collapseWhiteSpace(new XsdFacet()); + collapseWhiteSpace->setType(XsdFacet::WhiteSpace); + collapseWhiteSpace->setValue(DerivedString::fromLexical(m_namePool, XsdSchemaToken::toString(XsdSchemaToken::Collapse))); + collapseWhiteSpace->setFixed(false); + + const XsdFacet::Ptr preserveWhiteSpace(new XsdFacet()); + preserveWhiteSpace->setType(XsdFacet::WhiteSpace); + preserveWhiteSpace->setValue(DerivedString::fromLexical(m_namePool, XsdSchemaToken::toString(XsdSchemaToken::Preserve))); + preserveWhiteSpace->setFixed(false); + + const XsdFacet::Ptr replaceWhiteSpace(new XsdFacet()); + replaceWhiteSpace->setType(XsdFacet::WhiteSpace); + replaceWhiteSpace->setValue(DerivedString::fromLexical(m_namePool, XsdSchemaToken::toString(XsdSchemaToken::Replace))); + replaceWhiteSpace->setFixed(false); + + const XsdFacet::Ptr fixedZeroFractionDigits(new XsdFacet()); + fixedZeroFractionDigits->setType(XsdFacet::FractionDigits); + fixedZeroFractionDigits->setValue(DerivedInteger::fromValue(m_namePool, 0)); + fixedZeroFractionDigits->setFixed(true); + + { + XsdFacet::Hash &facets = hash[BuiltinTypes::xsString]; + facets.insert(preserveWhiteSpace->type(), preserveWhiteSpace); + } + + { + XsdFacet::Hash &facets = hash[BuiltinTypes::xsBoolean]; + facets.insert(fixedCollapseWhiteSpace->type(), fixedCollapseWhiteSpace); + } + + { + XsdFacet::Hash &facets = hash[BuiltinTypes::xsDecimal]; + facets.insert(fixedCollapseWhiteSpace->type(), fixedCollapseWhiteSpace); + } + + { + XsdFacet::Hash &facets = hash[BuiltinTypes::xsFloat]; + facets.insert(fixedCollapseWhiteSpace->type(), fixedCollapseWhiteSpace); + } + + { + XsdFacet::Hash &facets = hash[BuiltinTypes::xsDouble]; + facets.insert(fixedCollapseWhiteSpace->type(), fixedCollapseWhiteSpace); + } + + { + XsdFacet::Hash &facets = hash[BuiltinTypes::xsDuration]; + facets.insert(fixedCollapseWhiteSpace->type(), fixedCollapseWhiteSpace); + } + + { + XsdFacet::Hash &facets = hash[BuiltinTypes::xsDateTime]; + facets.insert(fixedCollapseWhiteSpace->type(), fixedCollapseWhiteSpace); + } + + { + XsdFacet::Hash &facets = hash[BuiltinTypes::xsTime]; + facets.insert(fixedCollapseWhiteSpace->type(), fixedCollapseWhiteSpace); + } + + { + XsdFacet::Hash &facets = hash[BuiltinTypes::xsDate]; + facets.insert(fixedCollapseWhiteSpace->type(), fixedCollapseWhiteSpace); + } + + { + XsdFacet::Hash &facets = hash[BuiltinTypes::xsGYearMonth]; + facets.insert(fixedCollapseWhiteSpace->type(), fixedCollapseWhiteSpace); + } + + { + XsdFacet::Hash &facets = hash[BuiltinTypes::xsGYear]; + facets.insert(fixedCollapseWhiteSpace->type(), fixedCollapseWhiteSpace); + } + + { + XsdFacet::Hash &facets = hash[BuiltinTypes::xsGMonthDay]; + facets.insert(fixedCollapseWhiteSpace->type(), fixedCollapseWhiteSpace); + } + + { + XsdFacet::Hash &facets = hash[BuiltinTypes::xsGDay]; + facets.insert(fixedCollapseWhiteSpace->type(), fixedCollapseWhiteSpace); + } + + { + XsdFacet::Hash &facets = hash[BuiltinTypes::xsGMonth]; + facets.insert(fixedCollapseWhiteSpace->type(), fixedCollapseWhiteSpace); + } + + { + XsdFacet::Hash &facets = hash[BuiltinTypes::xsHexBinary]; + facets.insert(fixedCollapseWhiteSpace->type(), fixedCollapseWhiteSpace); + } + + { + XsdFacet::Hash &facets = hash[BuiltinTypes::xsBase64Binary]; + facets.insert(fixedCollapseWhiteSpace->type(), fixedCollapseWhiteSpace); + } + + { + XsdFacet::Hash &facets = hash[BuiltinTypes::xsAnyURI]; + facets.insert(fixedCollapseWhiteSpace->type(), fixedCollapseWhiteSpace); + } + + { + XsdFacet::Hash &facets = hash[BuiltinTypes::xsQName]; + facets.insert(fixedCollapseWhiteSpace->type(), fixedCollapseWhiteSpace); + } + + { + XsdFacet::Hash &facets = hash[BuiltinTypes::xsNOTATION]; + facets.insert(fixedCollapseWhiteSpace->type(), fixedCollapseWhiteSpace); + } + + { + XsdFacet::Hash &facets = hash[BuiltinTypes::xsNormalizedString]; + facets.insert(replaceWhiteSpace->type(), replaceWhiteSpace); + } + + { + XsdFacet::Hash &facets = hash[BuiltinTypes::xsToken]; + facets.insert(collapseWhiteSpace->type(), collapseWhiteSpace); + } + + { + XsdFacet::Hash &facets = hash[BuiltinTypes::xsLanguage]; + facets.insert(collapseWhiteSpace->type(), collapseWhiteSpace); + + const XsdFacet::Ptr pattern(new XsdFacet()); + pattern->setType(XsdFacet::Pattern); + pattern->setMultiValue(AtomicValue::List() << DerivedString::fromLexical(m_namePool, QString::fromLatin1("[a-zA-Z]{1,8}(-[a-zA-Z0-9]{1,8})*"))); + facets.insert(pattern->type(), pattern); + } + + { + XsdFacet::Hash &facets = hash[BuiltinTypes::xsNMTOKEN]; + facets.insert(collapseWhiteSpace->type(), collapseWhiteSpace); + + const XsdFacet::Ptr pattern(new XsdFacet()); + pattern->setType(XsdFacet::Pattern); + pattern->setMultiValue(AtomicValue::List() << DerivedString::fromLexical(m_namePool, QString::fromLatin1("\\c+"))); + facets.insert(pattern->type(), pattern); + } + + { + XsdFacet::Hash &facets = hash[BuiltinTypes::xsName]; + facets.insert(collapseWhiteSpace->type(), collapseWhiteSpace); + + const XsdFacet::Ptr pattern(new XsdFacet()); + pattern->setType(XsdFacet::Pattern); + pattern->setMultiValue(AtomicValue::List() << DerivedString::fromLexical(m_namePool, QString::fromLatin1("\\i\\c*"))); + facets.insert(pattern->type(), pattern); + } + + const XsdFacet::Ptr ncNamePattern(new XsdFacet()); + { + ncNamePattern->setType(XsdFacet::Pattern); + AtomicValue::List patterns; + patterns << DerivedString::fromLexical(m_namePool, QString::fromLatin1("\\i\\c*")); + patterns << DerivedString::fromLexical(m_namePool, QString::fromLatin1("[\\i-[:]][\\c-[:]]*")); + ncNamePattern->setMultiValue(patterns); + } + + { + XsdFacet::Hash &facets = hash[BuiltinTypes::xsNCName]; + facets.insert(collapseWhiteSpace->type(), collapseWhiteSpace); + facets.insert(ncNamePattern->type(), ncNamePattern); + } + + { + XsdFacet::Hash &facets = hash[BuiltinTypes::xsID]; + facets.insert(collapseWhiteSpace->type(), collapseWhiteSpace); + facets.insert(ncNamePattern->type(), ncNamePattern); + } + + { + XsdFacet::Hash &facets = hash[BuiltinTypes::xsIDREF]; + facets.insert(collapseWhiteSpace->type(), collapseWhiteSpace); + facets.insert(ncNamePattern->type(), ncNamePattern); + } + + { + XsdFacet::Hash &facets = hash[BuiltinTypes::xsENTITY]; + facets.insert(collapseWhiteSpace->type(), collapseWhiteSpace); + facets.insert(ncNamePattern->type(), ncNamePattern); + } + + const XsdFacet::Ptr integerPattern(new XsdFacet()); + integerPattern->setType(XsdFacet::Pattern); + integerPattern->setMultiValue(AtomicValue::List() << DerivedString::fromLexical(m_namePool, QString::fromLatin1("[\\-+]?[0-9]+"))); + + { + XsdFacet::Hash &facets = hash[BuiltinTypes::xsInteger]; + facets.insert(fixedCollapseWhiteSpace->type(), fixedCollapseWhiteSpace); + facets.insert(fixedZeroFractionDigits->type(), fixedZeroFractionDigits); + facets.insert(integerPattern->type(), integerPattern); + } + + { + XsdFacet::Hash &facets = hash[BuiltinTypes::xsNonPositiveInteger]; + facets.insert(fixedCollapseWhiteSpace->type(), fixedCollapseWhiteSpace); + facets.insert(fixedZeroFractionDigits->type(), fixedZeroFractionDigits); + facets.insert(integerPattern->type(), integerPattern); + + const XsdFacet::Ptr maxInclusive(new XsdFacet()); + maxInclusive->setType(XsdFacet::MaximumInclusive); + maxInclusive->setValue(DerivedString::fromLexical(m_namePool, QString::fromLatin1("0"))); + facets.insert(maxInclusive->type(), maxInclusive); + } + + { + XsdFacet::Hash &facets = hash[BuiltinTypes::xsNegativeInteger]; + facets.insert(fixedCollapseWhiteSpace->type(), fixedCollapseWhiteSpace); + facets.insert(fixedZeroFractionDigits->type(), fixedZeroFractionDigits); + facets.insert(integerPattern->type(), integerPattern); + + const XsdFacet::Ptr maxInclusive(new XsdFacet()); + maxInclusive->setType(XsdFacet::MaximumInclusive); + maxInclusive->setValue(DerivedString::fromLexical(m_namePool, QString::fromLatin1("-1"))); + facets.insert(maxInclusive->type(), maxInclusive); + } + + { + XsdFacet::Hash &facets = hash[BuiltinTypes::xsLong]; + facets.insert(fixedCollapseWhiteSpace->type(), fixedCollapseWhiteSpace); + facets.insert(fixedZeroFractionDigits->type(), fixedZeroFractionDigits); + facets.insert(integerPattern->type(), integerPattern); + + const XsdFacet::Ptr maxInclusive(new XsdFacet()); + maxInclusive->setType(XsdFacet::MaximumInclusive); + maxInclusive->setValue(DerivedString::fromLexical(m_namePool, QString::fromLatin1("9223372036854775807"))); + facets.insert(maxInclusive->type(), maxInclusive); + + const XsdFacet::Ptr minInclusive(new XsdFacet()); + minInclusive->setType(XsdFacet::MinimumInclusive); + minInclusive->setValue(DerivedString::fromLexical(m_namePool, QString::fromLatin1("-9223372036854775808"))); + facets.insert(minInclusive->type(), minInclusive); + } + + { + XsdFacet::Hash &facets = hash[BuiltinTypes::xsInt]; + facets.insert(fixedCollapseWhiteSpace->type(), fixedCollapseWhiteSpace); + facets.insert(fixedZeroFractionDigits->type(), fixedZeroFractionDigits); + facets.insert(integerPattern->type(), integerPattern); + + const XsdFacet::Ptr maxInclusive(new XsdFacet()); + maxInclusive->setType(XsdFacet::MaximumInclusive); + maxInclusive->setValue(DerivedString::fromLexical(m_namePool, QString::fromLatin1("2147483647"))); + facets.insert(maxInclusive->type(), maxInclusive); + + const XsdFacet::Ptr minInclusive(new XsdFacet()); + minInclusive->setType(XsdFacet::MinimumInclusive); + minInclusive->setValue(DerivedString::fromLexical(m_namePool, QString::fromLatin1("-2147483648"))); + facets.insert(minInclusive->type(), minInclusive); + } + + { + XsdFacet::Hash &facets = hash[BuiltinTypes::xsShort]; + facets.insert(fixedCollapseWhiteSpace->type(), fixedCollapseWhiteSpace); + facets.insert(fixedZeroFractionDigits->type(), fixedZeroFractionDigits); + facets.insert(integerPattern->type(), integerPattern); + + const XsdFacet::Ptr maxInclusive(new XsdFacet()); + maxInclusive->setType(XsdFacet::MaximumInclusive); + maxInclusive->setValue(DerivedString::fromLexical(m_namePool, QString::fromLatin1("32767"))); + facets.insert(maxInclusive->type(), maxInclusive); + + const XsdFacet::Ptr minInclusive(new XsdFacet()); + minInclusive->setType(XsdFacet::MinimumInclusive); + minInclusive->setValue(DerivedString::fromLexical(m_namePool, QString::fromLatin1("-32768"))); + facets.insert(minInclusive->type(), minInclusive); + } + + { + XsdFacet::Hash &facets = hash[BuiltinTypes::xsByte]; + facets.insert(fixedCollapseWhiteSpace->type(), fixedCollapseWhiteSpace); + facets.insert(fixedZeroFractionDigits->type(), fixedZeroFractionDigits); + facets.insert(integerPattern->type(), integerPattern); + + const XsdFacet::Ptr maxInclusive(new XsdFacet()); + maxInclusive->setType(XsdFacet::MaximumInclusive); + maxInclusive->setValue(DerivedString::fromLexical(m_namePool, QString::fromLatin1("127"))); + facets.insert(maxInclusive->type(), maxInclusive); + + const XsdFacet::Ptr minInclusive(new XsdFacet()); + minInclusive->setType(XsdFacet::MinimumInclusive); + minInclusive->setValue(DerivedString::fromLexical(m_namePool, QString::fromLatin1("-128"))); + facets.insert(minInclusive->type(), minInclusive); + } + + const XsdFacet::Ptr unsignedMinInclusive(new XsdFacet()); + unsignedMinInclusive->setType(XsdFacet::MinimumInclusive); + unsignedMinInclusive->setValue(DerivedString::fromLexical(m_namePool, QString::fromLatin1("0"))); + + { + XsdFacet::Hash &facets = hash[BuiltinTypes::xsNonNegativeInteger]; + facets.insert(fixedCollapseWhiteSpace->type(), fixedCollapseWhiteSpace); + facets.insert(fixedZeroFractionDigits->type(), fixedZeroFractionDigits); + facets.insert(integerPattern->type(), integerPattern); + facets.insert(unsignedMinInclusive->type(), unsignedMinInclusive); + } + + { + XsdFacet::Hash &facets = hash[BuiltinTypes::xsUnsignedLong]; + facets.insert(fixedCollapseWhiteSpace->type(), fixedCollapseWhiteSpace); + facets.insert(fixedZeroFractionDigits->type(), fixedZeroFractionDigits); + facets.insert(integerPattern->type(), integerPattern); + facets.insert(unsignedMinInclusive->type(), unsignedMinInclusive); + + const XsdFacet::Ptr maxInclusive(new XsdFacet()); + maxInclusive->setType(XsdFacet::MaximumInclusive); + maxInclusive->setValue(DerivedString::fromLexical(m_namePool, QString::fromLatin1("18446744073709551615"))); + facets.insert(maxInclusive->type(), maxInclusive); + } + + { + XsdFacet::Hash &facets = hash[BuiltinTypes::xsUnsignedInt]; + facets.insert(fixedCollapseWhiteSpace->type(), fixedCollapseWhiteSpace); + facets.insert(fixedZeroFractionDigits->type(), fixedZeroFractionDigits); + facets.insert(integerPattern->type(), integerPattern); + facets.insert(unsignedMinInclusive->type(), unsignedMinInclusive); + + const XsdFacet::Ptr maxInclusive(new XsdFacet()); + maxInclusive->setType(XsdFacet::MaximumInclusive); + maxInclusive->setValue(DerivedString::fromLexical(m_namePool, QString::fromLatin1("4294967295"))); + facets.insert(maxInclusive->type(), maxInclusive); + } + + { + XsdFacet::Hash &facets = hash[BuiltinTypes::xsUnsignedShort]; + facets.insert(fixedCollapseWhiteSpace->type(), fixedCollapseWhiteSpace); + facets.insert(fixedZeroFractionDigits->type(), fixedZeroFractionDigits); + facets.insert(integerPattern->type(), integerPattern); + facets.insert(unsignedMinInclusive->type(), unsignedMinInclusive); + + const XsdFacet::Ptr maxInclusive(new XsdFacet()); + maxInclusive->setType(XsdFacet::MaximumInclusive); + maxInclusive->setValue(DerivedString::fromLexical(m_namePool, QString::fromLatin1("65535"))); + facets.insert(maxInclusive->type(), maxInclusive); + } + + { + XsdFacet::Hash &facets = hash[BuiltinTypes::xsUnsignedByte]; + facets.insert(fixedCollapseWhiteSpace->type(), fixedCollapseWhiteSpace); + facets.insert(fixedZeroFractionDigits->type(), fixedZeroFractionDigits); + facets.insert(integerPattern->type(), integerPattern); + facets.insert(unsignedMinInclusive->type(), unsignedMinInclusive); + + const XsdFacet::Ptr maxInclusive(new XsdFacet()); + maxInclusive->setType(XsdFacet::MaximumInclusive); + maxInclusive->setValue(DerivedString::fromLexical(m_namePool, QString::fromLatin1("255"))); + facets.insert(maxInclusive->type(), maxInclusive); + } + + { + XsdFacet::Hash &facets = hash[BuiltinTypes::xsPositiveInteger]; + facets.insert(fixedCollapseWhiteSpace->type(), fixedCollapseWhiteSpace); + facets.insert(fixedZeroFractionDigits->type(), fixedZeroFractionDigits); + + const XsdFacet::Ptr minInclusive(new XsdFacet()); + minInclusive->setType(XsdFacet::MinimumInclusive); + minInclusive->setValue(DerivedString::fromLexical(m_namePool, QString::fromLatin1("1"))); + facets.insert(minInclusive->type(), minInclusive); + } + + { + XsdFacet::Hash &facets = hash[BuiltinTypes::xsYearMonthDuration]; + facets.insert(fixedCollapseWhiteSpace->type(), fixedCollapseWhiteSpace); + + const XsdFacet::Ptr pattern(new XsdFacet()); + pattern->setType(XsdFacet::Pattern); + pattern->setMultiValue(AtomicValue::List() << DerivedString::fromLexical(m_namePool, QString::fromLatin1("[^DT]*"))); + facets.insert(pattern->type(), pattern); + } + + { + XsdFacet::Hash &facets = hash[BuiltinTypes::xsDayTimeDuration]; + facets.insert(fixedCollapseWhiteSpace->type(), fixedCollapseWhiteSpace); + + const XsdFacet::Ptr pattern(new XsdFacet()); + pattern->setType(XsdFacet::Pattern); + pattern->setMultiValue(AtomicValue::List() << DerivedString::fromLexical(m_namePool, QString::fromLatin1("[^YM]*(T.*)?"))); + facets.insert(pattern->type(), pattern); + } + + return hash; +} + +QT_END_NAMESPACE diff --git a/src/xmlpatterns/schema/qxsdschemacontext_p.h b/src/xmlpatterns/schema/qxsdschemacontext_p.h new file mode 100644 index 0000000..cf52028 --- /dev/null +++ b/src/xmlpatterns/schema/qxsdschemacontext_p.h @@ -0,0 +1,157 @@ +/**************************************************************************** +** +** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the $MODULE$ of the Qt Toolkit. +** +** $TROLLTECH_DUAL_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_XsdSchemaContext_H +#define Patternist_XsdSchemaContext_H + +#include "qnamedschemacomponent_p.h" +#include "qreportcontext_p.h" +#include "qschematypefactory_p.h" +#include "qxsdschematoken_p.h" +#include "qxsdschema_p.h" +#include "qxsdschemachecker_p.h" +#include "qxsdschemaresolver_p.h" + +#include +#include +#include + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +namespace QPatternist +{ + /** + * @short A context for schema parsing and validation. + * + * This class provides the infrastructure for error reporting and + * network access. Additionally it stores objects that are used by + * both, the parser and the validator. + * + * @ingroup Patternist_schema + * @author Tobias Koenig + */ + class XsdSchemaContext : public ReportContext + { + public: + /** + * A smart pointer wrapping XsdSchemaContext instances. + */ + typedef QExplicitlySharedDataPointer Ptr; + + /** + * Creates a new schema context object. + * + * @param namePool The name pool all names belong to. + */ + XsdSchemaContext(const NamePool::Ptr &namePool); + + /** + * Returns the name pool of the schema context. + */ + virtual NamePool::Ptr namePool() const; + + /** + * Sets the base URI for the main schema. + * + * The main schema is the one that includes resp. imports + * all the other schema files. + */ + virtual void setBaseURI(const QUrl &uri); + + /** + * Returns the base URI of the main schema. + */ + virtual QUrl baseURI() const; + + /** + * Sets the network access manager that should be used + * to access referenced schema definitions. + */ + void setNetworkAccessManager(QNetworkAccessManager *accessManager); + + /** + * Returns the network access manager that is used to + * access referenced schema definitions. + */ + virtual QNetworkAccessManager* networkAccessManager() const; + + /** + * Sets the message @p handler used by the context for error reporting. + */ + void setMessageHandler(QAbstractMessageHandler *handler); + + /** + * Returns the message handler used by the context for + * error reporting. + */ + virtual QAbstractMessageHandler* messageHandler() const; + + /** + * Always returns an empty source location. + */ + virtual QSourceLocation locationFor(const SourceLocationReflection *const reflection) const; + + /** + * Sets the uri @p resolver that is used for resolving URIs in the + * schema parser. + */ + void setUriResolver(QAbstractUriResolver *resolver); + + /** + * Returns the uri resolver that is used for resolving URIs in the + * schema parser. + */ + virtual const QAbstractUriResolver* uriResolver() const; + + /** + * Returns the list of facets for the given simple @p type. + */ + XsdFacet::Hash facetsForType(const AnySimpleType::Ptr &type) const; + + /** + * Returns a schema type factory that contains some predefined schema types. + */ + SchemaTypeFactory::Ptr schemaTypeFactory() const; + + /** + * The following variables should not be accessed directly. + */ + mutable SchemaTypeFactory::Ptr m_schemaTypeFactory; + mutable QHash m_builtinTypesFacetList; + + private: + QHash setupBuiltinTypesFacetList() const; + + NamePool::Ptr m_namePool; + QNetworkAccessManager* m_networkAccessManager; + QUrl m_baseURI; + QAbstractUriResolver* m_uriResolver; + QAbstractMessageHandler* m_messageHandler; + }; +} + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif diff --git a/src/xmlpatterns/schema/qxsdschemadebugger.cpp b/src/xmlpatterns/schema/qxsdschemadebugger.cpp new file mode 100644 index 0000000..850192c --- /dev/null +++ b/src/xmlpatterns/schema/qxsdschemadebugger.cpp @@ -0,0 +1,196 @@ +/**************************************************************************** +** +** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the $MODULE$ of the Qt Toolkit. +** +** $TROLLTECH_DUAL_LICENSE$ +** +****************************************************************************/ + +#include "qxsdschemadebugger_p.h" + +QT_BEGIN_NAMESPACE + +using namespace QPatternist; + +XsdSchemaDebugger::XsdSchemaDebugger(const NamePool::Ptr &namePool) + : m_namePool(namePool) +{ +} + +void XsdSchemaDebugger::dumpParticle(const XsdParticle::Ptr &particle, int level) +{ + QString prefix; prefix.fill(QLatin1Char(' '), level); + + qDebug("%s min=%s max=%s", qPrintable(prefix), qPrintable(QString::number(particle->minimumOccurs())), + qPrintable(particle->maximumOccursUnbounded() ? QLatin1String("unbounded") : QString::number(particle->maximumOccurs()))); + + if (particle->term()->isElement()) { + qDebug("%selement (%s)", qPrintable(prefix), qPrintable(XsdElement::Ptr(particle->term())->displayName(m_namePool))); + } else if (particle->term()->isModelGroup()) { + const XsdModelGroup::Ptr group(particle->term()); + if (group->compositor() == XsdModelGroup::SequenceCompositor) { + qDebug("%ssequence", qPrintable(prefix)); + } else if (group->compositor() == XsdModelGroup::AllCompositor) { + qDebug("%sall", qPrintable(prefix)); + } else if (group->compositor() == XsdModelGroup::ChoiceCompositor) { + qDebug("%schoice", qPrintable(prefix)); + } + + for (int i = 0; i < group->particles().count(); ++i) + dumpParticle(group->particles().at(i), level + 5); + } else if (particle->term()->isWildcard()) { + XsdWildcard::Ptr wildcard(particle->term()); + qDebug("%swildcard (process=%d)", qPrintable(prefix), wildcard->processContents()); + } +} + +void XsdSchemaDebugger::dumpInheritance(const SchemaType::Ptr &type, int level) +{ + QString prefix; prefix.fill(QLatin1Char(' '), level); + qDebug("%s-->%s", qPrintable(prefix), qPrintable(type->displayName(m_namePool))); + if (type->wxsSuperType()) + dumpInheritance(type->wxsSuperType(), ++level); +} + +void XsdSchemaDebugger::dumpWildcard(const XsdWildcard::Ptr &wildcard) +{ + QVector varietyNames; + varietyNames.append(QLatin1String("Any")); + varietyNames.append(QLatin1String("Enumeration")); + varietyNames.append(QLatin1String("Not")); + + QVector processContentsNames; + processContentsNames.append(QLatin1String("Strict")); + processContentsNames.append(QLatin1String("Lax")); + processContentsNames.append(QLatin1String("Skip")); + + qDebug(" processContents: %s", qPrintable(processContentsNames.at((int)wildcard->processContents()))); + const XsdWildcard::NamespaceConstraint::Ptr constraint = wildcard->namespaceConstraint(); + qDebug(" variety: %s", qPrintable(varietyNames.at((int)constraint->variety()))); + if (constraint->variety() != XsdWildcard::NamespaceConstraint::Any) + qDebug() << " namespaces:" << constraint->namespaces(); +} + +void XsdSchemaDebugger::dumpType(const SchemaType::Ptr &type) +{ + if (type->isComplexType()) { + const XsdComplexType::Ptr complexType(type); + qDebug("\n+++ Complex Type +++"); + qDebug("Name: %s (abstract: %s)", qPrintable(complexType->displayName(m_namePool)), complexType->isAbstract() ? "yes" : "no"); + if (complexType->wxsSuperType()) + qDebug(" base type: %s", qPrintable(complexType->wxsSuperType()->displayName(m_namePool))); + else + qDebug(" base type: (none)"); + if (complexType->contentType()->variety() == XsdComplexType::ContentType::Empty) + qDebug(" content type: empty"); + if (complexType->contentType()->variety() == XsdComplexType::ContentType::Simple) + qDebug(" content type: simple"); + if (complexType->contentType()->variety() == XsdComplexType::ContentType::ElementOnly) + qDebug(" content type: element-only"); + if (complexType->contentType()->variety() == XsdComplexType::ContentType::Mixed) + qDebug(" content type: mixed"); + if (complexType->contentType()->variety() == XsdComplexType::ContentType::Simple) { + if (complexType->contentType()->simpleType()) + qDebug(" simple type: %s", qPrintable(complexType->contentType()->simpleType()->displayName(m_namePool))); + else + qDebug(" simple type: (none)"); + } + + const XsdAttributeUse::List uses = complexType->attributeUses(); + qDebug(" %d attributes", uses.count()); + for (int i = 0; i < uses.count(); ++i) { + qDebug(" attr: %s", qPrintable(uses.at(i)->attribute()->displayName(m_namePool))); + } + qDebug(" has attribute wildcard: %s", complexType->attributeWildcard() ? "yes" : "no"); + if (complexType->attributeWildcard()) { + dumpWildcard(complexType->attributeWildcard()); + } + + if (complexType->contentType()->particle()) { + dumpParticle(complexType->contentType()->particle(), 5); + } + } else { + qDebug("\n+++ Simple Type +++"); + qDebug("Name: %s", qPrintable(type->displayName(m_namePool))); + if (type->isDefinedBySchema()) { + const XsdSimpleType::Ptr simpleType(type); + if (simpleType->primitiveType()) + qDebug(" primitive type: %s", qPrintable(simpleType->primitiveType()->displayName(m_namePool))); + else + qDebug(" primitive type: (none)"); + } + dumpInheritance(type, 0); + } +} + + +void XsdSchemaDebugger::dumpElement(const XsdElement::Ptr &element) +{ + QStringList disallowedSubstGroup; + if (element->disallowedSubstitutions() & XsdElement::RestrictionConstraint) + disallowedSubstGroup << QLatin1String("restriction"); + if (element->disallowedSubstitutions() & XsdElement::ExtensionConstraint) + disallowedSubstGroup << QLatin1String("extension"); + if (element->disallowedSubstitutions() & XsdElement::SubstitutionConstraint) + disallowedSubstGroup << QLatin1String("substitution"); + + + qDebug() << "Name:" << element->displayName(m_namePool); + qDebug() << "IsAbstract:" << (element->isAbstract() ? "yes" : "no"); + qDebug() << "Type:" << element->type()->displayName(m_namePool); + qDebug() << "DisallowedSubstitutionGroups:" << disallowedSubstGroup.join(QLatin1String("' ")); +} + +void XsdSchemaDebugger::dumpAttribute(const XsdAttribute::Ptr &attribute) +{ + qDebug() << "Name:" << attribute->displayName(m_namePool); + qDebug() << "Type:" << attribute->type()->displayName(m_namePool); +} + +void XsdSchemaDebugger::dumpSchema(const XsdSchema::Ptr &schema) +{ + qDebug() << "------------------------------ Schema -------------------------------"; + + // elements + { + qDebug() << "Global Elements:"; + const XsdElement::List elements = schema->elements(); + for (int i = 0; i < elements.count(); ++i) { + dumpElement(elements.at(i)); + } + } + + // attributes + { + qDebug() << "Global Attributes:"; + const XsdAttribute::List attributes = schema->attributes(); + for (int i = 0; i < attributes.count(); ++i) { + dumpAttribute(attributes.at(i)); + } + } + + // types + { + qDebug() << "Global Types:"; + const SchemaType::List types = schema->types(); + for (int i = 0; i < types.count(); ++i) { + dumpType(types.at(i)); + } + } + + // anonymous types + { + qDebug() << "Anonymous Types:"; + const SchemaType::List types = schema->anonymousTypes(); + for (int i = 0; i < types.count(); ++i) { + dumpType(types.at(i)); + } + } + + qDebug() << "+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++"; +} + +QT_END_NAMESPACE diff --git a/src/xmlpatterns/schema/qxsdschemadebugger_p.h b/src/xmlpatterns/schema/qxsdschemadebugger_p.h new file mode 100644 index 0000000..8c12f0f --- /dev/null +++ b/src/xmlpatterns/schema/qxsdschemadebugger_p.h @@ -0,0 +1,97 @@ +/**************************************************************************** +** +** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the $MODULE$ of the Qt Toolkit. +** +** $TROLLTECH_DUAL_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_XsdSchemaDebugger_H +#define Patternist_XsdSchemaDebugger_H + +#include "qxsdschema_p.h" + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +namespace QPatternist +{ + /** + * A helper class to print out the structure of a compiled schema. + */ + class XsdSchemaDebugger + { + public: + /** + * Creates a new schema debugger. + * + * @param namePool The name pool that the schema uses. + */ + XsdSchemaDebugger(const NamePool::Ptr &namePool); + + /** + * Dumps the structure of the given @p particle. + * + * @param particle The particle to dump. + * @param level The level of indention. + */ + void dumpParticle(const XsdParticle::Ptr &particle, int level = 0); + + /** + * Dumps the inheritance path of the given @p type. + * + * @param type The type to dump. + * @param level The level of indention. + */ + void dumpInheritance(const SchemaType::Ptr &type, int level = 0); + + /** + * Dumps the structure of the given @p wildcard. + */ + void dumpWildcard(const XsdWildcard::Ptr &wildcard); + + /** + * Dumps the structure of the given @p type. + */ + void dumpType(const SchemaType::Ptr &type); + + /** + * Dumps the structure of the given @p element. + */ + void dumpElement(const XsdElement::Ptr &element); + + /** + * Dumps the structure of the given @p attribute. + */ + void dumpAttribute(const XsdAttribute::Ptr &attribute); + + /** + * Dumps the structure of the complete @p schema. + */ + void dumpSchema(const XsdSchema::Ptr &schema); + + private: + NamePool::Ptr m_namePool; + }; + +} + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif diff --git a/src/xmlpatterns/schema/qxsdschemahelper.cpp b/src/xmlpatterns/schema/qxsdschemahelper.cpp new file mode 100644 index 0000000..752af89 --- /dev/null +++ b/src/xmlpatterns/schema/qxsdschemahelper.cpp @@ -0,0 +1,791 @@ +/**************************************************************************** +** +** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the $MODULE$ of the Qt Toolkit. +** +** $TROLLTECH_DUAL_LICENSE$ +** +****************************************************************************/ + +#include "qxsdschemahelper_p.h" + +#include "qbuiltintypes_p.h" +#include "qvaluefactory_p.h" +#include "qxsdcomplextype_p.h" +#include "qxsdmodelgroup_p.h" +#include "qxsdsimpletype_p.h" +#include "qxsdtypechecker_p.h" + +QT_BEGIN_NAMESPACE + +using namespace QPatternist; + +/* + * Calculates the effective total range minimum of the given @p particle as + * described by the algorithm in the schema spec. + */ +static inline unsigned int effectiveTotalRangeMinimum(const XsdParticle::Ptr &particle) +{ + const XsdModelGroup::Ptr group = particle->term(); + + if (group->compositor() == XsdModelGroup::ChoiceCompositor) { + // @see http://www.w3.org/TR/xmlschema11-1/# cos-choice-range + + int minValue = -1; + + const XsdParticle::List particles = group->particles(); + if (particles.isEmpty()) + minValue = 0; + + for (int i = 0; i < particles.count(); ++i) { + const XsdParticle::Ptr particle = particles.at(i); + + if (particle->term()->isElement() || particle->term()->isWildcard()) { + if (minValue == -1) { + minValue = particle->minimumOccurs(); + } else { + minValue = qMin((unsigned int)minValue, particle->minimumOccurs()); + } + } else if (particle->term()->isModelGroup()) { + if (minValue == -1) { + minValue = effectiveTotalRangeMinimum(particle); + } else { + minValue = qMin((unsigned int)minValue, effectiveTotalRangeMinimum(particle)); + } + } + } + + return (particle->minimumOccurs() * minValue); + + } else { + // @see http://www.w3.org/TR/xmlschema11-1/# cos-seq-range + + unsigned int sum = 0; + const XsdParticle::List particles = group->particles(); + for (int i = 0; i < particles.count(); ++i) { + const XsdParticle::Ptr particle = particles.at(i); + + if (particle->term()->isElement() || particle->term()->isWildcard()) + sum += particle->minimumOccurs(); + else if (particle->term()->isModelGroup()) + sum += effectiveTotalRangeMinimum(particle); + } + + return (particle->minimumOccurs() * sum); + } +} + +bool XsdSchemaHelper::isParticleEmptiable(const XsdParticle::Ptr &particle) +{ + // @see http://www.w3.org/TR/xmlschema11-1/#cos-group-emptiable + + if (particle->minimumOccurs() == 0) + return true; + + if (!(particle->term()->isModelGroup())) + return false; + + return (effectiveTotalRangeMinimum(particle) == 0); +} + +bool XsdSchemaHelper::wildcardAllowsNamespaceName(const QString &nameSpace, const XsdWildcard::NamespaceConstraint::Ptr &constraint) +{ + // @see http://www.w3.org/TR/xmlschema11-1/#cvc-wildcard-namespace + + // 1 + if (constraint->variety() == XsdWildcard::NamespaceConstraint::Any) + return true; + + // 2 + if (constraint->variety() == XsdWildcard::NamespaceConstraint::Not) { // 2.1 + if (!constraint->namespaces().contains(nameSpace)) // 2.2 + if (nameSpace != XsdWildcard::absentNamespace()) // 2.3 + return true; + } + + // 3 + if (constraint->variety() == XsdWildcard::NamespaceConstraint::Enumeration) { + if (constraint->namespaces().contains(nameSpace)) + return true; + } + + return false; +} + +bool XsdSchemaHelper::wildcardAllowsExpandedName(const QXmlName &name, const XsdWildcard::Ptr &wildcard, const NamePool::Ptr &namePool) +{ + // @see http://www.w3.org/TR/xmlschema11-1/#cvc-wildcard-name + + // 1 + if (!wildcardAllowsNamespaceName(namePool->stringForNamespace(name.namespaceURI()), wildcard->namespaceConstraint())) + return false; + + // 2, 3, 4 + //TODO: we have no disallowed namespace yet + + return true; +} + +// small helper function that should be available in Qt 4.6 +template +static inline bool containsSet(const QSet &super, const QSet &sub) +{ + QSetIterator it(sub); + while (it.hasNext()) { + if (!super.contains(it.next())) + return false; + } + + return true; +} + +bool XsdSchemaHelper::isWildcardSubset(const XsdWildcard::Ptr &wildcard, const XsdWildcard::Ptr &otherWildcard) +{ + // @see http://www.w3.org/TR/xmlschema11-1/#cos-ns-subset + // wildcard =^ sub + // otherWildcard =^ super + + const XsdWildcard::NamespaceConstraint::Ptr constraint(wildcard->namespaceConstraint()); + const XsdWildcard::NamespaceConstraint::Ptr otherConstraint(otherWildcard->namespaceConstraint()); + + // 1 + if (otherConstraint->variety() == XsdWildcard::NamespaceConstraint::Any) + return true; + + // 2 + if ((constraint->variety() == XsdWildcard::NamespaceConstraint::Enumeration) && (otherConstraint->variety() == XsdWildcard::NamespaceConstraint::Enumeration)) { + if (containsSet(otherConstraint->namespaces(), constraint->namespaces())) + return true; + } + + // 3 + if ((constraint->variety() == XsdWildcard::NamespaceConstraint::Enumeration) && (otherConstraint->variety() == XsdWildcard::NamespaceConstraint::Not)) { + if (constraint->namespaces().intersect(otherConstraint->namespaces()).isEmpty()) + return true; + } + + // 4 + if ((constraint->variety() == XsdWildcard::NamespaceConstraint::Not) && (otherConstraint->variety() == XsdWildcard::NamespaceConstraint::Not)) { + if (containsSet(constraint->namespaces(), otherConstraint->namespaces())) + return true; + } + + return false; +} + +XsdWildcard::Ptr XsdSchemaHelper::wildcardUnion(const XsdWildcard::Ptr &wildcard, const XsdWildcard::Ptr &otherWildcard) +{ + // @see http://www.w3.org/TR/xmlschema11-1/#cos-aw-union + + XsdWildcard::Ptr unionWildcard(new XsdWildcard()); + + const XsdWildcard::NamespaceConstraint::Ptr constraint(wildcard->namespaceConstraint()); + const XsdWildcard::NamespaceConstraint::Ptr otherConstraint(otherWildcard->namespaceConstraint()); + + // 1 + if ((constraint->variety() == otherConstraint->variety()) && + (constraint->namespaces() == otherConstraint->namespaces())) { + unionWildcard->namespaceConstraint()->setVariety(constraint->variety()); + unionWildcard->namespaceConstraint()->setNamespaces(constraint->namespaces()); + return unionWildcard; + } + + // 2 + if ((constraint->variety() == XsdWildcard::NamespaceConstraint::Any) || (otherConstraint->variety() == XsdWildcard::NamespaceConstraint::Any)) { + unionWildcard->namespaceConstraint()->setVariety(XsdWildcard::NamespaceConstraint::Any); + return unionWildcard; + } + + // 3 + if ((constraint->variety() == XsdWildcard::NamespaceConstraint::Enumeration) && (otherConstraint->variety() == XsdWildcard::NamespaceConstraint::Enumeration)) { + unionWildcard->namespaceConstraint()->setVariety(XsdWildcard::NamespaceConstraint::Enumeration); + unionWildcard->namespaceConstraint()->setNamespaces(constraint->namespaces() + otherConstraint->namespaces()); + return unionWildcard; + } + + // 4 + if ((constraint->variety() == XsdWildcard::NamespaceConstraint::Not) && (otherConstraint->variety() == XsdWildcard::NamespaceConstraint::Not)) { + if (constraint->namespaces() != otherConstraint->namespaces()) { + unionWildcard->namespaceConstraint()->setVariety(XsdWildcard::NamespaceConstraint::Not); + unionWildcard->namespaceConstraint()->setNamespaces(QSet() << XsdWildcard::absentNamespace()); + return unionWildcard; + } + } + + // 5 + QSet sSet, negatedSet; + bool matches5 = false; + if (((constraint->variety() == XsdWildcard::NamespaceConstraint::Not) && !constraint->namespaces().contains(XsdWildcard::absentNamespace())) + && (otherConstraint->variety() == XsdWildcard::NamespaceConstraint::Enumeration)) { + + negatedSet = constraint->namespaces(); + sSet = otherConstraint->namespaces(); + matches5 = true; + } else if (((otherConstraint->variety() == XsdWildcard::NamespaceConstraint::Not) && !otherConstraint->namespaces().contains(XsdWildcard::absentNamespace())) + && (constraint->variety() == XsdWildcard::NamespaceConstraint::Enumeration)) { + + negatedSet = otherConstraint->namespaces(); + sSet = constraint->namespaces(); + matches5 = true; + } + + if (matches5) { + if (sSet.contains(negatedSet.values().first()) && sSet.contains(XsdWildcard::absentNamespace())) { // 5.1 + unionWildcard->namespaceConstraint()->setVariety(XsdWildcard::NamespaceConstraint::Any); + return unionWildcard; + } + if (sSet.contains(negatedSet.values().first()) && !sSet.contains(XsdWildcard::absentNamespace())) { // 5.2 + unionWildcard->namespaceConstraint()->setVariety(XsdWildcard::NamespaceConstraint::Not); + unionWildcard->namespaceConstraint()->setNamespaces(QSet() << XsdWildcard::absentNamespace()); + return unionWildcard; + } + if (!sSet.contains(negatedSet.values().first()) && sSet.contains(XsdWildcard::absentNamespace())) { // 5.3 + return XsdWildcard::Ptr(); // not expressible + } + if (!sSet.contains(negatedSet.values().first()) && !sSet.contains(XsdWildcard::absentNamespace())) { // 5.4 + unionWildcard->namespaceConstraint()->setVariety(XsdWildcard::NamespaceConstraint::Not); + unionWildcard->namespaceConstraint()->setNamespaces(negatedSet); + return unionWildcard; + } + } + + // 6 + bool matches6 = false; + if (((constraint->variety() == XsdWildcard::NamespaceConstraint::Not) && constraint->namespaces().contains(XsdWildcard::absentNamespace())) + && (otherConstraint->variety() == XsdWildcard::NamespaceConstraint::Enumeration)) { + + negatedSet = constraint->namespaces(); + sSet = otherConstraint->namespaces(); + matches6 = true; + } else if (((otherConstraint->variety() == XsdWildcard::NamespaceConstraint::Not) && otherConstraint->namespaces().contains(XsdWildcard::absentNamespace())) + && (constraint->variety() == XsdWildcard::NamespaceConstraint::Enumeration)) { + + negatedSet = otherConstraint->namespaces(); + sSet = constraint->namespaces(); + matches6 = true; + } + + if (matches6) { + if (sSet.contains(XsdWildcard::absentNamespace())) { // 6.1 + unionWildcard->namespaceConstraint()->setVariety(XsdWildcard::NamespaceConstraint::Any); + return unionWildcard; + } + if (!sSet.contains(XsdWildcard::absentNamespace())) { // 6.2 + unionWildcard->namespaceConstraint()->setVariety(XsdWildcard::NamespaceConstraint::Not); + unionWildcard->namespaceConstraint()->setNamespaces(QSet() += XsdWildcard::absentNamespace()); + return unionWildcard; + } + } + + return XsdWildcard::Ptr(); +} + +XsdWildcard::Ptr XsdSchemaHelper::wildcardIntersection(const XsdWildcard::Ptr &wildcard, const XsdWildcard::Ptr &otherWildcard) +{ + // @see http://www.w3.org/TR/xmlschema11-1/#cos-aw-intersect + + const XsdWildcard::NamespaceConstraint::Ptr constraint(wildcard->namespaceConstraint()); + const XsdWildcard::NamespaceConstraint::Ptr otherConstraint(otherWildcard->namespaceConstraint()); + + const XsdWildcard::Ptr intersectionWildcard(new XsdWildcard()); + + // 1 + if ((constraint->variety() == otherConstraint->variety()) && + (constraint->namespaces() == otherConstraint->namespaces())) { + intersectionWildcard->namespaceConstraint()->setVariety(constraint->variety()); + intersectionWildcard->namespaceConstraint()->setNamespaces(constraint->namespaces()); + return intersectionWildcard; + } + + // 2 + if ((constraint->variety() == XsdWildcard::NamespaceConstraint::Any) && + (otherConstraint->variety() != XsdWildcard::NamespaceConstraint::Any)) { + intersectionWildcard->namespaceConstraint()->setVariety(otherConstraint->variety()); + intersectionWildcard->namespaceConstraint()->setNamespaces(otherConstraint->namespaces()); + return intersectionWildcard; + } + + // 2 + if ((constraint->variety() != XsdWildcard::NamespaceConstraint::Any) && + (otherConstraint->variety() == XsdWildcard::NamespaceConstraint::Any)) { + intersectionWildcard->namespaceConstraint()->setVariety(constraint->variety()); + intersectionWildcard->namespaceConstraint()->setNamespaces(constraint->namespaces()); + return intersectionWildcard; + } + + // 3 + if ((constraint->variety() == XsdWildcard::NamespaceConstraint::Not) && + (otherConstraint->variety() == XsdWildcard::NamespaceConstraint::Enumeration)) { + + QSet set = otherConstraint->namespaces(); + set.subtract(constraint->namespaces()); + set.remove(XsdWildcard::absentNamespace()); + + intersectionWildcard->namespaceConstraint()->setVariety(XsdWildcard::NamespaceConstraint::Enumeration); + intersectionWildcard->namespaceConstraint()->setNamespaces(set); + + return intersectionWildcard; + } + + // 3 + if ((otherConstraint->variety() == XsdWildcard::NamespaceConstraint::Not) && + (constraint->variety() == XsdWildcard::NamespaceConstraint::Enumeration)) { + + QSet set = constraint->namespaces(); + set.subtract(otherConstraint->namespaces()); + set.remove(XsdWildcard::absentNamespace()); + + intersectionWildcard->namespaceConstraint()->setVariety(XsdWildcard::NamespaceConstraint::Enumeration); + intersectionWildcard->namespaceConstraint()->setNamespaces(set); + + return intersectionWildcard; + } + + // 4 + if ((constraint->variety() == XsdWildcard::NamespaceConstraint::Enumeration) && + (otherConstraint->variety() == XsdWildcard::NamespaceConstraint::Enumeration)) { + + QSet set = constraint->namespaces(); + set.intersect(otherConstraint->namespaces()); + + intersectionWildcard->namespaceConstraint()->setVariety(XsdWildcard::NamespaceConstraint::Enumeration); + intersectionWildcard->namespaceConstraint()->setNamespaces(set); + + return intersectionWildcard; + } + + // 6 + if ((constraint->variety() == XsdWildcard::NamespaceConstraint::Not) && + (otherConstraint->variety() == XsdWildcard::NamespaceConstraint::Not)) { + if (!(constraint->namespaces().contains(XsdWildcard::absentNamespace())) && otherConstraint->namespaces().contains(XsdWildcard::absentNamespace())) { + return wildcard; + } + if (constraint->namespaces().contains(XsdWildcard::absentNamespace()) && !(otherConstraint->namespaces().contains(XsdWildcard::absentNamespace()))) { + return otherWildcard; + } + } + + // 5 as not expressible return empty wildcard + return XsdWildcard::Ptr(); +} + +static SchemaType::DerivationConstraints convertBlockingConstraints(const NamedSchemaComponent::BlockingConstraints &constraints) +{ + SchemaType::DerivationConstraints result = 0; + + if (constraints & NamedSchemaComponent::RestrictionConstraint) + result |= SchemaType::RestrictionConstraint; + if (constraints & NamedSchemaComponent::ExtensionConstraint) + result |= SchemaType::ExtensionConstraint; + + return result; +} + +bool XsdSchemaHelper::isValidlySubstitutable(const SchemaType::Ptr &type, const SchemaType::Ptr &otherType, const SchemaType::DerivationConstraints &constraints) +{ + // @see http://www.w3.org/TR/xmlschema11-1/#key-val-sub-type + + // 1 + if (type->isComplexType() && otherType->isComplexType()) { + SchemaType::DerivationConstraints keywords = constraints; + if (otherType->isDefinedBySchema()) + keywords |= convertBlockingConstraints(XsdComplexType::Ptr(otherType)->prohibitedSubstitutions()); + + return isComplexDerivationOk(type, otherType, keywords); + } + + // 2 + if (type->isComplexType() && otherType->isSimpleType()) { + return isComplexDerivationOk(type, otherType, constraints); + } + + // 3 + if (type->isSimpleType() && otherType->isSimpleType()) { + return isSimpleDerivationOk(type, otherType, constraints); + } + + return false; +} + +bool XsdSchemaHelper::isSimpleDerivationOk(const SchemaType::Ptr &derivedType, const SchemaType::Ptr baseType, const SchemaType::DerivationConstraints &constraints) +{ + // @see http://www.w3.org/TR/xmlschema11-1/#cos-st-derived-ok + + // 1 + if (derivedType == baseType) + return true; + + // 2.1 + if ((constraints & SchemaType::RestrictionConstraint) || derivedType->wxsSuperType()->derivationConstraints() & SchemaType::RestrictionConstraint) { + return false; + } + + // 2.2.1 + if (derivedType->wxsSuperType() == baseType) + return true; + + // 2.2.2 + if (derivedType->wxsSuperType() != BuiltinTypes::xsAnyType) { + if (isSimpleDerivationOk(derivedType->wxsSuperType(), baseType, constraints)) + return true; + } + + // 2.2.3 + if (derivedType->category() == SchemaType::SimpleTypeList || derivedType->category() == SchemaType::SimpleTypeUnion) { + if (baseType == BuiltinTypes::xsAnySimpleType) + return true; + } + + // 2.2.4 + if (baseType->category() == SchemaType::SimpleTypeUnion && baseType->isDefinedBySchema()) { // 2.2.4.1 + const AnySimpleType::List memberTypes = XsdSimpleType::Ptr(baseType)->memberTypes(); + for (int i = 0; i < memberTypes.count(); ++i) { + if (isSimpleDerivationOk(derivedType, memberTypes.at(i), constraints)) { // 2.2.4.2 + if (XsdSimpleType::Ptr(baseType)->facets().isEmpty()) { // 2.2.4.3 + return true; + } + } + } + } + + return false; +} + +bool XsdSchemaHelper::isComplexDerivationOk(const SchemaType::Ptr &derivedType, const SchemaType::Ptr baseType, const SchemaType::DerivationConstraints &constraints) +{ + if (!derivedType) + return false; + + // @see http://www.w3.org/TR/xmlschema11-1/#cos-ct-derived-ok + + // 1 + if (derivedType != baseType) { + if ((derivedType->derivationMethod() == SchemaType::DerivationRestriction) && (constraints & SchemaType::RestrictionConstraint)) + return false; + if ((derivedType->derivationMethod() == SchemaType::DerivationExtension) && (constraints & SchemaType::ExtensionConstraint)) + return false; + } + + // 2.1 + if (derivedType == baseType) + return true; + + // 2.2 + if (derivedType->wxsSuperType() == baseType) + return true; + + // 2.3 + bool isOk = true; + if (derivedType->wxsSuperType() == BuiltinTypes::xsAnyType) { // 2.3.1 + isOk = false; + } else { // 2.3.2 + if (!derivedType->wxsSuperType()) + return false; + + if (derivedType->wxsSuperType()->isComplexType()) { // 2.3.2.1 + isOk = isComplexDerivationOk(derivedType->wxsSuperType(), baseType, constraints); + } else { // 2.3.2.2 + isOk = isSimpleDerivationOk(derivedType->wxsSuperType(), baseType, constraints); + } + } + if (isOk) + return true; + + return false; +} + +bool XsdSchemaHelper::constructAndCompare(const DerivedString::Ptr &operand1, + const AtomicComparator::Operator op, + const DerivedString::Ptr &operand2, + const SchemaType::Ptr &type, + const ReportContext::Ptr &context, + const SourceLocationReflection *const sourceLocationReflection) +{ + Q_ASSERT_X(type->category() == SchemaType::SimpleTypeAtomic, Q_FUNC_INFO, + "We can only compare atomic values."); + + // we can not cast a xs:String to a xs:QName, so lets go the safe way + if (type->name(context->namePool()) == BuiltinTypes::xsQName->name(context->namePool())) + return false; + + const AtomicValue::Ptr value1 = ValueFactory::fromLexical(operand1->stringValue(), type, context, sourceLocationReflection); + if (value1->hasError()) + return false; + + const AtomicValue::Ptr value2 = ValueFactory::fromLexical(operand2->stringValue(), type, context, sourceLocationReflection); + if (value2->hasError()) + return false; + + return ComparisonFactory::compare(value1, op, value2, type, context, sourceLocationReflection); +} + +bool XsdSchemaHelper::checkWildcardProcessContents(const XsdWildcard::Ptr &baseWildcard, const XsdWildcard::Ptr &derivedWildcard) +{ + if (baseWildcard->processContents() == XsdWildcard::Strict) { + if (derivedWildcard->processContents() == XsdWildcard::Lax || derivedWildcard->processContents() == XsdWildcard::Skip) { + return false; + } + } else if (baseWildcard->processContents() == XsdWildcard::Lax) { + if (derivedWildcard->processContents() == XsdWildcard::Skip) + return false; + } + + return true; +} + +bool XsdSchemaHelper::foundSubstitutionGroupTransitive(const XsdElement::Ptr &head, const XsdElement::Ptr &member, QSet &visitedElements) +{ + if (visitedElements.contains(member)) + return false; + else + visitedElements.insert(member); + + if (member->substitutionGroupAffiliations().isEmpty()) + return false; + + if (member->substitutionGroupAffiliations().contains(head)) { + return true; + } else { + const XsdElement::List affiliations = member->substitutionGroupAffiliations(); + for (int i = 0; i < affiliations.count(); ++i) { + if (foundSubstitutionGroupTransitive(head, affiliations.at(i), visitedElements)) + return true; + } + + return false; + } +} + +void XsdSchemaHelper::foundSubstitutionGroupTypeInheritance(const SchemaType::Ptr &headType, const SchemaType::Ptr &memberType, + QSet &derivationSet, NamedSchemaComponent::BlockingConstraints &blockSet) +{ + if (!memberType) + return; + + if (memberType == headType) + return; + + derivationSet.insert(memberType->derivationMethod()); + + if (memberType->isComplexType()) { + const XsdComplexType::Ptr complexType(memberType); + blockSet |= complexType->prohibitedSubstitutions(); + } + + foundSubstitutionGroupTypeInheritance(headType, memberType->wxsSuperType(), derivationSet, blockSet); +} + +bool XsdSchemaHelper::substitutionGroupOkTransitive(const XsdElement::Ptr &head, const XsdElement::Ptr &member, const NamePool::Ptr &namePool) +{ + // @see http://www.w3.org/TR/xmlschema11-1/#cos-equiv-derived-ok-rec + + // 1 + if ((member->name(namePool) == head->name(namePool)) && (member->type() == head->type())) + return true; + + // 2.1 + if (head->disallowedSubstitutions() & NamedSchemaComponent::SubstitutionConstraint) + return false; + + // 2.2 + { + QSet visitedElements; + if (!foundSubstitutionGroupTransitive(head, member, visitedElements)) + return false; + } + + // 2.3 + { + QSet derivationSet; + NamedSchemaComponent::BlockingConstraints blockSet; + + foundSubstitutionGroupTypeInheritance(head->type(), member->type(), derivationSet, blockSet); + + NamedSchemaComponent::BlockingConstraints checkSet(blockSet); + checkSet |= head->disallowedSubstitutions(); + if (head->type()->isComplexType()) { + const XsdComplexType::Ptr complexType(head->type()); + checkSet |= complexType->prohibitedSubstitutions(); + } + + if ((checkSet & NamedSchemaComponent::RestrictionConstraint) && derivationSet.contains(SchemaType::DerivationRestriction)) + return false; + if ((checkSet & NamedSchemaComponent::ExtensionConstraint) && derivationSet.contains(SchemaType::DerivationExtension)) + return false; + if (checkSet & NamedSchemaComponent::SubstitutionConstraint) + return false; + } + + return true; +} + +bool XsdSchemaHelper::isValidAttributeGroupRestriction(const XsdAttributeGroup::Ptr &derivedAttributeGroup, const XsdAttributeGroup::Ptr &attributeGroup, const XsdSchemaContext::Ptr &context, QString &errorMsg) +{ + // @see http://www.w3.org/TR/xmlschema-1/#derivation-ok-restriction + + const XsdAttributeUse::List derivedAttributeUses = derivedAttributeGroup->attributeUses(); + const XsdAttributeUse::List baseAttributeUses = attributeGroup->attributeUses(); + + return isValidAttributeUsesRestriction(derivedAttributeUses, baseAttributeUses, + derivedAttributeGroup->wildcard(), attributeGroup->wildcard(), context, errorMsg); +} + +bool XsdSchemaHelper::isValidAttributeUsesRestriction(const XsdAttributeUse::List &derivedAttributeUses, const XsdAttributeUse::List &baseAttributeUses, + const XsdWildcard::Ptr &derivedWildcard, const XsdWildcard::Ptr &wildcard, const XsdSchemaContext::Ptr &context, QString &errorMsg) +{ + const NamePool::Ptr namePool(context->namePool()); + + QHash baseAttributeUsesLookup; + for (int i = 0; i < baseAttributeUses.count(); ++i) + baseAttributeUsesLookup.insert(baseAttributeUses.at(i)->attribute()->name(namePool), baseAttributeUses.at(i)); + + QHash derivedAttributeUsesLookup; + for (int i = 0; i < derivedAttributeUses.count(); ++i) + derivedAttributeUsesLookup.insert(derivedAttributeUses.at(i)->attribute()->name(namePool), derivedAttributeUses.at(i)); + + // 2 + for (int i = 0; i < derivedAttributeUses.count(); ++i) { + const XsdAttributeUse::Ptr derivedAttributeUse = derivedAttributeUses.at(i); + + // prohibited attributes are no real attributes, so skip them in that test here + if (derivedAttributeUse->useType() == XsdAttributeUse::ProhibitedUse) + continue; + + if (baseAttributeUsesLookup.contains(derivedAttributeUse->attribute()->name(namePool))) { + const XsdAttributeUse::Ptr baseAttributeUse(baseAttributeUsesLookup.value(derivedAttributeUse->attribute()->name(namePool))); + + // 2.1.1 + if (baseAttributeUse->isRequired() == true && derivedAttributeUse->isRequired() == false) { + errorMsg = QtXmlPatterns::tr("base attribute %1 is required but derived attribute is not").arg(formatAttribute(baseAttributeUse->attribute()->displayName(namePool))); + return false; + } + + // 2.1.2 + if (!isSimpleDerivationOk(derivedAttributeUse->attribute()->type(), baseAttributeUse->attribute()->type(), SchemaType::DerivationConstraints())) { + errorMsg = QtXmlPatterns::tr("type of derived attribute %1 cannot be validly derived from type of base attribute").arg(formatAttribute(derivedAttributeUse->attribute()->displayName(namePool))); + return false; + } + + // 2.1.3 + XsdAttributeUse::ValueConstraint::Ptr derivedConstraint; + if (derivedAttributeUse->valueConstraint()) + derivedConstraint = derivedAttributeUse->valueConstraint(); + else if (derivedAttributeUse->attribute()->valueConstraint()) + derivedConstraint = XsdAttributeUse::ValueConstraint::fromAttributeValueConstraint(derivedAttributeUse->attribute()->valueConstraint()); + + XsdAttributeUse::ValueConstraint::Ptr baseConstraint; + if (baseAttributeUse->valueConstraint()) + baseConstraint = baseAttributeUse->valueConstraint(); + else if (baseAttributeUse->attribute()->valueConstraint()) + baseConstraint = XsdAttributeUse::ValueConstraint::fromAttributeValueConstraint(baseAttributeUse->attribute()->valueConstraint()); + + bool ok = false; + if (!baseConstraint || baseConstraint->variety() == XsdAttributeUse::ValueConstraint::Default) + ok = true; + + if (derivedConstraint && baseConstraint) { + const XsdTypeChecker checker(context, QVector(), QSourceLocation(QUrl(QLatin1String("http://dummy.org")), 1, 1)); + if (derivedConstraint->variety() == XsdAttributeUse::ValueConstraint::Fixed && checker.valuesAreEqual(derivedConstraint->value(), baseConstraint->value(), baseAttributeUse->attribute()->type())) + ok = true; + } + + if (!ok) { + errorMsg = QtXmlPatterns::tr("value constraint of derived attribute %1 does not match value constraint of base attribute").arg(formatAttribute(derivedAttributeUse->attribute()->displayName(namePool))); + return false; + } + } else { + if (!wildcard) { + errorMsg = QtXmlPatterns::tr("derived attribute %1 does not exists in the base definition").arg(formatAttribute(derivedAttributeUse->attribute()->displayName(namePool))); + return false; + } + + QXmlName name = derivedAttributeUse->attribute()->name(namePool); + + // wildcards using XsdWildcard::absentNamespace, so we have to fix that here + if (name.namespaceURI() == StandardNamespaces::empty) + name.setNamespaceURI(namePool->allocateNamespace(XsdWildcard::absentNamespace())); + + if (!wildcardAllowsExpandedName(name, wildcard, namePool)) { + errorMsg = QtXmlPatterns::tr("derived attribute %1 does not match the wildcard in the base definition").arg(formatAttribute(derivedAttributeUse->attribute()->displayName(namePool))); + return false; + } + } + } + + // 3 + for (int i = 0; i < baseAttributeUses.count(); ++i) { + const XsdAttributeUse::Ptr baseAttributeUse = baseAttributeUses.at(i); + + if (baseAttributeUse->isRequired()) { + if (derivedAttributeUsesLookup.contains(baseAttributeUse->attribute()->name(namePool))) { + if (!derivedAttributeUsesLookup.value(baseAttributeUse->attribute()->name(namePool))->isRequired()) { + errorMsg = QtXmlPatterns::tr("base attribute %1 is required but derived attribute is not").arg(formatAttribute(baseAttributeUse->attribute()->displayName(namePool))); + return false; + } + } else { + errorMsg = QtXmlPatterns::tr("base attribute %1 is required but missing in derived definition").arg(formatAttribute(baseAttributeUse->attribute()->displayName(namePool))); + return false; + } + } + } + + // 4 + if (derivedWildcard) { + if (!wildcard) { + errorMsg = QtXmlPatterns::tr("derived definition contains an %1 element that does not exists in the base definition").arg(formatElement("anyAttribute")); + return false; + } + + if (!isWildcardSubset(derivedWildcard, wildcard)) { + errorMsg = QtXmlPatterns::tr("derived wildcard is not a subset of the base wildcard"); + return false; + } + + if (!checkWildcardProcessContents(wildcard, derivedWildcard)) { + errorMsg = QtXmlPatterns::tr("%1 of derived wildcard is not a valid restriction of %2 of base wildcard").arg(formatKeyword("processContents")).arg(formatKeyword("processContents")); + return false; + } + } + + return true; +} + +bool XsdSchemaHelper::isValidAttributeUsesExtension(const XsdAttributeUse::List &derivedAttributeUses, const XsdAttributeUse::List &attributeUses, + const XsdWildcard::Ptr &derivedWildcard, const XsdWildcard::Ptr &wildcard, const XsdSchemaContext::Ptr &context, QString &errorMsg) +{ + // @see http://www.w3.org/TR/xmlschema11-1/#cos-ct-extends + + const NamePool::Ptr namePool(context->namePool()); + + // 1.2 + QHash lookupHash; + for (int i = 0; i < derivedAttributeUses.count(); ++i) + lookupHash.insert(derivedAttributeUses.at(i)->attribute()->name(namePool), derivedAttributeUses.at(i)->attribute()); + + for (int i = 0; i < attributeUses.count(); ++i) { + const QXmlName attributeName = attributeUses.at(i)->attribute()->name(namePool); + if (!lookupHash.contains(attributeName)) { + errorMsg = QtXmlPatterns::tr("attribute %1 from base type is missing in derived type").arg(formatKeyword(namePool->displayName(attributeName))); + return false; + } + + if (lookupHash.value(attributeName)->type() != attributeUses.at(i)->attribute()->type()) { + errorMsg = QtXmlPatterns::tr("type of derived attribute %1 differs from type of base attribute").arg(formatKeyword(namePool->displayName(attributeName))); + return false; + } + } + + // 1.3 + if (wildcard) { + if (!derivedWildcard) { + errorMsg = QtXmlPatterns::tr("base definition contains an %1 element that is missing in the derived definition").arg(formatElement("anyAttribute")); + return false; + } + } + + return true; +} + +QT_END_NAMESPACE diff --git a/src/xmlpatterns/schema/qxsdschemahelper_p.h b/src/xmlpatterns/schema/qxsdschemahelper_p.h new file mode 100644 index 0000000..1722b4c --- /dev/null +++ b/src/xmlpatterns/schema/qxsdschemahelper_p.h @@ -0,0 +1,156 @@ +/**************************************************************************** +** +** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the $MODULE$ of the Qt Toolkit. +** +** $TROLLTECH_DUAL_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_XsdSchemaHelper_H +#define Patternist_XsdSchemaHelper_H + +#include "qcomparisonfactory_p.h" +#include "qschematype_p.h" +#include "qxsdattributegroup_p.h" +#include "qxsdelement_p.h" +#include "qxsdparticle_p.h" +#include "qxsdschemacontext_p.h" +#include "qxsdwildcard_p.h" + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +namespace QPatternist +{ + + /** + * @short Contains helper methods that are used by XsdSchemaParser, XsdSchemaResolver and XsdSchemaChecker. + * + * @ingroup Patternist_schema + * @author Tobias Koenig + */ + class XsdSchemaHelper + { + public: + /** + * Checks whether the given @p particle is emptiable as defined by the + * algorithm in the schema spec. + */ + static bool isParticleEmptiable(const XsdParticle::Ptr &particle); + + /** + * Checks whether the given @p nameSpace is allowed by the given namespace @p constraint. + */ + static bool wildcardAllowsNamespaceName(const QString &nameSpace, const XsdWildcard::NamespaceConstraint::Ptr &constraint); + + /** + * Checks whether the given @p name is allowed by the namespace constraint of the given @p wildcard. + */ + static bool wildcardAllowsExpandedName(const QXmlName &name, const XsdWildcard::Ptr &wildcard, const NamePool::Ptr &namePool); + + /** + * Checks whether the @p wildcard is a subset of @p otherWildcard. + */ + static bool isWildcardSubset(const XsdWildcard::Ptr &wildcard, const XsdWildcard::Ptr &otherWildcard); + + /** + * Returns the union of the given @p wildcard and @p otherWildcard. + */ + static XsdWildcard::Ptr wildcardUnion(const XsdWildcard::Ptr &wildcard, const XsdWildcard::Ptr &otherWildcard); + + /** + * Returns the intersection of the given @p wildcard and @p otherWildcard. + */ + static XsdWildcard::Ptr wildcardIntersection(const XsdWildcard::Ptr &wildcard, const XsdWildcard::Ptr &otherWildcard); + + /** + * Returns whether the given @p type is validly substitutable for an @p otherType + * under the given @p constraints. + */ + static bool isValidlySubstitutable(const SchemaType::Ptr &type, const SchemaType::Ptr &otherType, const SchemaType::DerivationConstraints &constraints); + + /** + * Returns whether the simple @p derivedType can be derived from the simple @p baseType + * under the given @p constraints. + */ + static bool isSimpleDerivationOk(const SchemaType::Ptr &derivedType, const SchemaType::Ptr baseType, const SchemaType::DerivationConstraints &constraints); + + /** + * Returns whether the complex @p derivedType can be derived from the complex @p baseType + * under the given @p constraints. + */ + static bool isComplexDerivationOk(const SchemaType::Ptr &derivedType, const SchemaType::Ptr baseType, const SchemaType::DerivationConstraints &constraints); + + /** + * This method takes the two string based operands @p operand1 and @p operand2 and converts them to instances of type @p type. + * If the conversion fails, @c false is returned, otherwise the instances are compared by the given operator @p op and the + * result of the comparison is returned. + */ + static bool constructAndCompare(const DerivedString::Ptr &operand1, + const AtomicComparator::Operator op, + const DerivedString::Ptr &operand2, + const SchemaType::Ptr &type, + const ReportContext::Ptr &context, + const SourceLocationReflection *const sourceLocationReflection); + + /** + * Returns whether the process content property of the @p derivedWildcard is valid + * according to the process content property of its @p baseWildcard. + */ + static bool checkWildcardProcessContents(const XsdWildcard::Ptr &baseWildcard, const XsdWildcard::Ptr &derivedWildcard); + + /** + * Checks whether @[ member is a member of the substitution group with the given @p head. + */ + static bool foundSubstitutionGroupTransitive(const XsdElement::Ptr &head, const XsdElement::Ptr &member, QSet &visitedElements); + + /** + * A helper method that iterates over the type hierarchy from @p memberType up to @p headType and collects all + * @p derivationSet and @p blockSet constraints that exists on the way there. + */ + static void foundSubstitutionGroupTypeInheritance(const SchemaType::Ptr &headType, const SchemaType::Ptr &memberType, + QSet &derivationSet, NamedSchemaComponent::BlockingConstraints &blockSet); + + /** + * Checks if the @p member is transitive to @p head. + */ + static bool substitutionGroupOkTransitive(const XsdElement::Ptr &head, const XsdElement::Ptr &member, const NamePool::Ptr &namePool); + + /** + * Checks if @p derivedAttributeGroup is a valid restriction for @p attributeGroup. + */ + static bool isValidAttributeGroupRestriction(const XsdAttributeGroup::Ptr &derivedAttributeGroup, const XsdAttributeGroup::Ptr &attributeGroup, const XsdSchemaContext::Ptr &context, QString &errorMsg); + + /** + * Checks if @p derivedAttributeUses are a valid restriction for @p attributeUses. + */ + static bool isValidAttributeUsesRestriction(const XsdAttributeUse::List &derivedAttributeUses, const XsdAttributeUse::List &attributeUses, + const XsdWildcard::Ptr &derivedWildcard, const XsdWildcard::Ptr &wildcard, const XsdSchemaContext::Ptr &context, QString &errorMsg); + + /** + * Checks if @p derivedAttributeUses are a valid extension for @p attributeUses. + */ + static bool isValidAttributeUsesExtension(const XsdAttributeUse::List &derivedAttributeUses, const XsdAttributeUse::List &attributeUses, + const XsdWildcard::Ptr &derivedWildcard, const XsdWildcard::Ptr &wildcard, const XsdSchemaContext::Ptr &context, QString &errorMsg); + }; +} + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif diff --git a/src/xmlpatterns/schema/qxsdschemamerger.cpp b/src/xmlpatterns/schema/qxsdschemamerger.cpp new file mode 100644 index 0000000..a924c9c --- /dev/null +++ b/src/xmlpatterns/schema/qxsdschemamerger.cpp @@ -0,0 +1,127 @@ +/**************************************************************************** +** +** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the $MODULE$ of the Qt Toolkit. +** +** $TROLLTECH_DUAL_LICENSE$ +** +****************************************************************************/ + +#include "qxsdschemamerger_p.h" + +QT_BEGIN_NAMESPACE + +using namespace QPatternist; + +XsdSchemaMerger::XsdSchemaMerger(const XsdSchema::Ptr &schema, const XsdSchema::Ptr &otherSchema) +{ + merge(schema, otherSchema); +} + +XsdSchema::Ptr XsdSchemaMerger::mergedSchema() const +{ + return m_mergedSchema; +} + +void XsdSchemaMerger::merge(const XsdSchema::Ptr &schema, const XsdSchema::Ptr &otherSchema) +{ + m_mergedSchema = XsdSchema::Ptr(new XsdSchema(otherSchema->namePool())); + + // first fill the merged schema with the values from schema + if (schema) { + const XsdElement::List elements = schema->elements(); + for (int i = 0; i < elements.count(); ++i) { + m_mergedSchema->addElement(elements.at(i)); + } + + const XsdAttribute::List attributes = schema->attributes(); + for (int i = 0; i < attributes.count(); ++i) { + m_mergedSchema->addAttribute(attributes.at(i)); + } + + const SchemaType::List types = schema->types(); + for (int i = 0; i < types.count(); ++i) { + m_mergedSchema->addType(types.at(i)); + } + + const SchemaType::List anonymousTypes = schema->anonymousTypes(); + for (int i = 0; i < anonymousTypes.count(); ++i) { + m_mergedSchema->addAnonymousType(anonymousTypes.at(i)); + } + + const XsdModelGroup::List elementGroups = schema->elementGroups(); + for (int i = 0; i < elementGroups.count(); ++i) { + m_mergedSchema->addElementGroup(elementGroups.at(i)); + } + + const XsdAttributeGroup::List attributeGroups = schema->attributeGroups(); + for (int i = 0; i < attributeGroups.count(); ++i) { + m_mergedSchema->addAttributeGroup(attributeGroups.at(i)); + } + + const XsdNotation::List notations = schema->notations(); + for (int i = 0; i < notations.count(); ++i) { + m_mergedSchema->addNotation(notations.at(i)); + } + + const XsdIdentityConstraint::List identityConstraints = schema->identityConstraints(); + for (int i = 0; i < identityConstraints.count(); ++i) { + m_mergedSchema->addIdentityConstraint(identityConstraints.at(i)); + } + } + + // then merge in the values from the otherSchema + { + const XsdElement::List elements = otherSchema->elements(); + for (int i = 0; i < elements.count(); ++i) { + if (!m_mergedSchema->element(elements.at(i)->name(otherSchema->namePool()))) + m_mergedSchema->addElement(elements.at(i)); + } + + const XsdAttribute::List attributes = otherSchema->attributes(); + for (int i = 0; i < attributes.count(); ++i) { + if (!m_mergedSchema->attribute(attributes.at(i)->name(otherSchema->namePool()))) + m_mergedSchema->addAttribute(attributes.at(i)); + } + + const SchemaType::List types = otherSchema->types(); + for (int i = 0; i < types.count(); ++i) { + if (!m_mergedSchema->type(types.at(i)->name(otherSchema->namePool()))) + m_mergedSchema->addType(types.at(i)); + } + + const SchemaType::List anonymousTypes = otherSchema->anonymousTypes(); + for (int i = 0; i < anonymousTypes.count(); ++i) { + // add anonymous type as they are + m_mergedSchema->addAnonymousType(anonymousTypes.at(i)); + } + + const XsdModelGroup::List elementGroups = otherSchema->elementGroups(); + for (int i = 0; i < elementGroups.count(); ++i) { + if (!m_mergedSchema->elementGroup(elementGroups.at(i)->name(otherSchema->namePool()))) + m_mergedSchema->addElementGroup(elementGroups.at(i)); + } + + const XsdAttributeGroup::List attributeGroups = otherSchema->attributeGroups(); + for (int i = 0; i < attributeGroups.count(); ++i) { + if (!m_mergedSchema->attributeGroup(attributeGroups.at(i)->name(otherSchema->namePool()))) + m_mergedSchema->addAttributeGroup(attributeGroups.at(i)); + } + + const XsdNotation::List notations = otherSchema->notations(); + for (int i = 0; i < notations.count(); ++i) { + if (!m_mergedSchema->notation(notations.at(i)->name(otherSchema->namePool()))) + m_mergedSchema->addNotation(notations.at(i)); + } + + const XsdIdentityConstraint::List identityConstraints = otherSchema->identityConstraints(); + for (int i = 0; i < identityConstraints.count(); ++i) { + if (!m_mergedSchema->identityConstraint(identityConstraints.at(i)->name(otherSchema->namePool()))) + m_mergedSchema->addIdentityConstraint(identityConstraints.at(i)); + } + } +} + +QT_END_NAMESPACE diff --git a/src/xmlpatterns/schema/qxsdschemamerger_p.h b/src/xmlpatterns/schema/qxsdschemamerger_p.h new file mode 100644 index 0000000..54cc0f2 --- /dev/null +++ b/src/xmlpatterns/schema/qxsdschemamerger_p.h @@ -0,0 +1,69 @@ +/**************************************************************************** +** +** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the $MODULE$ of the Qt Toolkit. +** +** $TROLLTECH_DUAL_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_XsdSchemaMerger_H +#define Patternist_XsdSchemaMerger_H + +#include "qxsdschema_p.h" + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +namespace QPatternist +{ + /** + * @short A helper class that merges two schemas into one. + * + * This class is used in XsdValidatingInstanceReader to merge the schema + * given in the constructor with a schema defined in the instance document + * via xsi:schemaLocation or xsi:noNamespaceSchema location. + * + * @ingroup Patternist_schema + * @author Tobias Koenig + */ + class XsdSchemaMerger : public QSharedData + { + public: + typedef QExplicitlySharedDataPointer Ptr; + + /** + * Creates a new schema merger object that merges @p schema with @p otherSchema. + */ + XsdSchemaMerger(const XsdSchema::Ptr &schema, const XsdSchema::Ptr &otherSchema); + + /** + * Returns the merged schema. + */ + XsdSchema::Ptr mergedSchema() const; + + private: + void merge(const XsdSchema::Ptr &schema, const XsdSchema::Ptr &otherSchema); + + XsdSchema::Ptr m_mergedSchema; + }; +} + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif diff --git a/src/xmlpatterns/schema/qxsdschemaparser.cpp b/src/xmlpatterns/schema/qxsdschemaparser.cpp new file mode 100644 index 0000000..9f1e75d --- /dev/null +++ b/src/xmlpatterns/schema/qxsdschemaparser.cpp @@ -0,0 +1,6012 @@ + +#include "qxsdschemaparser_p.h" + +#include "private/qxmlutils_p.h" +#include "qacceltreeresourceloader_p.h" +#include "qautoptr_p.h" +#include "qboolean_p.h" +#include "qderivedinteger_p.h" +#include "qderivedstring_p.h" +#include "qqnamevalue_p.h" +#include "qxmlquery_p.h" +#include "qxpathhelper_p.h" +#include "qxsdattributereference_p.h" +#include "qxsdreference_p.h" +#include "qxsdschematoken_p.h" + +#include +#include + +QT_BEGIN_NAMESPACE + +/** + * @page schema_overview Overview + * @section structure_and_components Structure and Components + * + * The schema validator code consists of 4 major components + * + *
+ *
The schema parser (QPatternist::XsdSchemaParser)
+ *
This component parses a XML document that is supplied via a QIODevice. It creates + * a so called (incomplete) 'compiled schema', which is a representation of the XML Schema + * structure as C++ objects. + * As the parser is a streaming parser, it can't resolve references to types or elements/attributes + * in place, therefor it creates resolver tasks which are passed to the schema resolver component + * for resolving at a later point in time. + * The parser does furthermore the basic XML structure constraint checking, e.g. if all required + * attributes are available or the order of the elements is correct.
+ * + *
The schema resolver (QPatternist::XsdSchemaResolver)
+ *
This component is activated after the schema parser component has been finished the parsing + * of all schemas. The resolver has been supplied with resolve tasks by the schema parser that + * it will resolve in this step now. Between working on the single resolver tasks, the resolver + * calls check methods from the schema checker component to make sure that some assertions are + * valid (e.g. no circular inheritance of types), so that the resolver can work without hassle. + * During resoving references to attribute or element groups it also checks for circular references + * of these groups. + * At the end of that phase we have a compiled schema that is fully resolved (not necessarily valid though).
+ * + *
The schema checker (QPatternist::XsdSchemaChecker)
+ *
This component does all the schema constraint checking as given by the Schema specification. + * At the end of that phase we have fully resolved and valid compiled schema that can be used for validation + * of instance documents.
+ * + *
The validator (QPatternist::XsdValidatingInstanceReader)
+ *
This component is responsible for validating a XML instance document, provided via a QIODevice, against + * a valid compiled schema.
+ *
+ * + * @ingroup Patternist_schema + */ + +using namespace QPatternist; + +namespace QPatternist +{ + +/** + * @short A helper class for automatically handling namespace scopes of elements. + * + * This class should be instantiated at the beginning of each parse XYZ method. + */ +class ElementNamespaceHandler +{ + public: + /** + * Creates a new element namespace handler object. + * + * It checks whether the @p parser is on the right @p tag and it creates a new namespace + * context that contains the inherited and local namespace declarations. + */ + ElementNamespaceHandler(const XsdSchemaToken::NodeName &tag, XsdSchemaParser *parser) + : m_parser(parser) + { + Q_ASSERT(m_parser->isStartElement() && (XsdSchemaToken::toToken(m_parser->name()) == tag) && (XsdSchemaToken::toToken(m_parser->namespaceUri()) == XsdSchemaToken::XML_NS_SCHEMA_URI)); + m_parser->m_namespaceSupport.pushContext(); + m_parser->m_namespaceSupport.setPrefixes(m_parser->namespaceDeclarations()); + } + + /** + * Destroys the element namespace handler object. + * + * It destroys the local namespace context. + */ + ~ElementNamespaceHandler() + { + m_parser->m_namespaceSupport.popContext(); + } + + private: + XsdSchemaParser *m_parser; +}; + +/** + * A helper class that checks for the right occurrence of + * xml tags with the help of a DFA. + */ +class TagValidationHandler +{ + public: + TagValidationHandler(XsdTagScope::Type tag, XsdSchemaParser *parser, const NamePool::Ptr &namePool) + : m_parser(parser), m_machine(namePool) + { + Q_ASSERT(m_parser->m_stateMachines.contains(tag)); + + m_machine = m_parser->m_stateMachines.value(tag); + m_machine.reset(); + } + + void validate(XsdSchemaToken::NodeName token) + { + if (token == XsdSchemaToken::NoKeyword) { + m_parser->error(QtXmlPatterns::tr("can not process unknown element %1").arg(formatElement(m_parser->name().toString()))); + return; + } + + if (!m_machine.proceed(token)) { + m_parser->error(QtXmlPatterns::tr("element %1 is not allowed in this scope").arg(formatElement(XsdSchemaToken::toString(token)))); + return; + } + } + + void finalize() const + { + if (!m_machine.inEndState()) { + m_parser->error(QtXmlPatterns::tr("child element is missing in that scope")); + } + } + + private: + XsdSchemaParser *m_parser; + XsdStateMachine m_machine; +}; + +} + +/** + * Returns a list of all particles with group references that appear at any level of + * the given unresolved @p group. + */ +static XsdParticle::List collectGroupRef(const XsdModelGroup::Ptr &group) +{ + XsdParticle::List refParticles; + + XsdParticle::List particles = group->particles(); + for (int i = 0; i < particles.count(); ++i) { + if (particles.at(i)->term()->isReference()) { + const XsdReference::Ptr reference(particles.at(i)->term()); + if (reference->type() == XsdReference::ModelGroup) + refParticles.append(particles.at(i)); + } + if (particles.at(i)->term()->isModelGroup()) { + refParticles << collectGroupRef(XsdModelGroup::Ptr(particles.at(i)->term())); + } + } + + return refParticles; +} + +/** + * Helper function that works around the limited facilities of + * QUrl/AnyURI::fromLexical to detect invalid URIs + */ +inline static bool isValidUri(const QString &string) +{ + // an empty URI points to the current document as defined in RFC 2396 (4.2) + if (string.isEmpty()) + return true; + + // explicit check as that is not checked by the code below + if (string.startsWith(QLatin1String("##"))) + return false; + + const AnyURI::Ptr uri = AnyURI::fromLexical(string); + return (!(uri->hasError())); +} + +XsdSchemaParser::XsdSchemaParser(const XsdSchemaContext::Ptr &context, const XsdSchemaParserContext::Ptr &parserContext, QIODevice *device) + : MaintainingReader(parserContext->elementDescriptions(), QSet(), context, device) + , m_context(context) + , m_parserContext(parserContext) + , m_namePool(m_parserContext->namePool()) + , m_namespaceSupport(m_namePool) +{ + m_schema = m_parserContext->schema(); + m_schemaResolver = m_parserContext->resolver(); + m_idCache = XsdIdCache::Ptr(new XsdIdCache()); + + setupStateMachines(); + setupBuiltinTypeNames(); +} + +void XsdSchemaParser::setIncludedSchemas(const NamespaceSet &schemas) +{ + m_includedSchemas = schemas; +} + +void XsdSchemaParser::setImportedSchemas(const NamespaceSet &schemas) +{ + m_importedSchemas = schemas; +} + +void XsdSchemaParser::setRedefinedSchemas(const NamespaceSet &schemas) +{ + m_redefinedSchemas = schemas; +} + +void XsdSchemaParser::setTargetNamespace(const QString &targetNamespace) +{ + m_targetNamespace = targetNamespace; +} + +void XsdSchemaParser::setTargetNamespaceExtended(const QString &targetNamespace) +{ + m_targetNamespace = targetNamespace; + m_namespaceSupport.setTargetNamespace(m_namePool->allocateNamespace(m_targetNamespace)); +} + +void XsdSchemaParser::setDocumentURI(const QUrl &uri) +{ + qDebug("%s", qPrintable(uri.toString())); + m_documentURI = uri; + + // prevent to get included/imported/redefined twice + m_includedSchemas.insert(uri); + m_importedSchemas.insert(uri); +} + +QUrl XsdSchemaParser::documentURI() const +{ + return m_documentURI; +} + +bool XsdSchemaParser::isAnyAttributeAllowed() const +{ + return false; +} + +bool XsdSchemaParser::parse(ParserType parserType) +{ + m_componentLocationHash.clear(); + + while (!atEnd()) { + readNext(); + + if (isStartElement()) { + const XsdSchemaToken::NodeName token = XsdSchemaToken::toToken(name()); + const XsdSchemaToken::NodeName namespaceToken = XsdSchemaToken::toToken(namespaceUri()); + + if (isSchemaTag(XsdSchemaToken::Schema, token, namespaceToken)) { + parseSchema(parserType); + } else { + error(QtXmlPatterns::tr("document is not a XML schema")); + } + } + } + + m_schemaResolver->addComponentLocationHash(m_componentLocationHash); + m_schemaResolver->setDefaultOpenContent(m_defaultOpenContent, m_defaultOpenContentAppliesToEmpty); + + return true; +} + +void XsdSchemaParser::error(const QString &msg) +{ + MaintainingReader::error(msg, XsdSchemaContext::XSDError); +} + +void XsdSchemaParser::attributeContentError(const char *attributeName, const char *elementName, const QString &value, const SchemaType::Ptr &type) +{ + if (type) { + error(QtXmlPatterns::tr("%1 attribute of %2 element contains invalid content: {%3} is not a value of type %4") + .arg(formatAttribute(attributeName)) + .arg(formatElement(elementName)) + .arg(formatData(value)) + .arg(formatType(m_namePool, type))); + } else { + error(QtXmlPatterns::tr("%1 attribute of %2 element contains invalid content: {%3}") + .arg(formatAttribute(attributeName)) + .arg(formatElement(elementName)) + .arg(formatData(value))); + } +} + +void XsdSchemaParser::parseSchema(ParserType parserType) +{ + const ElementNamespaceHandler namespaceHandler(XsdSchemaToken::Schema, this); + + validateElement(XsdTagScope::Schema); + + // parse attributes + + if (parserType == TopLevelParser) { + if (hasAttribute(QString::fromLatin1("targetNamespace"))) { + m_targetNamespace = readNamespaceAttribute(QString::fromLatin1("targetNamespace"), "schema"); + } + } else if (parserType == IncludeParser) { + // m_targetNamespace is set to the target namespace of the including schema at this point + + if (hasAttribute(QString::fromLatin1("targetNamespace"))) { + const QString targetNamespace = readNamespaceAttribute(QString::fromLatin1("targetNamespace"), "schema"); + + if (m_targetNamespace != targetNamespace) { + error(QtXmlPatterns::tr("target namespace %1 of included schema is different from the target namespace %2 as defined by the including schema") + .arg(formatURI(targetNamespace)).arg(formatURI(m_targetNamespace))); + return; + } + } + } else if (parserType == ImportParser) { + // m_targetNamespace is set to the target namespace from the namespace attribute of the tag at this point + + QString targetNamespace; + if (hasAttribute(QString::fromLatin1("targetNamespace"))) { + targetNamespace = readNamespaceAttribute(QString::fromLatin1("targetNamespace"), "schema"); + } + + if (m_targetNamespace != targetNamespace) { + error(QtXmlPatterns::tr("target namespace %1 of imported schema is different from the target namespace %2 as defined by the importing schema") + .arg(formatURI(targetNamespace)).arg(formatURI(m_targetNamespace))); + return; + } + } else if (parserType == RedefineParser) { + // m_targetNamespace is set to the target namespace of the redefining schema at this point + + if (hasAttribute(QString::fromLatin1("targetNamespace"))) { + const QString targetNamespace = readNamespaceAttribute(QString::fromLatin1("targetNamespace"), "schema"); + + if (m_targetNamespace != targetNamespace) { + error(QtXmlPatterns::tr("target namespace %1 of imported schema is different from the target namespace %2 as defined by the importing schema") + .arg(formatURI(targetNamespace)).arg(formatURI(m_targetNamespace))); + return; + } + } + } + + if (hasAttribute(QString::fromLatin1("attributeFormDefault"))) { + const QString value = readAttribute(QString::fromLatin1("attributeFormDefault")); + if (value != QString::fromLatin1("qualified") && value != QString::fromLatin1("unqualified")) { + attributeContentError("attributeFormDefault", "schema", value); + return; + } + + m_attributeFormDefault = value; + } else { + m_attributeFormDefault = QString::fromLatin1("unqualified"); + } + + if (hasAttribute(QString::fromLatin1("elementFormDefault"))) { + const QString value = readAttribute(QString::fromLatin1("elementFormDefault")); + if (value != QString::fromLatin1("qualified") && value != QString::fromLatin1("unqualified")) { + attributeContentError("elementFormDefault", "schema", value); + return; + } + + m_elementFormDefault = value; + } else { + m_elementFormDefault = QString::fromLatin1("unqualified"); + } + + if (hasAttribute(QString::fromLatin1("blockDefault"))) { + const QString blockDefault = readAttribute(QString::fromLatin1("blockDefault")); + const QStringList blockDefaultList = blockDefault.split(QLatin1Char(' '), QString::SkipEmptyParts); + for (int i = 0; i < blockDefaultList.count(); ++i) { + const QString value = blockDefaultList.at(i); + if (value != QString::fromLatin1("#all") && + value != QString::fromLatin1("extension") && + value != QString::fromLatin1("restriction") && + value != QString::fromLatin1("substitution")) { + attributeContentError("blockDefault", "schema", value); + return; + } + } + + m_blockDefault = blockDefault; + } + + if (hasAttribute(QString::fromLatin1("finalDefault"))) { + const QString finalDefault = readAttribute(QString::fromLatin1("finalDefault")); + const QStringList finalDefaultList = finalDefault.split(QLatin1Char(' '), QString::SkipEmptyParts); + for (int i = 0; i < finalDefaultList.count(); ++i) { + const QString value = finalDefaultList.at(i); + if (value != QString::fromLatin1("#all") && + value != QString::fromLatin1("extension") && + value != QString::fromLatin1("restriction") && + value != QString::fromLatin1("list") && + value != QString::fromLatin1("union")) { + attributeContentError("finalDefault", "schema", value); + return; + } + } + + m_finalDefault = finalDefault; + } + + if (hasAttribute(QString::fromLatin1("xpathDefaultNamespace"))) { + const QString xpathDefaultNamespace = readAttribute(QString::fromLatin1("xpathDefaultNamespace")); + if (xpathDefaultNamespace != QString::fromLatin1("##defaultNamespace") && + xpathDefaultNamespace != QString::fromLatin1("##targetNamespace") && + xpathDefaultNamespace != QString::fromLatin1("##local")) { + if (!isValidUri(xpathDefaultNamespace)) { + attributeContentError("xpathDefaultNamespace", "schema", xpathDefaultNamespace); + return; + } + } + m_xpathDefaultNamespace = xpathDefaultNamespace; + } else { + m_xpathDefaultNamespace = QString::fromLatin1("##local"); + } + + if (hasAttribute(QString::fromLatin1("defaultAttributes"))) { + const QString attrGroupName = readQNameAttribute(QString::fromLatin1("defaultAttributes"), "schema"); + convertName(attrGroupName, NamespaceSupport::ElementName, m_defaultAttributes); // translate qualified name into QXmlName + } + + if (hasAttribute(QString::fromLatin1("version"))) { + const QString version = readAttribute(QString::fromLatin1("version")); + } + + if (hasAttribute(QString::fromLatin1("http://www.w3.org/XML/1998/namespace"), QString::fromLatin1("lang"))) { + const QString value = readAttribute(QString::fromLatin1("lang"), QString::fromLatin1("http://www.w3.org/XML/1998/namespace")); + + const QRegExp exp(QString::fromLatin1("[a-zA-Z]{1,8}(-[a-zA-Z0-9]{1,8})*")); + if (!exp.exactMatch(value)) { + attributeContentError("xml:lang", "schema", value); + return; + } + } + + validateIdAttribute("schema"); + + TagValidationHandler tagValidator(XsdTagScope::Schema, this, m_namePool); + + while (!atEnd()) { + readNext(); + + if (isEndElement()) + break; + + if (isStartElement()) { + const XsdSchemaToken::NodeName token = XsdSchemaToken::toToken(name()); + const XsdSchemaToken::NodeName namespaceToken = XsdSchemaToken::toToken(namespaceUri()); + + tagValidator.validate(token); + + if (isSchemaTag(XsdSchemaToken::Include, token, namespaceToken)) { + parseInclude(); + } else if (isSchemaTag(XsdSchemaToken::Import, token, namespaceToken)) { + parseImport(); + } else if (isSchemaTag(XsdSchemaToken::Redefine, token, namespaceToken)) { + parseRedefine(); + } else if (isSchemaTag(XsdSchemaToken::Annotation, token, namespaceToken)) { + const XsdAnnotation::Ptr annotation = parseAnnotation(); + m_schema->addAnnotation(annotation); + } else if (isSchemaTag(XsdSchemaToken::DefaultOpenContent, token, namespaceToken)) { + parseDefaultOpenContent(); + } else if (isSchemaTag(XsdSchemaToken::SimpleType, token, namespaceToken)) { + const XsdSimpleType::Ptr type = parseGlobalSimpleType(); + addType(type); + } else if (isSchemaTag(XsdSchemaToken::ComplexType, token, namespaceToken)) { + const XsdComplexType::Ptr type = parseGlobalComplexType(); + addType(type); + } else if (isSchemaTag(XsdSchemaToken::Group, token, namespaceToken)) { + const XsdModelGroup::Ptr group = parseNamedGroup(); + addElementGroup(group); + } else if (isSchemaTag(XsdSchemaToken::AttributeGroup, token, namespaceToken)) { + XsdAttributeGroup::Ptr attributeGroup = parseNamedAttributeGroup(); + addAttributeGroup(attributeGroup); + } else if (isSchemaTag(XsdSchemaToken::Element, token, namespaceToken)) { + const XsdElement::Ptr element = parseGlobalElement(); + addElement(element); + } else if (isSchemaTag(XsdSchemaToken::Attribute, token, namespaceToken)) { + const XsdAttribute::Ptr attribute = parseGlobalAttribute(); + addAttribute(attribute); + } else if (isSchemaTag(XsdSchemaToken::Notation, token, namespaceToken)) { + const XsdNotation::Ptr notation = parseNotation(); + addNotation(notation); + } else { + parseUnknown(); + } + } + } + + tagValidator.finalize(); + + m_schema->setTargetNamespace(m_targetNamespace); +} + +void XsdSchemaParser::parseInclude() +{ + Q_ASSERT(isStartElement() && XsdSchemaToken::toToken(name()) == XsdSchemaToken::Include && + XsdSchemaToken::toToken(namespaceUri()) == XsdSchemaToken::XML_NS_SCHEMA_URI); + + validateElement(XsdTagScope::Include); + + // parse attributes + const QString schemaLocation = readAttribute(QString::fromLatin1("schemaLocation")); + + QUrl url(schemaLocation); + if (url.isRelative()) { + Q_ASSERT(m_documentURI.isValid()); + + url = m_documentURI.resolved(url); + } + + if (m_includedSchemas.contains(url)) { + // we have included that file already, according to the schema spec we are + // allowed to silently skip it. + } else { + m_includedSchemas.insert(url); + + const AutoPtr reply(AccelTreeResourceLoader::load(url, m_context->networkAccessManager(), + m_context, AccelTreeResourceLoader::ContinueOnError)); + if (reply) { + // parse the included schema by a different parser but with the same context + XsdSchemaParser parser(m_context, m_parserContext, reply.data()); + parser.setDocumentURI(url); + parser.setTargetNamespaceExtended(m_targetNamespace); + parser.setIncludedSchemas(m_includedSchemas); + parser.setImportedSchemas(m_importedSchemas); + parser.setRedefinedSchemas(m_redefinedSchemas); + if (!parser.parse(XsdSchemaParser::IncludeParser)) + return; + } + } + + validateIdAttribute("include"); + + TagValidationHandler tagValidator(XsdTagScope::Include, this, m_namePool); + + while (!atEnd()) { + readNext(); + + if (isEndElement()) + break; + + if (isStartElement()) { + const XsdSchemaToken::NodeName token = XsdSchemaToken::toToken(name()); + const XsdSchemaToken::NodeName namespaceToken = XsdSchemaToken::toToken(namespaceUri()); + + tagValidator.validate(token); + + if (isSchemaTag(XsdSchemaToken::Annotation, token, namespaceToken)) { + const XsdAnnotation::Ptr annotation = parseAnnotation(); + m_schema->addAnnotation(annotation); + } else { + parseUnknown(); + } + } + } + + tagValidator.finalize(); +} + +void XsdSchemaParser::parseImport() +{ + Q_ASSERT(isStartElement() && XsdSchemaToken::toToken(name()) == XsdSchemaToken::Import && + XsdSchemaToken::toToken(namespaceUri()) == XsdSchemaToken::XML_NS_SCHEMA_URI); + + validateElement(XsdTagScope::Import); + + // parse attributes + QString importNamespace; + if (hasAttribute(QString::fromLatin1("namespace"))) { + importNamespace = readAttribute(QString::fromLatin1("namespace")); + if (importNamespace == m_targetNamespace) { + error(QtXmlPatterns::tr("%1 element is not allowed to have the same %2 attribute value as the target namespace %3") + .arg(formatElement("import")) + .arg(formatAttribute("namespace")) + .arg(formatURI(m_targetNamespace))); + return; + } + } else { + if (m_targetNamespace.isEmpty()) { + error(QtXmlPatterns::tr("%1 element without %2 attribute is not allowed inside schema without target namespace") + .arg(formatElement("import")) + .arg(formatAttribute("namespace"))); + return; + } + } + + if (hasAttribute(QString::fromLatin1("schemaLocation"))) { + const QString schemaLocation = readAttribute(QString::fromLatin1("schemaLocation")); + + QUrl url(schemaLocation); + if (url.isRelative()) { + Q_ASSERT(m_documentURI.isValid()); + + url = m_documentURI.resolved(url); + } + + if (m_importedSchemas.contains(url)) { + // we have imported that file already, according to the schema spec we are + // allowed to silently skip it. + } else { + m_importedSchemas.insert(url); + + // as it is possible that well known schemas (e.g. XSD for XML) are only referenced by + // namespace we should add it as well + m_importedSchemas.insert(importNamespace); + + AutoPtr reply(AccelTreeResourceLoader::load(url, m_context->networkAccessManager(), + m_context, AccelTreeResourceLoader::ContinueOnError)); + if (reply) { + // parse the included schema by a different parser but with the same context + XsdSchemaParser parser(m_context, m_parserContext, reply.data()); + parser.setDocumentURI(url); + parser.setTargetNamespace(importNamespace); + parser.setIncludedSchemas(m_includedSchemas); + parser.setImportedSchemas(m_importedSchemas); + parser.setRedefinedSchemas(m_redefinedSchemas); + if (!parser.parse(XsdSchemaParser::ImportParser)) + return; + } + } + } else { + // check whether it is a known namespace we have a builtin schema for + if (!importNamespace.isEmpty()) { + if (!m_importedSchemas.contains(importNamespace)) { + m_importedSchemas.insert(importNamespace); + + QFile file(QString::fromLatin1(":") + importNamespace); + if (file.open(QIODevice::ReadOnly)) { + XsdSchemaParser parser(m_context, m_parserContext, &file); + parser.setDocumentURI(importNamespace); + parser.setTargetNamespace(importNamespace); + parser.setIncludedSchemas(m_includedSchemas); + parser.setImportedSchemas(m_importedSchemas); + parser.setRedefinedSchemas(m_redefinedSchemas); + if (!parser.parse(XsdSchemaParser::ImportParser)) + return; + } + } + } else { + // we don't import anything... that is valid according to the schema + } + } + + validateIdAttribute("import"); + + TagValidationHandler tagValidator(XsdTagScope::Import, this, m_namePool); + + while (!atEnd()) { + readNext(); + + if (isEndElement()) + break; + + if (isStartElement()) { + const XsdSchemaToken::NodeName token = XsdSchemaToken::toToken(name()); + const XsdSchemaToken::NodeName namespaceToken = XsdSchemaToken::toToken(namespaceUri()); + + tagValidator.validate(token); + + if (isSchemaTag(XsdSchemaToken::Annotation, token, namespaceToken)) { + const XsdAnnotation::Ptr annotation = parseAnnotation(); + m_schema->addAnnotation(annotation); + } else { + parseUnknown(); + } + } + } + + tagValidator.finalize(); +} + +void XsdSchemaParser::parseRedefine() +{ + Q_ASSERT(isStartElement() && XsdSchemaToken::toToken(name()) == XsdSchemaToken::Redefine && + XsdSchemaToken::toToken(namespaceUri()) == XsdSchemaToken::XML_NS_SCHEMA_URI); + + validateElement(XsdTagScope::Redefine); + + // parse attributes + validateIdAttribute("redefine"); + + const QString schemaLocation = readAttribute(QString::fromLatin1("schemaLocation")); + + TagValidationHandler tagValidator(XsdTagScope::Redefine, this, m_namePool); + + XsdSimpleType::List redefinedSimpleTypes; + XsdComplexType::List redefinedComplexTypes; + XsdModelGroup::List redefinedGroups; + XsdAttributeGroup::List redefinedAttributeGroups; + + while (!atEnd()) { + readNext(); + + if (isEndElement()) + break; + + if (isStartElement()) { + const XsdSchemaToken::NodeName token = XsdSchemaToken::toToken(name()); + const XsdSchemaToken::NodeName namespaceToken = XsdSchemaToken::toToken(namespaceUri()); + + tagValidator.validate(token); + + if (isSchemaTag(XsdSchemaToken::Annotation, token, namespaceToken)) { + const XsdAnnotation::Ptr annotation = parseAnnotation(); + m_schema->addAnnotation(annotation); + } else if (isSchemaTag(XsdSchemaToken::SimpleType, token, namespaceToken)) { + const XsdSimpleType::Ptr type = parseGlobalSimpleType(); + redefinedSimpleTypes.append(type); + + const QXmlName baseTypeName = m_parserContext->resolver()->baseTypeNameOfType(type); + if (baseTypeName != type->name(m_namePool)) { + error(QString::fromLatin1("redefined simple type %1 must have itself as base type").arg(formatType(m_namePool, type))); + return; + } + } else if (isSchemaTag(XsdSchemaToken::ComplexType, token, namespaceToken)) { + const XsdComplexType::Ptr type = parseGlobalComplexType(); + redefinedComplexTypes.append(type); + + // @see http://www.w3.org/TR/xmlschema11-1/#src-redefine + + // 5 + const QXmlName baseTypeName = m_parserContext->resolver()->baseTypeNameOfType(type); + if (baseTypeName != type->name(m_namePool)) { + error(QString::fromLatin1("redefined complex type %1 must have itself as base type").arg(formatType(m_namePool, type))); + return; + } + } else if (isSchemaTag(XsdSchemaToken::Group, token, namespaceToken)) { + const XsdModelGroup::Ptr group = parseNamedGroup(); + redefinedGroups.append(group); + } else if (isSchemaTag(XsdSchemaToken::AttributeGroup, token, namespaceToken)) { + const XsdAttributeGroup::Ptr group = parseNamedAttributeGroup(); + redefinedAttributeGroups.append(group); + + } else { + parseUnknown(); + } + } + } + + bool locationMustResolve = false; + if (!redefinedSimpleTypes.isEmpty() || !redefinedComplexTypes.isEmpty() || + !redefinedGroups.isEmpty() || !redefinedAttributeGroups.isEmpty()) { + locationMustResolve = true; + } + + QUrl url(schemaLocation); + if (url.isRelative()) { + Q_ASSERT(m_documentURI.isValid()); + + url = m_documentURI.resolved(url); + } + + // we parse the schema given in the redefine tag into its own context + const XsdSchemaParserContext::Ptr redefinedContext(new XsdSchemaParserContext(m_namePool, m_context)); + + if (m_redefinedSchemas.contains(url)) { + // we have redefined that file already, according to the schema spec we are + // allowed to silently skip it. + } else { + m_redefinedSchemas.insert(url); + QNetworkReply *reply = AccelTreeResourceLoader::load(url, m_context->networkAccessManager(), + m_context, + (locationMustResolve ? AccelTreeResourceLoader::FailOnError : AccelTreeResourceLoader::ContinueOnError)); + if (reply) { + // parse the included schema by a different parser but with the same context + XsdSchemaParser parser(m_context, redefinedContext, reply); + parser.setDocumentURI(url); + parser.setTargetNamespaceExtended(m_targetNamespace); + parser.setIncludedSchemas(m_includedSchemas); + parser.setImportedSchemas(m_importedSchemas); + parser.setRedefinedSchemas(m_redefinedSchemas); + if (!parser.parse(XsdSchemaParser::RedefineParser)) + return; + + delete reply; + } + } + + XsdSimpleType::List contextSimpleTypes = redefinedContext->schema()->simpleTypes(); + XsdComplexType::List contextComplexTypes = redefinedContext->schema()->complexTypes(); + XsdModelGroup::List contextGroups = redefinedContext->schema()->elementGroups(); + XsdAttributeGroup::List contextAttributeGroups = redefinedContext->schema()->attributeGroups(); + + // now we do the actual redefinition: + + // iterate over all redefined simple types + for (int i = 0; i < redefinedSimpleTypes.count(); ++i) { + XsdSimpleType::Ptr redefinedType = redefinedSimpleTypes.at(i); + + //TODONEXT: validation + + // search the definition they override in the context types + bool found = false; + for (int j = 0; j < contextSimpleTypes.count(); ++j) { + XsdSimpleType::Ptr contextType = contextSimpleTypes.at(j); + + if (redefinedType->name(m_namePool) == contextType->name(m_namePool)) { // we found the right type + found = true; + + // 1) set name of context type to empty name + contextType->setName(m_parserContext->createAnonymousName(QString())); + + // 2) set the context type as base type for the redefined type + redefinedType->setWxsSuperType(contextType); + + // 3) remove the base type resolving job from the resolver as + // we have set the base type here explicitely + m_parserContext->resolver()->removeSimpleRestrictionBase(redefinedType); + + // 4) add the redefined type to the schema + addType(redefinedType); + + // 5) add the context type as anonymous type, so the resolver + // can resolve it further. + addAnonymousType(contextType); + + // 6) remove the context type from the list + contextSimpleTypes.removeAt(j); + + break; + } + } + + if (!found) { + error(QString::fromLatin1("no matching type found to redefine simple type %1").arg(formatType(m_namePool, redefinedType))); + return; + } + } + + // add all remaining context simple types to the schema + for (int i = 0; i < contextSimpleTypes.count(); ++i) { + addType(contextSimpleTypes.at(i)); + } + + // iterate over all redefined complex types + for (int i = 0; i < redefinedComplexTypes.count(); ++i) { + XsdComplexType::Ptr redefinedType = redefinedComplexTypes.at(i); + + //TODONEXT: validation + + // search the definition they override in the context types + bool found = false; + for (int j = 0; j < contextComplexTypes.count(); ++j) { + XsdComplexType::Ptr contextType = contextComplexTypes.at(j); + + if (redefinedType->name(m_namePool) == contextType->name(m_namePool)) { // we found the right type + found = true; + + // 1) set name of context type to empty name + contextType->setName(m_parserContext->createAnonymousName(QString())); + + // 2) set the context type as base type for the redefined type + redefinedType->setWxsSuperType(contextType); + + // 3) remove the base type resolving job from the resolver as + // we have set the base type here explicitely + m_parserContext->resolver()->removeComplexBaseType(redefinedType); + + // 4) add the redefined type to the schema + addType(redefinedType); + + // 5) add the context type as anonymous type, so the resolver + // can resolve its attribute uses etc. + addAnonymousType(contextType); + + // 6) remove the context type from the list + contextComplexTypes.removeAt(j); + + break; + } + } + + if (!found) { + error(QString::fromLatin1("no matching type found to redefine complex type %1").arg(formatType(m_namePool, redefinedType))); + return; + } + } + + // iterate over all redefined element groups + for (int i = 0; i < redefinedGroups.count(); ++i) { + const XsdModelGroup::Ptr group(redefinedGroups.at(i)); + + // @see http://www.w3.org/TR/xmlschema11-1/#src-redefine + + // 6 + const XsdParticle::List particles = collectGroupRef(group); + XsdParticle::Ptr referencedParticle; + int sameNameCounter = 0; + for (int i = 0; i < particles.count(); ++i) { + const XsdReference::Ptr ref(particles.at(i)->term()); + if (ref->referenceName() == group->name(m_namePool)) { + referencedParticle = particles.at(i); + + if (referencedParticle->minimumOccurs() != 1 || referencedParticle->maximumOccurs() != 1 || referencedParticle->maximumOccursUnbounded()) { // 6.1.2 + error(QString::fromLatin1("redefined group %1 can not contain reference to itself with minOccurs or maxOccurs != 1").arg(formatKeyword(group->displayName(m_namePool)))); + return; + } + sameNameCounter++; + } + } + + // 6.1.1 + if (sameNameCounter > 1) { + error(QString::fromLatin1("redefined group %1 can not contain multiple references to itself").arg(formatKeyword(group->displayName(m_namePool)))); + return; + } + + // search the group definition in the included schema (S2) + XsdModelGroup::Ptr contextGroup; + for (int j = 0; j < contextGroups.count(); ++j) { + if (group->name(m_namePool) == contextGroups.at(j)->name(m_namePool)) { + contextGroup = contextGroups.at(j); + break; + } + } + + if (!contextGroup) { // 6.2.1 + error(QString::fromLatin1("redefined group %1 has no occurrence in included schema").arg(formatKeyword(group->displayName(m_namePool)))); + return; + } + + if (sameNameCounter == 1) { + // there was a self reference in the redefined group, so use the + // group from the included schema + + // set a anonymous name to the group of the included schema + contextGroup->setName(m_parserContext->createAnonymousName(m_namePool->stringForNamespace(contextGroup->name(m_namePool).namespaceURI()))); + + // replace the self-reference with the group from the included schema + referencedParticle->setTerm(contextGroup); + + addElementGroup(group); + + addElementGroup(contextGroup); + contextGroups.removeAll(contextGroup); + } else { + // there was no self reference in the redefined group + + // just add the redefined group... + addElementGroup(group); + + // we have to add them, otherwise it is not resolved and we can't validate it later + contextGroup->setName(m_parserContext->createAnonymousName(m_namePool->stringForNamespace(contextGroup->name(m_namePool).namespaceURI()))); + addElementGroup(contextGroup); + + m_schemaResolver->addRedefinedGroups(group, contextGroup); + + // ...and forget about the group from the included schema + contextGroups.removeAll(contextGroup); + } + } + + // iterate over all redefined attribute groups + for (int i = 0; i < redefinedAttributeGroups.count(); ++i) { + const XsdAttributeGroup::Ptr group(redefinedAttributeGroups.at(i)); + + // @see http://www.w3.org/TR/xmlschema11-1/#src-redefine + + // 7 + + // 7.1 + int sameNameCounter = 0; + for (int j = 0; j < group->attributeUses().count(); ++j) { + const XsdAttributeUse::Ptr attributeUse(group->attributeUses().at(j)); + if (attributeUse->isReference()) { + const XsdAttributeReference::Ptr reference(attributeUse); + if (reference->type() == XsdAttributeReference::AttributeGroup) { + if (group->name(m_namePool) == reference->referenceName()) + sameNameCounter++; + } + } + } + if (sameNameCounter > 1) { + error(QString::fromLatin1("redefined attribute group %1 can not contain multiple references to itself").arg(formatKeyword(group->displayName(m_namePool)))); + return; + } + + // search the attribute group definition in the included schema (S2) + XsdAttributeGroup::Ptr baseGroup; + for (int j = 0; j < contextAttributeGroups.count(); ++j) { + const XsdAttributeGroup::Ptr contextGroup(contextAttributeGroups.at(j)); + if (group->name(m_namePool) == contextGroup->name(m_namePool)) { + baseGroup = contextGroup; + break; + } + } + + if (!baseGroup) { // 7.2.1 + error(QString::fromLatin1("redefined attribute group %1 has no occurrence in included schema").arg(formatKeyword(group->displayName(m_namePool)))); + return; + } + + if (sameNameCounter == 1) { + + // first set an anonymous name to the attribute group from the included + // schema + baseGroup->setName(m_parserContext->createAnonymousName(m_namePool->stringForNamespace(baseGroup->name(m_namePool).namespaceURI()))); + + // iterate over the attribute uses of the redefined attribute group + // and replace the self-reference with the attribute group from the + // included schema + for (int j = 0; j < group->attributeUses().count(); ++j) { + const XsdAttributeUse::Ptr attributeUse(group->attributeUses().at(j)); + if (attributeUse->isReference()) { + const XsdAttributeReference::Ptr reference(attributeUse); + if (reference->type() == XsdAttributeReference::AttributeGroup) { + if (group->name(m_namePool) == reference->referenceName()) { + reference->setReferenceName(baseGroup->name(m_namePool)); + break; + } + } + } + } + + // add both groups to the target schema + addAttributeGroup(baseGroup); + addAttributeGroup(group); + + contextAttributeGroups.removeAll(baseGroup); + } + + if (sameNameCounter == 0) { // 7.2 + + // we have to add them, otherwise it is not resolved and we can't validate it later + baseGroup->setName(m_parserContext->createAnonymousName(m_namePool->stringForNamespace(baseGroup->name(m_namePool).namespaceURI()))); + addAttributeGroup(baseGroup); + + m_schemaResolver->addRedefinedAttributeGroups(group, baseGroup); + + // just add the redefined attribute group to the target schema... + addAttributeGroup(group); + + // ... and forget about the one from the included schema + contextAttributeGroups.removeAll(baseGroup); + } + } + + // add all remaining context complex types to the schema + for (int i = 0; i < contextComplexTypes.count(); ++i) { + addType(contextComplexTypes.at(i)); + } + + // add all remaining context element groups to the schema + for (int i = 0; i < contextGroups.count(); ++i) { + addElementGroup(contextGroups.at(i)); + } + + // add all remaining context attribute groups to the schema + for (int i = 0; i < contextAttributeGroups.count(); ++i) { + addAttributeGroup(contextAttributeGroups.at(i)); + } + + // copy all elements, attributes and notations + const XsdElement::List contextElements = redefinedContext->schema()->elements(); + for (int i = 0; i < contextElements.count(); ++i) { + addElement(contextElements.at(i)); + } + + const XsdAttribute::List contextAttributes = redefinedContext->schema()->attributes(); + for (int i = 0; i < contextAttributes.count(); ++i) { + addAttribute(contextAttributes.at(i)); + } + + const XsdNotation::List contextNotations = redefinedContext->schema()->notations(); + for (int i = 0; i < contextNotations.count(); ++i) { + addNotation(contextNotations.at(i)); + } + + // push all data to resolve from the context resolver to our resolver + redefinedContext->resolver()->copyDataTo(m_parserContext->resolver()); + + tagValidator.finalize(); +} + +XsdAnnotation::Ptr XsdSchemaParser::parseAnnotation() +{ + const ElementNamespaceHandler namespaceHandler(XsdSchemaToken::Annotation, this); + + validateElement(XsdTagScope::Annotation); + + // parse attributes + validateIdAttribute("annotation"); + + TagValidationHandler tagValidator(XsdTagScope::Annotation, this, m_namePool); + + const XsdAnnotation::Ptr annotation(new XsdAnnotation()); + + while (!atEnd()) { + readNext(); + + if (isEndElement()) + break; + + if (isStartElement()) { + const XsdSchemaToken::NodeName token = XsdSchemaToken::toToken(name()); + const XsdSchemaToken::NodeName namespaceToken = XsdSchemaToken::toToken(namespaceUri()); + + tagValidator.validate(token); + + if (isSchemaTag(XsdSchemaToken::Appinfo, token, namespaceToken)) { + const XsdApplicationInformation::Ptr info = parseAppInfo(); + annotation->addApplicationInformation(info); + } else if (isSchemaTag(XsdSchemaToken::Documentation, token, namespaceToken)) { + const XsdDocumentation::Ptr documentation = parseDocumentation(); + annotation->addDocumentation(documentation); + } else { + parseUnknown(); + } + } + } + + tagValidator.finalize(); + + return annotation; +} + +XsdApplicationInformation::Ptr XsdSchemaParser::parseAppInfo() +{ + const ElementNamespaceHandler namespaceHandler(XsdSchemaToken::Appinfo, this); + + validateElement(XsdTagScope::AppInfo); + + const XsdApplicationInformation::Ptr info(new XsdApplicationInformation()); + + // parse attributes + if (hasAttribute(QString::fromLatin1("source"))) { + const QString value = readAttribute(QString::fromLatin1("source")); + + if (!isValidUri(value)) { + attributeContentError("source", "appinfo", value, BuiltinTypes::xsAnyURI); + return info; + } + + if (!value.isEmpty()) { + const AnyURI::Ptr source = AnyURI::fromLexical(value); + info->setSource(source); + } + } + + while (!atEnd()) { //EVAL: can be anything... what to do? + readNext(); + + if (isEndElement()) + break; + + if (isStartElement()) + parseUnknownDocumentation(); + } + + return info; +} + +XsdDocumentation::Ptr XsdSchemaParser::parseDocumentation() +{ + const ElementNamespaceHandler namespaceHandler(XsdSchemaToken::Documentation, this); + + validateElement(XsdTagScope::Documentation); + + const XsdDocumentation::Ptr documentation(new XsdDocumentation()); + + // parse attributes + if (hasAttribute(QString::fromLatin1("source"))) { + const QString value = readAttribute(QString::fromLatin1("source")); + + if (!isValidUri(value)) { + attributeContentError("source", "documentation", value, BuiltinTypes::xsAnyURI); + return documentation; + } + + if (!value.isEmpty()) { + const AnyURI::Ptr source = AnyURI::fromLexical(value); + documentation->setSource(source); + } + } + + if (hasAttribute(QString::fromLatin1("http://www.w3.org/XML/1998/namespace"), QString::fromLatin1("lang"))) { + const QString value = readAttribute(QString::fromLatin1("lang"), QString::fromLatin1("http://www.w3.org/XML/1998/namespace")); + + const QRegExp exp(QString::fromLatin1("[a-zA-Z]{1,8}(-[a-zA-Z0-9]{1,8})*")); + if (!exp.exactMatch(value)) { + attributeContentError("xml:lang", "documentation", value); + return documentation; + } + } + + while (!atEnd()) { //EVAL: can by any... what to do? + readNext(); + + if (isEndElement()) + break; + + if (isStartElement()) + parseUnknownDocumentation(); + } + + return documentation; +} + +void XsdSchemaParser::parseDefaultOpenContent() +{ + const ElementNamespaceHandler namespaceHandler(XsdSchemaToken::DefaultOpenContent, this); + + validateElement(XsdTagScope::DefaultOpenContent); + + m_defaultOpenContent = XsdComplexType::OpenContent::Ptr(new XsdComplexType::OpenContent()); + + if (hasAttribute(QString::fromLatin1("appliesToEmpty"))) { + const QString value = readAttribute(QString::fromLatin1("appliesToEmpty")); + const Boolean::Ptr appliesToEmpty = Boolean::fromLexical(value); + if (appliesToEmpty->hasError()) { + attributeContentError("appliesToEmpty", "defaultOpenContent", value, BuiltinTypes::xsBoolean); + return; + } + + m_defaultOpenContentAppliesToEmpty = appliesToEmpty->as()->value(); + } else { + m_defaultOpenContentAppliesToEmpty = false; + } + + if (hasAttribute(QString::fromLatin1("mode"))) { + const QString mode = readAttribute(QString::fromLatin1("mode")); + + if (mode == QString::fromLatin1("interleave")) { + m_defaultOpenContent->setMode(XsdComplexType::OpenContent::Interleave); + } else if (mode == QString::fromLatin1("suffix")) { + m_defaultOpenContent->setMode(XsdComplexType::OpenContent::Suffix); + } else { + attributeContentError("mode", "defaultOpenContent", mode); + return; + } + } else { + m_defaultOpenContent->setMode(XsdComplexType::OpenContent::Interleave); + } + + validateIdAttribute("defaultOpenContent"); + + TagValidationHandler tagValidator(XsdTagScope::DefaultOpenContent, this, m_namePool); + + while (!atEnd()) { + readNext(); + + if (isEndElement()) + break; + + if (isStartElement()) { + const XsdSchemaToken::NodeName token = XsdSchemaToken::toToken(name()); + const XsdSchemaToken::NodeName namespaceToken = XsdSchemaToken::toToken(namespaceUri()); + + tagValidator.validate(token); + + if (isSchemaTag(XsdSchemaToken::Annotation, token, namespaceToken)) { + const XsdAnnotation::Ptr annotation = parseAnnotation(); + m_defaultOpenContent->addAnnotation(annotation); + } else if (isSchemaTag(XsdSchemaToken::Any, token, namespaceToken)) { + const XsdParticle::Ptr particle; + const XsdWildcard::Ptr wildcard = parseAny(particle); + m_defaultOpenContent->setWildcard(wildcard); + } else { + parseUnknown(); + } + } + } + + tagValidator.finalize(); +} + +XsdSimpleType::Ptr XsdSchemaParser::parseGlobalSimpleType() +{ + const ElementNamespaceHandler namespaceHandler(XsdSchemaToken::SimpleType, this); + + validateElement(XsdTagScope::GlobalSimpleType); + + const XsdSimpleType::Ptr simpleType(new XsdSimpleType()); + simpleType->setCategory(XsdSimpleType::SimpleTypeAtomic); // just to make sure it's not invalid + + // parse attributes + const SchemaType::DerivationConstraints allowedConstraints(SchemaType::ExtensionConstraint | SchemaType::RestrictionConstraint | SchemaType::ListConstraint | SchemaType::UnionConstraint); + simpleType->setDerivationConstraints(readDerivationConstraintAttribute(allowedConstraints, "simpleType")); + + const QXmlName objectName = m_namePool->allocateQName(m_targetNamespace, readNameAttribute("simpleType")); + simpleType->setName(objectName); + + validateIdAttribute("simpleType"); + + TagValidationHandler tagValidator(XsdTagScope::GlobalSimpleType, this, m_namePool); + + while (!atEnd()) { + readNext(); + + if (isEndElement()) + break; + + if (isStartElement()) { + const XsdSchemaToken::NodeName token = XsdSchemaToken::toToken(name()); + const XsdSchemaToken::NodeName namespaceToken = XsdSchemaToken::toToken(namespaceUri()); + + tagValidator.validate(token); + + if (isSchemaTag(XsdSchemaToken::Annotation, token, namespaceToken)) { + const XsdAnnotation::Ptr annotation = parseAnnotation(); + simpleType->addAnnotation(annotation); + } else if (isSchemaTag(XsdSchemaToken::Restriction, token, namespaceToken)) { + parseSimpleRestriction(simpleType); + } else if (isSchemaTag(XsdSchemaToken::List, token, namespaceToken)) { + parseList(simpleType); + } else if (isSchemaTag(XsdSchemaToken::Union, token, namespaceToken)) { + parseUnion(simpleType); + } else { + parseUnknown(); + } + } + } + + tagValidator.finalize(); + + return simpleType; +} + +XsdSimpleType::Ptr XsdSchemaParser::parseLocalSimpleType() +{ + const ElementNamespaceHandler namespaceHandler(XsdSchemaToken::SimpleType, this); + + validateElement(XsdTagScope::LocalSimpleType); + + const XsdSimpleType::Ptr simpleType(new XsdSimpleType()); + simpleType->setCategory(XsdSimpleType::SimpleTypeAtomic); // just to make sure it's not invalid + simpleType->setName(m_parserContext->createAnonymousName(m_targetNamespace)); + + validateIdAttribute("simpleType"); + + TagValidationHandler tagValidator(XsdTagScope::LocalSimpleType, this, m_namePool); + + while (!atEnd()) { + readNext(); + + if (isEndElement()) + break; + + if (isStartElement()) { + const XsdSchemaToken::NodeName token = XsdSchemaToken::toToken(name()); + const XsdSchemaToken::NodeName namespaceToken = XsdSchemaToken::toToken(namespaceUri()); + + tagValidator.validate(token); + + if (isSchemaTag(XsdSchemaToken::Annotation, token, namespaceToken)) { + const XsdAnnotation::Ptr annotation = parseAnnotation(); + simpleType->addAnnotation(annotation); + } else if (isSchemaTag(XsdSchemaToken::Restriction, token, namespaceToken)) { + parseSimpleRestriction(simpleType); + } else if (isSchemaTag(XsdSchemaToken::List, token, namespaceToken)) { + parseList(simpleType); + } else if (isSchemaTag(XsdSchemaToken::Union, token, namespaceToken)) { + parseUnion(simpleType); + } else { + parseUnknown(); + } + } + } + + tagValidator.finalize(); + + return simpleType; +} + +void XsdSchemaParser::parseSimpleRestriction(const XsdSimpleType::Ptr &ptr) +{ + const ElementNamespaceHandler namespaceHandler(XsdSchemaToken::Restriction, this); + + validateElement(XsdTagScope::SimpleRestriction); + + ptr->setDerivationMethod(XsdSimpleType::DerivationRestriction); + + // The base attribute and simpleType member are mutually exclusive, + // so we keep track of that + bool hasBaseAttribute = false; + bool hasBaseTypeSpecified = false; + + QXmlName baseName; + if (hasAttribute(QString::fromLatin1("base"))) { + const QString base = readQNameAttribute(QString::fromLatin1("base"), "restriction"); + convertName(base, NamespaceSupport::ElementName, baseName); // translate qualified name into QXmlName + m_schemaResolver->addSimpleRestrictionBase(ptr, baseName, currentSourceLocation()); // add to resolver + + hasBaseAttribute = true; + hasBaseTypeSpecified = true; + } + validateIdAttribute("restriction"); + + XsdFacet::Hash facets; + QList patternFacets; + QList enumerationFacets; + QList assertionFacets; + + TagValidationHandler tagValidator(XsdTagScope::SimpleRestriction, this, m_namePool); + + while (!atEnd()) { + readNext(); + + if (isEndElement()) + break; + + if (isStartElement()) { + const XsdSchemaToken::NodeName token = XsdSchemaToken::toToken(name()); + const XsdSchemaToken::NodeName namespaceToken = XsdSchemaToken::toToken(namespaceUri()); + + tagValidator.validate(token); + + if (isSchemaTag(XsdSchemaToken::Annotation, token, namespaceToken)) { + const XsdAnnotation::Ptr annotation = parseAnnotation(); + ptr->addAnnotation(annotation); + } else if (isSchemaTag(XsdSchemaToken::SimpleType, token, namespaceToken)) { + if (hasBaseAttribute) { + error(QtXmlPatterns::tr("%1 element is not allowed inside %2 element if %3 attribute is present") + .arg(formatElement("simpleType")) + .arg(formatElement("restriction")) + .arg(formatAttribute("base"))); + return; + } + + const XsdSimpleType::Ptr type = parseLocalSimpleType(); + type->setContext(ptr); + ptr->setWxsSuperType(type); + ptr->setCategory(type->category()); + hasBaseTypeSpecified = true; + + // add it to list of anonymous types as well + addAnonymousType(type); + } else if (isSchemaTag(XsdSchemaToken::MinExclusive, token, namespaceToken)) { + const XsdFacet::Ptr facet = parseMinExclusiveFacet(); + addFacet(facet, facets, ptr); + } else if (isSchemaTag(XsdSchemaToken::MinInclusive, token, namespaceToken)) { + const XsdFacet::Ptr facet = parseMinInclusiveFacet(); + addFacet(facet, facets, ptr); + } else if (isSchemaTag(XsdSchemaToken::MaxExclusive, token, namespaceToken)) { + const XsdFacet::Ptr facet = parseMaxExclusiveFacet(); + addFacet(facet, facets, ptr); + } else if (isSchemaTag(XsdSchemaToken::MaxInclusive, token, namespaceToken)) { + const XsdFacet::Ptr facet = parseMaxInclusiveFacet(); + addFacet(facet, facets, ptr); + } else if (isSchemaTag(XsdSchemaToken::TotalDigits, token, namespaceToken)) { + const XsdFacet::Ptr facet = parseTotalDigitsFacet(); + addFacet(facet, facets, ptr); + } else if (isSchemaTag(XsdSchemaToken::FractionDigits, token, namespaceToken)) { + const XsdFacet::Ptr facet = parseFractionDigitsFacet(); + addFacet(facet, facets, ptr); + } else if (isSchemaTag(XsdSchemaToken::Length, token, namespaceToken)) { + const XsdFacet::Ptr facet = parseLengthFacet(); + addFacet(facet, facets, ptr); + } else if (isSchemaTag(XsdSchemaToken::MinLength, token, namespaceToken)) { + const XsdFacet::Ptr facet = parseMinLengthFacet(); + addFacet(facet, facets, ptr); + } else if (isSchemaTag(XsdSchemaToken::MaxLength, token, namespaceToken)) { + const XsdFacet::Ptr facet = parseMaxLengthFacet(); + addFacet(facet, facets, ptr); + } else if (isSchemaTag(XsdSchemaToken::Enumeration, token, namespaceToken)) { + const XsdFacet::Ptr facet = parseEnumerationFacet(); + enumerationFacets.append(facet); + } else if (isSchemaTag(XsdSchemaToken::WhiteSpace, token, namespaceToken)) { + const XsdFacet::Ptr facet = parseWhiteSpaceFacet(); + addFacet(facet, facets, ptr); + } else if (isSchemaTag(XsdSchemaToken::Pattern, token, namespaceToken)) { + const XsdFacet::Ptr facet = parsePatternFacet(); + patternFacets.append(facet); + } else if (isSchemaTag(XsdSchemaToken::Assertion, token, namespaceToken)) { + const XsdFacet::Ptr facet = parseAssertionFacet(); + assertionFacets.append(facet); + } else { + parseUnknown(); + } + } + } + + if (!hasBaseTypeSpecified) { + error(QtXmlPatterns::tr("%1 element has neither %2 attribute nor %3 child element") + .arg(formatElement("restriction")) + .arg(formatAttribute("base")) + .arg(formatElement("simpleType"))); + return; + } + + // merge all pattern facets into one multi value facet + if (!patternFacets.isEmpty()) { + const XsdFacet::Ptr patternFacet(new XsdFacet()); + patternFacet->setType(XsdFacet::Pattern); + + AtomicValue::List multiValue; + for (int i = 0; i < patternFacets.count(); ++i) + multiValue << patternFacets.at(i)->multiValue(); + + patternFacet->setMultiValue(multiValue); + addFacet(patternFacet, facets, ptr); + } + + // merge all enumeration facets into one multi value facet + if (!enumerationFacets.isEmpty()) { + const XsdFacet::Ptr enumerationFacet(new XsdFacet()); + enumerationFacet->setType(XsdFacet::Enumeration); + + AtomicValue::List multiValue; + for (int i = 0; i < enumerationFacets.count(); ++i) + multiValue << enumerationFacets.at(i)->multiValue(); + + enumerationFacet->setMultiValue(multiValue); + addFacet(enumerationFacet, facets, ptr); + } + + // merge all assertion facets into one facet + if (!assertionFacets.isEmpty()) { + const XsdFacet::Ptr assertionFacet(new XsdFacet()); + assertionFacet->setType(XsdFacet::Assertion); + + XsdAssertion::List assertions; + for (int i = 0; i < assertionFacets.count(); ++i) + assertions << assertionFacets.at(i)->assertions(); + + assertionFacet->setAssertions(assertions); + addFacet(assertionFacet, facets, ptr); + } + + ptr->setFacets(facets); + + tagValidator.finalize(); +} + +void XsdSchemaParser::parseList(const XsdSimpleType::Ptr &ptr) +{ + const ElementNamespaceHandler namespaceHandler(XsdSchemaToken::List, this); + + validateElement(XsdTagScope::List); + + ptr->setCategory(XsdSimpleType::SimpleTypeList); + ptr->setDerivationMethod(XsdSimpleType::DerivationList); + ptr->setWxsSuperType(BuiltinTypes::xsAnySimpleType); + + // The itemType attribute and simpleType member are mutually exclusive, + // so we keep track of that + bool hasItemTypeAttribute = false; + bool hasItemTypeSpecified = false; + + if (hasAttribute(QString::fromLatin1("itemType"))) { + const QString itemType = readQNameAttribute(QString::fromLatin1("itemType"), "list"); + QXmlName typeName; + convertName(itemType, NamespaceSupport::ElementName, typeName); // translate qualified name into QXmlName + m_schemaResolver->addSimpleListType(ptr, typeName, currentSourceLocation()); // add to resolver + + hasItemTypeAttribute = true; + hasItemTypeSpecified = true; + } + + validateIdAttribute("list"); + + TagValidationHandler tagValidator(XsdTagScope::List, this, m_namePool); + + while (!atEnd()) { + readNext(); + + if (isEndElement()) + break; + + if (isStartElement()) { + const XsdSchemaToken::NodeName token = XsdSchemaToken::toToken(name()); + const XsdSchemaToken::NodeName namespaceToken = XsdSchemaToken::toToken(namespaceUri()); + + tagValidator.validate(token); + + if (isSchemaTag(XsdSchemaToken::Annotation, token, namespaceToken)) { + const XsdAnnotation::Ptr annotation = parseAnnotation(); + ptr->addAnnotation(annotation); + } else if (isSchemaTag(XsdSchemaToken::SimpleType, token, namespaceToken)) { + if (hasItemTypeAttribute) { + error(QtXmlPatterns::tr("%1 element is not allowed inside %2 element if %3 attribute is present") + .arg(formatElement("simpleType")) + .arg(formatElement("list")) + .arg(formatAttribute("itemType"))); + return; + } + + const XsdSimpleType::Ptr type = parseLocalSimpleType(); + type->setContext(ptr); + ptr->setItemType(type); + + hasItemTypeSpecified = true; + + // add it to list of anonymous types as well + addAnonymousType(type); + } else { + parseUnknown(); + } + } + } + + if (!hasItemTypeSpecified) { + error(QtXmlPatterns::tr("%1 element has neither %2 attribute nor %3 child element") + .arg(formatElement("list")) + .arg(formatAttribute("itemType")) + .arg(formatElement("simpleType"))); + return; + } + + tagValidator.finalize(); + + // add the default white space facet that every simple type with list derivation has + const XsdFacet::Ptr defaultFacet(new XsdFacet()); + defaultFacet->setType(XsdFacet::WhiteSpace); + defaultFacet->setFixed(true); + defaultFacet->setValue(DerivedString::fromLexical(m_namePool, XsdSchemaToken::toString(XsdSchemaToken::Collapse))); + XsdFacet::Hash facets; + facets.insert(defaultFacet->type(), defaultFacet); + ptr->setFacets(facets); +} + +void XsdSchemaParser::parseUnion(const XsdSimpleType::Ptr &ptr) +{ + const ElementNamespaceHandler namespaceHandler(XsdSchemaToken::Union, this); + + validateElement(XsdTagScope::Union); + + ptr->setCategory(XsdSimpleType::SimpleTypeUnion); + ptr->setDerivationMethod(XsdSimpleType::DerivationUnion); + ptr->setWxsSuperType(BuiltinTypes::xsAnySimpleType); + + // The memberTypes attribute is not allowed to be empty, + // so we keep track of that + bool hasMemberTypesAttribute = false; + bool hasMemberTypesSpecified = false; + + if (hasAttribute(QString::fromLatin1("memberTypes"))) { + hasMemberTypesAttribute = true; + + const QStringList memberTypes = readAttribute(QString::fromLatin1("memberTypes")).split(QLatin1Char(' '), QString::SkipEmptyParts); + QList typeNames; + + for (int i = 0; i < memberTypes.count(); ++i) { + QXmlName typeName; + convertName(memberTypes.at(i), NamespaceSupport::ElementName, typeName); // translate qualified name into QXmlName + typeNames.append(typeName); + } + + if (!typeNames.isEmpty()) { + m_schemaResolver->addSimpleUnionTypes(ptr, typeNames, currentSourceLocation()); // add to resolver + hasMemberTypesSpecified = true; + } + } + + validateIdAttribute("union"); + + AnySimpleType::List memberTypes; + + TagValidationHandler tagValidator(XsdTagScope::Union, this, m_namePool); + + while (!atEnd()) { + readNext(); + + if (isEndElement()) + break; + + if (isStartElement()) { + const XsdSchemaToken::NodeName token = XsdSchemaToken::toToken(name()); + const XsdSchemaToken::NodeName namespaceToken = XsdSchemaToken::toToken(namespaceUri()); + + tagValidator.validate(token); + + if (isSchemaTag(XsdSchemaToken::Annotation, token, namespaceToken)) { + const XsdAnnotation::Ptr annotation = parseAnnotation(); + ptr->addAnnotation(annotation); + } else if (isSchemaTag(XsdSchemaToken::SimpleType, token, namespaceToken)) { + const XsdSimpleType::Ptr type = parseLocalSimpleType(); + type->setContext(ptr); + memberTypes.append(type); + + // add it to list of anonymous types as well + addAnonymousType(type); + } else { + parseUnknown(); + } + } + } + + if (!memberTypes.isEmpty()) { + ptr->setMemberTypes(memberTypes); + hasMemberTypesSpecified = true; + } + + if (!hasMemberTypesSpecified) { + error(QtXmlPatterns::tr("%1 element has neither %2 attribute nor %3 child element") + .arg(formatElement("union")) + .arg(formatAttribute("memberTypes")) + .arg(formatElement("simpleType"))); + return; + } + + tagValidator.finalize(); +} + +XsdFacet::Ptr XsdSchemaParser::parseMinExclusiveFacet() +{ + const ElementNamespaceHandler namespaceHandler(XsdSchemaToken::MinExclusive, this); + + validateElement(XsdTagScope::MinExclusiveFacet); + + const XsdFacet::Ptr facet = XsdFacet::Ptr(new XsdFacet()); + facet->setType(XsdFacet::MinimumExclusive); + + // parse attributes + if (hasAttribute(QString::fromLatin1("fixed"))) { + const QString value = readAttribute(QString::fromLatin1("fixed")); + const Boolean::Ptr fixed = Boolean::fromLexical(value); + if (fixed->hasError()) { + attributeContentError("fixed", "minExclusive", value, BuiltinTypes::xsBoolean); + return facet; + } + + facet->setFixed(fixed->as()->value()); + } else { + facet->setFixed(false); // the default value + } + + // as minExclusive can have a value of type anySimpleType, we just read + // the string here and store it for later intepretation + const QString value = readAttribute(QString::fromLatin1("value")); + DerivedString::Ptr string = DerivedString::fromLexical(m_namePool, value); + if (string->hasError()) { + attributeContentError("value", "minExclusive", value, BuiltinTypes::xsAnySimpleType); + return facet; + } else { + facet->setValue(string); + } + + validateIdAttribute("minExclusive"); + + TagValidationHandler tagValidator(XsdTagScope::MinExclusiveFacet, this, m_namePool); + + while (!atEnd()) { + readNext(); + + if (isEndElement()) + break; + + if (isStartElement()) { + const XsdSchemaToken::NodeName token = XsdSchemaToken::toToken(name()); + const XsdSchemaToken::NodeName namespaceToken = XsdSchemaToken::toToken(namespaceUri()); + + tagValidator.validate(token); + + if (isSchemaTag(XsdSchemaToken::Annotation, token, namespaceToken)) { + const XsdAnnotation::Ptr annotation = parseAnnotation(); + facet->addAnnotation(annotation); + } else { + parseUnknown(); + } + } + } + + tagValidator.finalize(); + + return facet; +} + +XsdFacet::Ptr XsdSchemaParser::parseMinInclusiveFacet() +{ + const ElementNamespaceHandler namespaceHandler(XsdSchemaToken::MinInclusive, this); + + validateElement(XsdTagScope::MinInclusiveFacet); + + const XsdFacet::Ptr facet = XsdFacet::Ptr(new XsdFacet()); + facet->setType(XsdFacet::MinimumInclusive); + + // parse attributes + if (hasAttribute(QString::fromLatin1("fixed"))) { + const QString value = readAttribute(QString::fromLatin1("fixed")); + const Boolean::Ptr fixed = Boolean::fromLexical(value); + if (fixed->hasError()) { + attributeContentError("fixed", "minInclusive", value, BuiltinTypes::xsBoolean); + return facet; + } + + facet->setFixed(fixed->as()->value()); + } else { + facet->setFixed(false); // the default value + } + + // as minInclusive can have a value of type anySimpleType, we just read + // the string here and store it for later intepretation + const QString value = readAttribute(QString::fromLatin1("value")); + DerivedString::Ptr string = DerivedString::fromLexical(m_namePool, value); + if (string->hasError()) { + attributeContentError("value", "minInclusive", value, BuiltinTypes::xsAnySimpleType); + return facet; + } else { + facet->setValue(string); + } + + validateIdAttribute("minInclusive"); + + TagValidationHandler tagValidator(XsdTagScope::MinInclusiveFacet, this, m_namePool); + + while (!atEnd()) { + readNext(); + + if (isEndElement()) + break; + + if (isStartElement()) { + const XsdSchemaToken::NodeName token = XsdSchemaToken::toToken(name()); + const XsdSchemaToken::NodeName namespaceToken = XsdSchemaToken::toToken(namespaceUri()); + + tagValidator.validate(token); + + if (isSchemaTag(XsdSchemaToken::Annotation, token, namespaceToken)) { + const XsdAnnotation::Ptr annotation = parseAnnotation(); + facet->addAnnotation(annotation); + } else { + parseUnknown(); + } + } + } + + tagValidator.finalize(); + + return facet; +} + +XsdFacet::Ptr XsdSchemaParser::parseMaxExclusiveFacet() +{ + const ElementNamespaceHandler namespaceHandler(XsdSchemaToken::MaxExclusive, this); + + validateElement(XsdTagScope::MaxExclusiveFacet); + + const XsdFacet::Ptr facet = XsdFacet::Ptr(new XsdFacet()); + facet->setType(XsdFacet::MaximumExclusive); + + // parse attributes + if (hasAttribute(QString::fromLatin1("fixed"))) { + const QString value = readAttribute(QString::fromLatin1("fixed")); + const Boolean::Ptr fixed = Boolean::fromLexical(value); + if (fixed->hasError()) { + attributeContentError("fixed", "maxExclusive", value, BuiltinTypes::xsBoolean); + return facet; + } + + facet->setFixed(fixed->as()->value()); + } else { + facet->setFixed(false); // the default value + } + + // as maxExclusive can have a value of type anySimpleType, we just read + // the string here and store it for later intepretation + const QString value = readAttribute(QString::fromLatin1("value")); + DerivedString::Ptr string = DerivedString::fromLexical(m_namePool, value); + if (string->hasError()) { + attributeContentError("value", "maxExclusive", value, BuiltinTypes::xsAnySimpleType); + return facet; + } else { + facet->setValue(string); + } + + validateIdAttribute("maxExclusive"); + + TagValidationHandler tagValidator(XsdTagScope::MaxExclusiveFacet, this, m_namePool); + + while (!atEnd()) { + readNext(); + + if (isEndElement()) + break; + + if (isStartElement()) { + const XsdSchemaToken::NodeName token = XsdSchemaToken::toToken(name()); + const XsdSchemaToken::NodeName namespaceToken = XsdSchemaToken::toToken(namespaceUri()); + + tagValidator.validate(token); + + if (isSchemaTag(XsdSchemaToken::Annotation, token, namespaceToken)) { + const XsdAnnotation::Ptr annotation = parseAnnotation(); + facet->addAnnotation(annotation); + } else { + parseUnknown(); + } + } + } + + tagValidator.finalize(); + + return facet; +} + +XsdFacet::Ptr XsdSchemaParser::parseMaxInclusiveFacet() +{ + const ElementNamespaceHandler namespaceHandler(XsdSchemaToken::MaxInclusive, this); + + validateElement(XsdTagScope::MaxInclusiveFacet); + + const XsdFacet::Ptr facet = XsdFacet::Ptr(new XsdFacet()); + facet->setType(XsdFacet::MaximumInclusive); + + // parse attributes + if (hasAttribute(QString::fromLatin1("fixed"))) { + const QString value = readAttribute(QString::fromLatin1("fixed")); + const Boolean::Ptr fixed = Boolean::fromLexical(value); + if (fixed->hasError()) { + attributeContentError("fixed", "maxInclusive", value, BuiltinTypes::xsBoolean); + return facet; + } + + facet->setFixed(fixed->as()->value()); + } else { + facet->setFixed(false); // the default value + } + + // as maxInclusive can have a value of type anySimpleType, we just read + // the string here and store it for later intepretation + const QString value = readAttribute(QString::fromLatin1("value")); + DerivedString::Ptr string = DerivedString::fromLexical(m_namePool, value); + if (string->hasError()) { + attributeContentError("value", "maxInclusive", value, BuiltinTypes::xsAnySimpleType); + return facet; + } else { + facet->setValue(string); + } + + validateIdAttribute("maxInclusive"); + + TagValidationHandler tagValidator(XsdTagScope::MaxInclusiveFacet, this, m_namePool); + + while (!atEnd()) { + readNext(); + + if (isEndElement()) + break; + + if (isStartElement()) { + const XsdSchemaToken::NodeName token = XsdSchemaToken::toToken(name()); + const XsdSchemaToken::NodeName namespaceToken = XsdSchemaToken::toToken(namespaceUri()); + + tagValidator.validate(token); + + if (isSchemaTag(XsdSchemaToken::Annotation, token, namespaceToken)) { + const XsdAnnotation::Ptr annotation = parseAnnotation(); + facet->addAnnotation(annotation); + } else { + parseUnknown(); + } + } + } + + tagValidator.finalize(); + + return facet; +} + +XsdFacet::Ptr XsdSchemaParser::parseTotalDigitsFacet() +{ + const ElementNamespaceHandler namespaceHandler(XsdSchemaToken::TotalDigits, this); + + validateElement(XsdTagScope::TotalDigitsFacet); + + const XsdFacet::Ptr facet = XsdFacet::Ptr(new XsdFacet()); + facet->setType(XsdFacet::TotalDigits); + + // parse attributes + if (hasAttribute(QString::fromLatin1("fixed"))) { + const QString value = readAttribute(QString::fromLatin1("fixed")); + const Boolean::Ptr fixed = Boolean::fromLexical(value); + if (fixed->hasError()) { + attributeContentError("fixed", "totalDigits", value, BuiltinTypes::xsBoolean); + return facet; + } + + facet->setFixed(fixed->as()->value()); + } else { + facet->setFixed(false); // the default value + } + + const QString value = readAttribute(QString::fromLatin1("value")); + DerivedInteger::Ptr integer = DerivedInteger::fromLexical(m_namePool, value); + if (integer->hasError()) { + attributeContentError("value", "totalDigits", value, BuiltinTypes::xsPositiveInteger); + return facet; + } else { + facet->setValue(integer); + } + + validateIdAttribute("totalDigits"); + + TagValidationHandler tagValidator(XsdTagScope::TotalDigitsFacet, this, m_namePool); + + while (!atEnd()) { + readNext(); + + if (isEndElement()) + break; + + if (isStartElement()) { + const XsdSchemaToken::NodeName token = XsdSchemaToken::toToken(name()); + const XsdSchemaToken::NodeName namespaceToken = XsdSchemaToken::toToken(namespaceUri()); + + tagValidator.validate(token); + + if (isSchemaTag(XsdSchemaToken::Annotation, token, namespaceToken)) { + const XsdAnnotation::Ptr annotation = parseAnnotation(); + facet->addAnnotation(annotation); + } else { + parseUnknown(); + } + } + } + + tagValidator.finalize(); + + return facet; +} + +XsdFacet::Ptr XsdSchemaParser::parseFractionDigitsFacet() +{ + const ElementNamespaceHandler namespaceHandler(XsdSchemaToken::FractionDigits, this); + + validateElement(XsdTagScope::FractionDigitsFacet); + + const XsdFacet::Ptr facet = XsdFacet::Ptr(new XsdFacet()); + facet->setType(XsdFacet::FractionDigits); + + // parse attributes + if (hasAttribute(QString::fromLatin1("fixed"))) { + const QString value = readAttribute(QString::fromLatin1("fixed")); + const Boolean::Ptr fixed = Boolean::fromLexical(value); + if (fixed->hasError()) { + attributeContentError("fixed", "fractionDigits", value, BuiltinTypes::xsBoolean); + return facet; + } + + facet->setFixed(fixed->as()->value()); + } else { + facet->setFixed(false); // the default value + } + + const QString value = readAttribute(QString::fromLatin1("value")); + DerivedInteger::Ptr integer = DerivedInteger::fromLexical(m_namePool, value); + if (integer->hasError()) { + attributeContentError("value", "fractionDigits", value, BuiltinTypes::xsNonNegativeInteger); + return facet; + } else { + facet->setValue(integer); + } + + validateIdAttribute("fractionDigits"); + + TagValidationHandler tagValidator(XsdTagScope::FractionDigitsFacet, this, m_namePool); + + while (!atEnd()) { + readNext(); + + if (isEndElement()) + break; + + if (isStartElement()) { + const XsdSchemaToken::NodeName token = XsdSchemaToken::toToken(name()); + const XsdSchemaToken::NodeName namespaceToken = XsdSchemaToken::toToken(namespaceUri()); + + tagValidator.validate(token); + + if (isSchemaTag(XsdSchemaToken::Annotation, token, namespaceToken)) { + const XsdAnnotation::Ptr annotation = parseAnnotation(); + facet->addAnnotation(annotation); + } else { + parseUnknown(); + } + } + } + + tagValidator.finalize(); + + return facet; +} + +XsdFacet::Ptr XsdSchemaParser::parseLengthFacet() +{ + const ElementNamespaceHandler namespaceHandler(XsdSchemaToken::Length, this); + + validateElement(XsdTagScope::LengthFacet); + + const XsdFacet::Ptr facet = XsdFacet::Ptr(new XsdFacet()); + facet->setType(XsdFacet::Length); + + // parse attributes + if (hasAttribute(QString::fromLatin1("fixed"))) { + const QString value = readAttribute(QString::fromLatin1("fixed")); + const Boolean::Ptr fixed = Boolean::fromLexical(value); + if (fixed->hasError()) { + attributeContentError("fixed", "length", value, BuiltinTypes::xsBoolean); + return facet; + } + + facet->setFixed(fixed->as()->value()); + } else { + facet->setFixed(false); // the default value + } + + const QString value = readAttribute(QString::fromLatin1("value")); + DerivedInteger::Ptr integer = DerivedInteger::fromLexical(m_namePool, value); + if (integer->hasError()) { + attributeContentError("value", "length", value, BuiltinTypes::xsNonNegativeInteger); + return facet; + } else { + facet->setValue(integer); + } + + validateIdAttribute("length"); + + TagValidationHandler tagValidator(XsdTagScope::LengthFacet, this, m_namePool); + + while (!atEnd()) { + readNext(); + + if (isEndElement()) + break; + + if (isStartElement()) { + const XsdSchemaToken::NodeName token = XsdSchemaToken::toToken(name()); + const XsdSchemaToken::NodeName namespaceToken = XsdSchemaToken::toToken(namespaceUri()); + + tagValidator.validate(token); + + if (isSchemaTag(XsdSchemaToken::Annotation, token, namespaceToken)) { + const XsdAnnotation::Ptr annotation = parseAnnotation(); + facet->addAnnotation(annotation); + } else { + parseUnknown(); + } + } + } + + tagValidator.finalize(); + + return facet; +} + +XsdFacet::Ptr XsdSchemaParser::parseMinLengthFacet() +{ + const ElementNamespaceHandler namespaceHandler(XsdSchemaToken::MinLength, this); + + validateElement(XsdTagScope::MinLengthFacet); + + const XsdFacet::Ptr facet = XsdFacet::Ptr(new XsdFacet()); + facet->setType(XsdFacet::MinimumLength); + + // parse attributes + if (hasAttribute(QString::fromLatin1("fixed"))) { + const QString value = readAttribute(QString::fromLatin1("fixed")); + const Boolean::Ptr fixed = Boolean::fromLexical(value); + if (fixed->hasError()) { + attributeContentError("fixed", "minLength", value, BuiltinTypes::xsBoolean); + return facet; + } + + facet->setFixed(fixed->as()->value()); + } else { + facet->setFixed(false); // the default value + } + + const QString value = readAttribute(QString::fromLatin1("value")); + DerivedInteger::Ptr integer = DerivedInteger::fromLexical(m_namePool, value); + if (integer->hasError()) { + attributeContentError("value", "minLength", value, BuiltinTypes::xsNonNegativeInteger); + return facet; + } else { + facet->setValue(integer); + } + + validateIdAttribute("minLength"); + + TagValidationHandler tagValidator(XsdTagScope::MinLengthFacet, this, m_namePool); + + while (!atEnd()) { + readNext(); + + if (isEndElement()) + break; + + if (isStartElement()) { + const XsdSchemaToken::NodeName token = XsdSchemaToken::toToken(name()); + const XsdSchemaToken::NodeName namespaceToken = XsdSchemaToken::toToken(namespaceUri()); + + tagValidator.validate(token); + + if (isSchemaTag(XsdSchemaToken::Annotation, token, namespaceToken)) { + const XsdAnnotation::Ptr annotation = parseAnnotation(); + facet->addAnnotation(annotation); + } else { + parseUnknown(); + } + } + } + + tagValidator.finalize(); + + return facet; +} + +XsdFacet::Ptr XsdSchemaParser::parseMaxLengthFacet() +{ + const ElementNamespaceHandler namespaceHandler(XsdSchemaToken::MaxLength, this); + + validateElement(XsdTagScope::MaxLengthFacet); + + const XsdFacet::Ptr facet = XsdFacet::Ptr(new XsdFacet()); + facet->setType(XsdFacet::MaximumLength); + + // parse attributes + if (hasAttribute(QString::fromLatin1("fixed"))) { + const QString value = readAttribute(QString::fromLatin1("fixed")); + const Boolean::Ptr fixed = Boolean::fromLexical(value); + if (fixed->hasError()) { + attributeContentError("fixed", "maxLength", value, BuiltinTypes::xsBoolean); + return facet; + } + + facet->setFixed(fixed->as()->value()); + } else { + facet->setFixed(false); // the default value + } + + const QString value = readAttribute(QString::fromLatin1("value")); + DerivedInteger::Ptr integer = DerivedInteger::fromLexical(m_namePool, value); + if (integer->hasError()) { + attributeContentError("value", "maxLength", value, BuiltinTypes::xsNonNegativeInteger); + return facet; + } else { + facet->setValue(integer); + } + + validateIdAttribute("maxLength"); + + TagValidationHandler tagValidator(XsdTagScope::MaxLengthFacet, this, m_namePool); + + while (!atEnd()) { + readNext(); + + if (isEndElement()) + break; + + if (isStartElement()) { + const XsdSchemaToken::NodeName token = XsdSchemaToken::toToken(name()); + const XsdSchemaToken::NodeName namespaceToken = XsdSchemaToken::toToken(namespaceUri()); + + tagValidator.validate(token); + + if (isSchemaTag(XsdSchemaToken::Annotation, token, namespaceToken)) { + const XsdAnnotation::Ptr annotation = parseAnnotation(); + facet->addAnnotation(annotation); + } else { + parseUnknown(); + } + } + } + + tagValidator.finalize(); + + return facet; +} + +XsdFacet::Ptr XsdSchemaParser::parseEnumerationFacet() +{ + const ElementNamespaceHandler namespaceHandler(XsdSchemaToken::Enumeration, this); + + validateElement(XsdTagScope::EnumerationFacet); + + const XsdFacet::Ptr facet = XsdFacet::Ptr(new XsdFacet()); + facet->setType(XsdFacet::Enumeration); + + // parse attributes + facet->setFixed(false); // not defined in schema, but can't hurt + + const QString value = readAttribute(QString::fromLatin1("value")); + + // as enumeration can have a value of type anySimpleType, we just read + // the string here and store it for later intepretation + DerivedString::Ptr string = DerivedString::fromLexical(m_namePool, value); + if (string->hasError()) { + attributeContentError("value", "enumeration", value); + return facet; + } else { + AtomicValue::List multiValue; + multiValue << string; + facet->setMultiValue(multiValue); + } + m_schemaResolver->addEnumerationFacetValue(string, m_namespaceSupport); + + validateIdAttribute("enumeration"); + + TagValidationHandler tagValidator(XsdTagScope::EnumerationFacet, this, m_namePool); + + while (!atEnd()) { + readNext(); + + if (isEndElement()) + break; + + if (isStartElement()) { + const XsdSchemaToken::NodeName token = XsdSchemaToken::toToken(name()); + const XsdSchemaToken::NodeName namespaceToken = XsdSchemaToken::toToken(namespaceUri()); + + tagValidator.validate(token); + + if (isSchemaTag(XsdSchemaToken::Annotation, token, namespaceToken)) { + const XsdAnnotation::Ptr annotation = parseAnnotation(); + facet->addAnnotation(annotation); + } else { + parseUnknown(); + } + } + } + + tagValidator.finalize(); + + return facet; +} + +XsdFacet::Ptr XsdSchemaParser::parseWhiteSpaceFacet() +{ + const ElementNamespaceHandler namespaceHandler(XsdSchemaToken::WhiteSpace, this); + + validateElement(XsdTagScope::WhiteSpaceFacet); + + const XsdFacet::Ptr facet = XsdFacet::Ptr(new XsdFacet()); + facet->setType(XsdFacet::WhiteSpace); + + // parse attributes + if (hasAttribute(QString::fromLatin1("fixed"))) { + const QString value = readAttribute(QString::fromLatin1("fixed")); + const Boolean::Ptr fixed = Boolean::fromLexical(value); + if (fixed->hasError()) { + attributeContentError("fixed", "whiteSpace", value, BuiltinTypes::xsBoolean); + return facet; + } + + facet->setFixed(fixed->as()->value()); + } else { + facet->setFixed(false); // the default value + } + + const QString value = readAttribute(QString::fromLatin1("value")); + if (value != XsdSchemaToken::toString(XsdSchemaToken::Collapse) && + value != XsdSchemaToken::toString(XsdSchemaToken::Preserve) && + value != XsdSchemaToken::toString(XsdSchemaToken::Replace)) { + attributeContentError("value", "whiteSpace", value); + return facet; + } else { + DerivedString::Ptr string = DerivedString::fromLexical(m_namePool, value); + if (string->hasError()) { + attributeContentError("value", "whiteSpace", value); + return facet; + } else { + facet->setValue(string); + } + } + + validateIdAttribute("whiteSpace"); + + TagValidationHandler tagValidator(XsdTagScope::WhiteSpaceFacet, this, m_namePool); + + while (!atEnd()) { + readNext(); + + if (isEndElement()) + break; + + if (isStartElement()) { + const XsdSchemaToken::NodeName token = XsdSchemaToken::toToken(name()); + const XsdSchemaToken::NodeName namespaceToken = XsdSchemaToken::toToken(namespaceUri()); + + tagValidator.validate(token); + + if (isSchemaTag(XsdSchemaToken::Annotation, token, namespaceToken)) { + const XsdAnnotation::Ptr annotation = parseAnnotation(); + facet->addAnnotation(annotation); + } else { + parseUnknown(); + } + } + } + + tagValidator.finalize(); + + return facet; +} + +XsdFacet::Ptr XsdSchemaParser::parsePatternFacet() +{ + const ElementNamespaceHandler namespaceHandler(XsdSchemaToken::Pattern, this); + + validateElement(XsdTagScope::PatternFacet); + + const XsdFacet::Ptr facet = XsdFacet::Ptr(new XsdFacet()); + facet->setType(XsdFacet::Pattern); + + // parse attributes + + // as pattern can have a value of type anySimpleType, we just read + // the string here and store it for later intepretation + const QString value = readAttribute(QString::fromLatin1("value")); + DerivedString::Ptr string = DerivedString::fromLexical(m_namePool, value); + if (string->hasError()) { + attributeContentError("value", "pattern", value); + return facet; + } else { + AtomicValue::List multiValue; + multiValue << string; + facet->setMultiValue(multiValue); + } + + validateIdAttribute("pattern"); + + TagValidationHandler tagValidator(XsdTagScope::PatternFacet, this, m_namePool); + + while (!atEnd()) { + readNext(); + + if (isEndElement()) + break; + + if (isStartElement()) { + const XsdSchemaToken::NodeName token = XsdSchemaToken::toToken(name()); + const XsdSchemaToken::NodeName namespaceToken = XsdSchemaToken::toToken(namespaceUri()); + + tagValidator.validate(token); + + if (isSchemaTag(XsdSchemaToken::Annotation, token, namespaceToken)) { + const XsdAnnotation::Ptr annotation = parseAnnotation(); + facet->addAnnotation(annotation); + } else { + parseUnknown(); + } + } + } + + tagValidator.finalize(); + + return facet; +} + +XsdFacet::Ptr XsdSchemaParser::parseAssertionFacet() +{ + // this is just a wrapper function around the parseAssertion() method + + const XsdAssertion::Ptr assertion = parseAssertion(XsdSchemaToken::Assertion, XsdTagScope::Assertion); + + const XsdFacet::Ptr facet = XsdFacet::Ptr(new XsdFacet()); + facet->setType(XsdFacet::Assertion); + facet->setAssertions(XsdAssertion::List() << assertion); + + return facet; +} + +XsdComplexType::Ptr XsdSchemaParser::parseGlobalComplexType() +{ + const ElementNamespaceHandler namespaceHandler(XsdSchemaToken::ComplexType, this); + + validateElement(XsdTagScope::GlobalComplexType); + + bool hasTypeSpecified = false; + bool hasComplexContent = false; + + const XsdComplexType::Ptr complexType(new XsdComplexType()); + + // parse attributes + if (hasAttribute(QString::fromLatin1("abstract"))) { + const QString abstract = readAttribute(QString::fromLatin1("abstract")); + + const Boolean::Ptr value = Boolean::fromLexical(abstract); + if (value->hasError()) { + attributeContentError("abstract", "complexType", abstract, BuiltinTypes::xsBoolean); + return complexType; + } + + complexType->setIsAbstract(value->as()->value()); + } else { + complexType->setIsAbstract(false); // default value + } + + complexType->setProhibitedSubstitutions(readBlockingConstraintAttribute(NamedSchemaComponent::ExtensionConstraint | NamedSchemaComponent::RestrictionConstraint, "complexType")); + complexType->setDerivationConstraints(readDerivationConstraintAttribute(SchemaType::ExtensionConstraint | SchemaType::RestrictionConstraint, "complexType")); + + const QXmlName objectName = m_namePool->allocateQName(m_targetNamespace, readNameAttribute("complexType")); + complexType->setName(objectName); + + bool effectiveMixed = false; + if (hasAttribute(QString::fromLatin1("mixed"))) { + const QString mixed = readAttribute(QString::fromLatin1("mixed")); + + const Boolean::Ptr value = Boolean::fromLexical(mixed); + if (value->hasError()) { + attributeContentError("mixed", "complexType", mixed, BuiltinTypes::xsBoolean); + return complexType; + } + + effectiveMixed = value->as()->value(); + } + + validateIdAttribute("complexType"); + + TagValidationHandler tagValidator(XsdTagScope::GlobalComplexType, this, m_namePool); + + while (!atEnd()) { + readNext(); + + if (isEndElement()) + break; + + if (isStartElement()) { + const XsdSchemaToken::NodeName token = XsdSchemaToken::toToken(name()); + const XsdSchemaToken::NodeName namespaceToken = XsdSchemaToken::toToken(namespaceUri()); + + tagValidator.validate(token); + + if (isSchemaTag(XsdSchemaToken::Annotation, token, namespaceToken)) { + const XsdAnnotation::Ptr annotation = parseAnnotation(); + complexType->addAnnotation(annotation); + } else if (isSchemaTag(XsdSchemaToken::SimpleContent, token, namespaceToken)) { + if (effectiveMixed) { + error(QtXmlPatterns::tr("%1 element with %2 child element must not have a %3 attribute") + .arg(formatElement("complexType")) + .arg(formatElement("simpleContent")) + .arg(formatAttribute("mixed"))); + return complexType; + } + + parseSimpleContent(complexType); + hasTypeSpecified = true; + } else if (isSchemaTag(XsdSchemaToken::ComplexContent, token, namespaceToken)) { + bool mixed; + parseComplexContent(complexType, &mixed); + hasTypeSpecified = true; + + effectiveMixed = (effectiveMixed || mixed); + hasComplexContent = true; + } else if (isSchemaTag(XsdSchemaToken::OpenContent, token, namespaceToken)) { + const XsdComplexType::OpenContent::Ptr openContent = parseOpenContent(); + complexType->contentType()->setOpenContent(openContent); + hasComplexContent = true; + } else if (isSchemaTag(XsdSchemaToken::Group, token, namespaceToken)) { + const XsdParticle::Ptr particle(new XsdParticle()); + const XsdTerm::Ptr term = parseReferredGroup(particle); + particle->setTerm(term); + complexType->contentType()->setParticle(particle); + + complexType->setWxsSuperType(BuiltinTypes::xsAnyType); + complexType->contentType()->setVariety(XsdComplexType::ContentType::ElementOnly); + complexType->setDerivationMethod(XsdComplexType::DerivationRestriction); + hasComplexContent = true; + } else if (isSchemaTag(XsdSchemaToken::All, token, namespaceToken)) { + const XsdParticle::Ptr particle(new XsdParticle()); + const XsdTerm::Ptr term = parseLocalAll(particle, complexType); + particle->setTerm(term); + complexType->contentType()->setParticle(particle); + + complexType->setWxsSuperType(BuiltinTypes::xsAnyType); + complexType->contentType()->setVariety(XsdComplexType::ContentType::ElementOnly); + complexType->setDerivationMethod(XsdComplexType::DerivationRestriction); + hasComplexContent = true; + } else if (isSchemaTag(XsdSchemaToken::Choice, token, namespaceToken)) { + const XsdParticle::Ptr particle(new XsdParticle()); + const XsdTerm::Ptr term = parseLocalChoice(particle, complexType); + particle->setTerm(term); + complexType->contentType()->setParticle(particle); + + complexType->setWxsSuperType(BuiltinTypes::xsAnyType); + complexType->contentType()->setVariety(XsdComplexType::ContentType::ElementOnly); + complexType->setDerivationMethod(XsdComplexType::DerivationRestriction); + hasComplexContent = true; + } else if (isSchemaTag(XsdSchemaToken::Sequence, token, namespaceToken)) { + const XsdParticle::Ptr particle(new XsdParticle()); + const XsdTerm::Ptr term = parseLocalSequence(particle, complexType); + particle->setTerm(term); + complexType->contentType()->setParticle(particle); + + complexType->setWxsSuperType(BuiltinTypes::xsAnyType); + complexType->contentType()->setVariety(XsdComplexType::ContentType::ElementOnly); + complexType->setDerivationMethod(XsdComplexType::DerivationRestriction); + hasComplexContent = true; + } else if (isSchemaTag(XsdSchemaToken::Attribute, token, namespaceToken)) { + const XsdAttributeUse::Ptr attributeUse = parseLocalAttribute(complexType); + complexType->addAttributeUse(attributeUse); + + complexType->setWxsSuperType(BuiltinTypes::xsAnyType); + complexType->contentType()->setVariety(XsdComplexType::ContentType::ElementOnly); + complexType->setDerivationMethod(XsdComplexType::DerivationRestriction); + hasComplexContent = true; + } else if (isSchemaTag(XsdSchemaToken::AttributeGroup, token, namespaceToken)) { + const XsdAttributeUse::Ptr attributeUse = parseReferredAttributeGroup(); + complexType->addAttributeUse(attributeUse); + + complexType->setWxsSuperType(BuiltinTypes::xsAnyType); + complexType->contentType()->setVariety(XsdComplexType::ContentType::ElementOnly); + complexType->setDerivationMethod(XsdComplexType::DerivationRestriction); + hasComplexContent = true; + } else if (isSchemaTag(XsdSchemaToken::AnyAttribute, token, namespaceToken)) { + const XsdWildcard::Ptr wildcard = parseAnyAttribute(); + complexType->setAttributeWildcard(wildcard); + + complexType->setWxsSuperType(BuiltinTypes::xsAnyType); + complexType->contentType()->setVariety(XsdComplexType::ContentType::ElementOnly); + complexType->setDerivationMethod(XsdComplexType::DerivationRestriction); + hasComplexContent = true; + } else if (isSchemaTag(XsdSchemaToken::Assert, token, namespaceToken)) { + const XsdAssertion::Ptr assertion = parseAssertion(XsdSchemaToken::Assert, XsdTagScope::Assert); + complexType->addAssertion(assertion); + } else { + parseUnknown(); + } + } + } + + tagValidator.finalize(); + + if (!hasTypeSpecified) { + complexType->setWxsSuperType(BuiltinTypes::xsAnyType); + complexType->setDerivationMethod(XsdComplexType::DerivationRestriction); + hasComplexContent = true; + } + + if (hasComplexContent == true) { + resolveComplexContentType(complexType, effectiveMixed); + } + + return complexType; +} + +XsdComplexType::Ptr XsdSchemaParser::parseLocalComplexType() +{ + const ElementNamespaceHandler namespaceHandler(XsdSchemaToken::ComplexType, this); + + validateElement(XsdTagScope::LocalComplexType); + + bool hasTypeSpecified = false; + bool hasComplexContent = true; + + const XsdComplexType::Ptr complexType(new XsdComplexType()); + complexType->setName(m_parserContext->createAnonymousName(m_targetNamespace)); + + // parse attributes + bool effectiveMixed = false; + if (hasAttribute(QString::fromLatin1("mixed"))) { + const QString mixed = readAttribute(QString::fromLatin1("mixed")); + + const Boolean::Ptr value = Boolean::fromLexical(mixed); + if (value->hasError()) { + attributeContentError("mixed", "complexType", mixed, BuiltinTypes::xsBoolean); + return complexType; + } + + effectiveMixed = value->as()->value(); + } + + validateIdAttribute("complexType"); + + TagValidationHandler tagValidator(XsdTagScope::LocalComplexType, this, m_namePool); + + while (!atEnd()) { + readNext(); + + if (isEndElement()) + break; + + if (isStartElement()) { + const XsdSchemaToken::NodeName token = XsdSchemaToken::toToken(name()); + const XsdSchemaToken::NodeName namespaceToken = XsdSchemaToken::toToken(namespaceUri()); + + tagValidator.validate(token); + + if (isSchemaTag(XsdSchemaToken::Annotation, token, namespaceToken)) { + const XsdAnnotation::Ptr annotation = parseAnnotation(); + complexType->addAnnotation(annotation); + } else if (isSchemaTag(XsdSchemaToken::SimpleContent, token, namespaceToken)) { + parseSimpleContent(complexType); + hasTypeSpecified = true; + } else if (isSchemaTag(XsdSchemaToken::ComplexContent, token, namespaceToken)) { + bool mixed; + parseComplexContent(complexType, &mixed); + hasTypeSpecified = true; + + effectiveMixed = (effectiveMixed || mixed); + hasComplexContent = true; + } else if (isSchemaTag(XsdSchemaToken::OpenContent, token, namespaceToken)) { + const XsdComplexType::OpenContent::Ptr openContent = parseOpenContent(); + complexType->contentType()->setOpenContent(openContent); + hasComplexContent = true; + } else if (isSchemaTag(XsdSchemaToken::Group, token, namespaceToken)) { + const XsdParticle::Ptr particle(new XsdParticle()); + const XsdTerm::Ptr term = parseReferredGroup(particle); + particle->setTerm(term); + complexType->contentType()->setParticle(particle); + + complexType->setWxsSuperType(BuiltinTypes::xsAnyType); + complexType->contentType()->setVariety(XsdComplexType::ContentType::ElementOnly); + complexType->setDerivationMethod(XsdComplexType::DerivationRestriction); + hasComplexContent = true; + } else if (isSchemaTag(XsdSchemaToken::All, token, namespaceToken)) { + const XsdParticle::Ptr particle(new XsdParticle()); + const XsdTerm::Ptr term = parseLocalAll(particle, complexType); + particle->setTerm(term); + complexType->contentType()->setParticle(particle); + + complexType->setWxsSuperType(BuiltinTypes::xsAnyType); + complexType->contentType()->setVariety(XsdComplexType::ContentType::ElementOnly); + complexType->setDerivationMethod(XsdComplexType::DerivationRestriction); + hasComplexContent = true; + } else if (isSchemaTag(XsdSchemaToken::Choice, token, namespaceToken)) { + const XsdParticle::Ptr particle(new XsdParticle()); + const XsdTerm::Ptr term = parseLocalChoice(particle, complexType); + particle->setTerm(term); + complexType->contentType()->setParticle(particle); + + complexType->setWxsSuperType(BuiltinTypes::xsAnyType); + complexType->contentType()->setVariety(XsdComplexType::ContentType::ElementOnly); + complexType->setDerivationMethod(XsdComplexType::DerivationRestriction); + hasComplexContent = true; + } else if (isSchemaTag(XsdSchemaToken::Sequence, token, namespaceToken)) { + const XsdParticle::Ptr particle(new XsdParticle()); + const XsdTerm::Ptr term = parseLocalSequence(particle, complexType); + particle->setTerm(term); + complexType->contentType()->setParticle(particle); + + complexType->setWxsSuperType(BuiltinTypes::xsAnyType); + complexType->contentType()->setVariety(XsdComplexType::ContentType::ElementOnly); + complexType->setDerivationMethod(XsdComplexType::DerivationRestriction); + hasComplexContent = true; + } else if (isSchemaTag(XsdSchemaToken::Attribute, token, namespaceToken)) { + const XsdAttributeUse::Ptr attributeUse = parseLocalAttribute(complexType); + complexType->addAttributeUse(attributeUse); + + complexType->setWxsSuperType(BuiltinTypes::xsAnyType); + complexType->contentType()->setVariety(XsdComplexType::ContentType::ElementOnly); + complexType->setDerivationMethod(XsdComplexType::DerivationRestriction); + hasComplexContent = true; + } else if (isSchemaTag(XsdSchemaToken::AttributeGroup, token, namespaceToken)) { + const XsdAttributeUse::Ptr attributeUse = parseReferredAttributeGroup(); + complexType->addAttributeUse(attributeUse); + + complexType->setWxsSuperType(BuiltinTypes::xsAnyType); + complexType->contentType()->setVariety(XsdComplexType::ContentType::ElementOnly); + complexType->setDerivationMethod(XsdComplexType::DerivationRestriction); + hasComplexContent = true; + } else if (isSchemaTag(XsdSchemaToken::AnyAttribute, token, namespaceToken)) { + const XsdWildcard::Ptr wildcard = parseAnyAttribute(); + complexType->setAttributeWildcard(wildcard); + + complexType->setWxsSuperType(BuiltinTypes::xsAnyType); + complexType->contentType()->setVariety(XsdComplexType::ContentType::ElementOnly); + complexType->setDerivationMethod(XsdComplexType::DerivationRestriction); + hasComplexContent = true; + } else if (isSchemaTag(XsdSchemaToken::Assert, token, namespaceToken)) { + const XsdAssertion::Ptr assertion = parseAssertion(XsdSchemaToken::Assert, XsdTagScope::Assert); + complexType->addAssertion(assertion); + } else { + parseUnknown(); + } + } + } + + tagValidator.finalize(); + + if (!hasTypeSpecified) { + complexType->setWxsSuperType(BuiltinTypes::xsAnyType); + complexType->setDerivationMethod(XsdComplexType::DerivationRestriction); + hasComplexContent = true; + } + + if (hasComplexContent == true) { + resolveComplexContentType(complexType, effectiveMixed); + } + + return complexType; +} + +void XsdSchemaParser::resolveComplexContentType(const XsdComplexType::Ptr &complexType, bool effectiveMixed) +{ + // @see http://www.w3.org/TR/xmlschema11-1/#dcl.ctd.ctcc.common + + // 1 + // the effectiveMixed contains the effective mixed value + + // 2 + bool hasEmptyContent = false; + if (!complexType->contentType()->particle()) { + hasEmptyContent = true; // 2.1.1 + } else { + if (complexType->contentType()->particle()->term()->isModelGroup()) { + const XsdModelGroup::Ptr group = complexType->contentType()->particle()->term(); + if (group->compositor() == XsdModelGroup::SequenceCompositor || group->compositor() == XsdModelGroup::AllCompositor) { + if (group->particles().isEmpty()) + hasEmptyContent = true; // 2.1.2 + } else if (group->compositor() == XsdModelGroup::ChoiceCompositor) { + if ((complexType->contentType()->particle()->minimumOccurs() == 0) && group->particles().isEmpty()) + hasEmptyContent = true; // 2.1.3 + } + + if ((complexType->contentType()->particle()->maximumOccursUnbounded() == false) && (complexType->contentType()->particle()->maximumOccurs() == 0)) + hasEmptyContent = true; // 2.1.4 + } + } + + const XsdParticle::Ptr explicitContent = (hasEmptyContent ? XsdParticle::Ptr() : complexType->contentType()->particle()); + + // do all the other work (3, 4, 5 and 6) in the resolver, as they need access to the base type object + m_schemaResolver->addComplexContentType(complexType, explicitContent, effectiveMixed); +} + +void XsdSchemaParser::parseSimpleContent(const XsdComplexType::Ptr &complexType) +{ + const ElementNamespaceHandler namespaceHandler(XsdSchemaToken::SimpleContent, this); + + validateElement(XsdTagScope::SimpleContent); + + complexType->contentType()->setVariety(XsdComplexType::ContentType::Simple); + + // parse attributes + validateIdAttribute("simpleContent"); + + TagValidationHandler tagValidator(XsdTagScope::SimpleContent, this, m_namePool); + + while (!atEnd()) { + readNext(); + + if (isEndElement()) + break; + + if (isStartElement()) { + const XsdSchemaToken::NodeName token = XsdSchemaToken::toToken(name()); + const XsdSchemaToken::NodeName namespaceToken = XsdSchemaToken::toToken(namespaceUri()); + + tagValidator.validate(token); + + if (isSchemaTag(XsdSchemaToken::Annotation, token, namespaceToken)) { + const XsdAnnotation::Ptr annotation = parseAnnotation(); + complexType->addAnnotation(annotation); + } else if (isSchemaTag(XsdSchemaToken::Restriction, token, namespaceToken)) { + parseSimpleContentRestriction(complexType); + } else if (isSchemaTag(XsdSchemaToken::Extension, token, namespaceToken)) { + parseSimpleContentExtension(complexType); + } else { + parseUnknown(); + } + } + } + + tagValidator.finalize(); +} + +void XsdSchemaParser::parseSimpleContentRestriction(const XsdComplexType::Ptr &complexType) +{ + const ElementNamespaceHandler namespaceHandler(XsdSchemaToken::Restriction, this); + + validateElement(XsdTagScope::SimpleContentRestriction); + + complexType->setDerivationMethod(XsdComplexType::DerivationRestriction); + + // parse attributes + const QString baseType = readQNameAttribute(QString::fromLatin1("base"), "restriction"); + QXmlName typeName; + convertName(baseType, NamespaceSupport::ElementName, typeName); // translate qualified name into QXmlName + + validateIdAttribute("restriction"); + + XsdFacet::Hash facets; + QList patternFacets; + QList enumerationFacets; + QList assertionFacets; + + TagValidationHandler tagValidator(XsdTagScope::SimpleContentRestriction, this, m_namePool); + + while (!atEnd()) { + readNext(); + + if (isEndElement()) + break; + + if (isStartElement()) { + const XsdSchemaToken::NodeName token = XsdSchemaToken::toToken(name()); + const XsdSchemaToken::NodeName namespaceToken = XsdSchemaToken::toToken(namespaceUri()); + + tagValidator.validate(token); + + if (isSchemaTag(XsdSchemaToken::Annotation, token, namespaceToken)) { + const XsdAnnotation::Ptr annotation = parseAnnotation(); + complexType->addAnnotation(annotation); + } else if (isSchemaTag(XsdSchemaToken::SimpleType, token, namespaceToken)) { + const XsdSimpleType::Ptr type = parseLocalSimpleType(); + type->setContext(complexType); //TODO: investigate what the schema spec really wants here?!? + complexType->contentType()->setSimpleType(type); + + // add it to list of anonymous types as well + addAnonymousType(type); + } else if (isSchemaTag(XsdSchemaToken::MinExclusive, token, namespaceToken)) { + const XsdFacet::Ptr facet = parseMinExclusiveFacet(); + addFacet(facet, facets, complexType); + } else if (isSchemaTag(XsdSchemaToken::MinInclusive, token, namespaceToken)) { + const XsdFacet::Ptr facet = parseMinInclusiveFacet(); + addFacet(facet, facets, complexType); + } else if (isSchemaTag(XsdSchemaToken::MaxExclusive, token, namespaceToken)) { + const XsdFacet::Ptr facet = parseMaxExclusiveFacet(); + addFacet(facet, facets, complexType); + } else if (isSchemaTag(XsdSchemaToken::MaxInclusive, token, namespaceToken)) { + const XsdFacet::Ptr facet = parseMaxInclusiveFacet(); + addFacet(facet, facets, complexType); + } else if (isSchemaTag(XsdSchemaToken::TotalDigits, token, namespaceToken)) { + const XsdFacet::Ptr facet = parseTotalDigitsFacet(); + addFacet(facet, facets, complexType); + } else if (isSchemaTag(XsdSchemaToken::FractionDigits, token, namespaceToken)) { + const XsdFacet::Ptr facet = parseFractionDigitsFacet(); + addFacet(facet, facets, complexType); + } else if (isSchemaTag(XsdSchemaToken::Length, token, namespaceToken)) { + const XsdFacet::Ptr facet = parseLengthFacet(); + addFacet(facet, facets, complexType); + } else if (isSchemaTag(XsdSchemaToken::MinLength, token, namespaceToken)) { + const XsdFacet::Ptr facet = parseMinLengthFacet(); + addFacet(facet, facets, complexType); + } else if (isSchemaTag(XsdSchemaToken::MaxLength, token, namespaceToken)) { + const XsdFacet::Ptr facet = parseMaxLengthFacet(); + addFacet(facet, facets, complexType); + } else if (isSchemaTag(XsdSchemaToken::Enumeration, token, namespaceToken)) { + const XsdFacet::Ptr facet = parseEnumerationFacet(); + enumerationFacets.append(facet); + } else if (isSchemaTag(XsdSchemaToken::WhiteSpace, token, namespaceToken)) { + const XsdFacet::Ptr facet = parseWhiteSpaceFacet(); + addFacet(facet, facets, complexType); + } else if (isSchemaTag(XsdSchemaToken::Pattern, token, namespaceToken)) { + const XsdFacet::Ptr facet = parsePatternFacet(); + patternFacets.append(facet); + } else if (isSchemaTag(XsdSchemaToken::Assertion, token, namespaceToken)) { + const XsdFacet::Ptr facet = parseAssertionFacet(); + assertionFacets.append(facet); + } else if (isSchemaTag(XsdSchemaToken::Attribute, token, namespaceToken)) { + const XsdAttributeUse::Ptr attributeUse = parseLocalAttribute(complexType); + complexType->addAttributeUse(attributeUse); + } else if (isSchemaTag(XsdSchemaToken::AttributeGroup, token, namespaceToken)) { + const XsdAttributeUse::Ptr attributeUse = parseReferredAttributeGroup(); + complexType->addAttributeUse(attributeUse); + } else if (isSchemaTag(XsdSchemaToken::AnyAttribute, token, namespaceToken)) { + const XsdWildcard::Ptr wildcard = parseAnyAttribute(); + complexType->setAttributeWildcard(wildcard); + } else if (isSchemaTag(XsdSchemaToken::Assert, token, namespaceToken)) { + const XsdAssertion::Ptr assertion = parseAssertion(XsdSchemaToken::Assert, XsdTagScope::Assert); + complexType->addAssertion(assertion); + } else { + parseUnknown(); + } + } + } + + tagValidator.finalize(); + + // merge all pattern facets into one multi value facet + if (!patternFacets.isEmpty()) { + const XsdFacet::Ptr patternFacet(new XsdFacet()); + patternFacet->setType(XsdFacet::Pattern); + + AtomicValue::List multiValue; + for (int i = 0; i < patternFacets.count(); ++i) + multiValue << patternFacets.at(i)->multiValue(); + + patternFacet->setMultiValue(multiValue); + addFacet(patternFacet, facets, complexType); + } + + // merge all enumeration facets into one multi value facet + if (!enumerationFacets.isEmpty()) { + const XsdFacet::Ptr enumerationFacet(new XsdFacet()); + enumerationFacet->setType(XsdFacet::Enumeration); + + AtomicValue::List multiValue; + for (int i = 0; i < enumerationFacets.count(); ++i) + multiValue << enumerationFacets.at(i)->multiValue(); + + enumerationFacet->setMultiValue(multiValue); + addFacet(enumerationFacet, facets, complexType); + } + + // merge all assertion facets into one facet + if (!assertionFacets.isEmpty()) { + const XsdFacet::Ptr assertionFacet(new XsdFacet()); + assertionFacet->setType(XsdFacet::Assertion); + + XsdAssertion::List assertions; + for (int i = 0; i < assertionFacets.count(); ++i) + assertions << assertionFacets.at(i)->assertions(); + + assertionFacet->setAssertions(assertions); + addFacet(assertionFacet, facets, complexType); + } + + m_schemaResolver->addComplexBaseType(complexType, typeName, currentSourceLocation(), facets); // add to resolver +} + +void XsdSchemaParser::parseSimpleContentExtension(const XsdComplexType::Ptr &complexType) +{ + const ElementNamespaceHandler namespaceHandler(XsdSchemaToken::Extension, this); + + validateElement(XsdTagScope::SimpleContentExtension); + + complexType->setDerivationMethod(XsdComplexType::DerivationExtension); + + // parse attributes + const QString baseType = readQNameAttribute(QString::fromLatin1("base"), "extension"); + QXmlName typeName; + convertName(baseType, NamespaceSupport::ElementName, typeName); // translate qualified name into QXmlName + m_schemaResolver->addComplexBaseType(complexType, typeName, currentSourceLocation()); // add to resolver + + validateIdAttribute("extension"); + + TagValidationHandler tagValidator(XsdTagScope::SimpleContentExtension, this, m_namePool); + + while (!atEnd()) { + readNext(); + + if (isEndElement()) + break; + + if (isStartElement()) { + const XsdSchemaToken::NodeName token = XsdSchemaToken::toToken(name()); + const XsdSchemaToken::NodeName namespaceToken = XsdSchemaToken::toToken(namespaceUri()); + + tagValidator.validate(token); + + if (isSchemaTag(XsdSchemaToken::Annotation, token, namespaceToken)) { + const XsdAnnotation::Ptr annotation = parseAnnotation(); + complexType->addAnnotation(annotation); + } else if (isSchemaTag(XsdSchemaToken::Attribute, token, namespaceToken)) { + const XsdAttributeUse::Ptr attributeUse = parseLocalAttribute(complexType); + complexType->addAttributeUse(attributeUse); + } else if (isSchemaTag(XsdSchemaToken::AttributeGroup, token, namespaceToken)) { + const XsdAttributeUse::Ptr attributeUse = parseReferredAttributeGroup(); + complexType->addAttributeUse(attributeUse); + } else if (isSchemaTag(XsdSchemaToken::AnyAttribute, token, namespaceToken)) { + const XsdWildcard::Ptr wildcard = parseAnyAttribute(); + complexType->setAttributeWildcard(wildcard); + } else if (isSchemaTag(XsdSchemaToken::Assert, token, namespaceToken)) { + const XsdAssertion::Ptr assertion = parseAssertion(XsdSchemaToken::Assert, XsdTagScope::Assert); + complexType->addAssertion(assertion); + } else { + parseUnknown(); + } + } + } + + tagValidator.finalize(); +} + +void XsdSchemaParser::parseComplexContent(const XsdComplexType::Ptr &complexType, bool *mixed) +{ + const ElementNamespaceHandler namespaceHandler(XsdSchemaToken::ComplexContent, this); + + validateElement(XsdTagScope::ComplexContent); + + complexType->contentType()->setVariety(XsdComplexType::ContentType::ElementOnly); + + // parse attributes + if (hasAttribute(QString::fromLatin1("mixed"))) { + const QString mixedStr = readAttribute(QString::fromLatin1("mixed")); + + const Boolean::Ptr value = Boolean::fromLexical(mixedStr); + if (value->hasError()) { + attributeContentError("mixed", "complexType", mixedStr, BuiltinTypes::xsBoolean); + return; + } + + *mixed = value->as()->value(); + } else { + *mixed = false; + } + + validateIdAttribute("complexContent"); + + TagValidationHandler tagValidator(XsdTagScope::ComplexContent, this, m_namePool); + + while (!atEnd()) { + readNext(); + + if (isEndElement()) + break; + + if (isStartElement()) { + const XsdSchemaToken::NodeName token = XsdSchemaToken::toToken(name()); + const XsdSchemaToken::NodeName namespaceToken = XsdSchemaToken::toToken(namespaceUri()); + + tagValidator.validate(token); + + if (isSchemaTag(XsdSchemaToken::Annotation, token, namespaceToken)) { + const XsdAnnotation::Ptr annotation = parseAnnotation(); + complexType->addAnnotation(annotation); + } else if (isSchemaTag(XsdSchemaToken::Restriction, token, namespaceToken)) { + parseComplexContentRestriction(complexType); + } else if (isSchemaTag(XsdSchemaToken::Extension, token, namespaceToken)) { + parseComplexContentExtension(complexType); + } else { + parseUnknown(); + } + } + } + + tagValidator.finalize(); +} + +void XsdSchemaParser::parseComplexContentRestriction(const XsdComplexType::Ptr &complexType) +{ + const ElementNamespaceHandler namespaceHandler(XsdSchemaToken::Restriction, this); + + validateElement(XsdTagScope::ComplexContentRestriction); + + complexType->setDerivationMethod(XsdComplexType::DerivationRestriction); + + // parse attributes + const QString baseType = readQNameAttribute(QString::fromLatin1("base"), "restriction"); + QXmlName typeName; + convertName(baseType, NamespaceSupport::ElementName, typeName); // translate qualified name into QXmlName + m_schemaResolver->addComplexBaseType(complexType, typeName, currentSourceLocation()); // add to resolver + + validateIdAttribute("restriction"); + + TagValidationHandler tagValidator(XsdTagScope::ComplexContentRestriction, this, m_namePool); + + bool hasContent = false; + while (!atEnd()) { + readNext(); + + if (isEndElement()) + break; + + if (isStartElement()) { + const XsdSchemaToken::NodeName token = XsdSchemaToken::toToken(name()); + const XsdSchemaToken::NodeName namespaceToken = XsdSchemaToken::toToken(namespaceUri()); + + tagValidator.validate(token); + + if (isSchemaTag(XsdSchemaToken::Annotation, token, namespaceToken)) { + const XsdAnnotation::Ptr annotation = parseAnnotation(); + complexType->addAnnotation(annotation); + } else if (isSchemaTag(XsdSchemaToken::OpenContent, token, namespaceToken)) { + const XsdComplexType::OpenContent::Ptr openContent = parseOpenContent(); + complexType->contentType()->setOpenContent(openContent); + hasContent = true; + } else if (isSchemaTag(XsdSchemaToken::Group, token, namespaceToken)) { + const XsdParticle::Ptr particle(new XsdParticle()); + const XsdTerm::Ptr term = parseReferredGroup(particle); + particle->setTerm(term); + complexType->contentType()->setParticle(particle); + hasContent = true; + } else if (isSchemaTag(XsdSchemaToken::All, token, namespaceToken)) { + const XsdParticle::Ptr particle(new XsdParticle()); + const XsdTerm::Ptr term = parseLocalAll(particle, complexType); + particle->setTerm(term); + complexType->contentType()->setParticle(particle); + hasContent = true; + } else if (isSchemaTag(XsdSchemaToken::Choice, token, namespaceToken)) { + const XsdParticle::Ptr particle(new XsdParticle()); + const XsdTerm::Ptr term = parseLocalChoice(particle, complexType); + particle->setTerm(term); + complexType->contentType()->setParticle(particle); + hasContent = true; + } else if (isSchemaTag(XsdSchemaToken::Sequence, token, namespaceToken)) { + const XsdParticle::Ptr particle(new XsdParticle()); + const XsdTerm::Ptr term = parseLocalSequence(particle, complexType); + particle->setTerm(term); + complexType->contentType()->setParticle(particle); + hasContent = true; + } else if (isSchemaTag(XsdSchemaToken::Attribute, token, namespaceToken)) { + const XsdAttributeUse::Ptr attributeUse = parseLocalAttribute(complexType); + complexType->addAttributeUse(attributeUse); + } else if (isSchemaTag(XsdSchemaToken::AttributeGroup, token, namespaceToken)) { + const XsdAttributeUse::Ptr attributeUse = parseReferredAttributeGroup(); + complexType->addAttributeUse(attributeUse); + } else if (isSchemaTag(XsdSchemaToken::AnyAttribute, token, namespaceToken)) { + const XsdWildcard::Ptr wildcard = parseAnyAttribute(); + complexType->setAttributeWildcard(wildcard); + } else if (isSchemaTag(XsdSchemaToken::Assert, token, namespaceToken)) { + const XsdAssertion::Ptr assertion = parseAssertion(XsdSchemaToken::Assert, XsdTagScope::Assert); + complexType->addAssertion(assertion); + } else { + parseUnknown(); + } + } + } + + if (!hasContent) + complexType->contentType()->setVariety(XsdComplexType::ContentType::Empty); + + tagValidator.finalize(); +} + +void XsdSchemaParser::parseComplexContentExtension(const XsdComplexType::Ptr &complexType) +{ + const ElementNamespaceHandler namespaceHandler(XsdSchemaToken::Extension, this); + + validateElement(XsdTagScope::ComplexContentExtension); + + complexType->setDerivationMethod(XsdComplexType::DerivationExtension); + + // parse attributes + const QString baseType = readQNameAttribute(QString::fromLatin1("base"), "extension"); + QXmlName typeName; + convertName(baseType, NamespaceSupport::ElementName, typeName); // translate qualified name into QXmlName + m_schemaResolver->addComplexBaseType(complexType, typeName, currentSourceLocation()); // add to resolver + + validateIdAttribute("extension"); + + TagValidationHandler tagValidator(XsdTagScope::ComplexContentExtension, this, m_namePool); + + bool hasContent = false; + while (!atEnd()) { + readNext(); + + if (isEndElement()) + break; + + if (isStartElement()) { + const XsdSchemaToken::NodeName token = XsdSchemaToken::toToken(name()); + const XsdSchemaToken::NodeName namespaceToken = XsdSchemaToken::toToken(namespaceUri()); + + tagValidator.validate(token); + + if (isSchemaTag(XsdSchemaToken::Annotation, token, namespaceToken)) { + const XsdAnnotation::Ptr annotation = parseAnnotation(); + complexType->addAnnotation(annotation); + } else if (isSchemaTag(XsdSchemaToken::OpenContent, token, namespaceToken)) { + const XsdComplexType::OpenContent::Ptr openContent = parseOpenContent(); + complexType->contentType()->setOpenContent(openContent); + hasContent = true; + } else if (isSchemaTag(XsdSchemaToken::Group, token, namespaceToken)) { + const XsdParticle::Ptr particle(new XsdParticle()); + const XsdTerm::Ptr term = parseReferredGroup(particle); + particle->setTerm(term); + complexType->contentType()->setParticle(particle); + hasContent = true; + } else if (isSchemaTag(XsdSchemaToken::All, token, namespaceToken)) { + const XsdParticle::Ptr particle(new XsdParticle()); + const XsdTerm::Ptr term = parseLocalAll(particle, complexType); + particle->setTerm(term); + complexType->contentType()->setParticle(particle); + hasContent = true; + } else if (isSchemaTag(XsdSchemaToken::Choice, token, namespaceToken)) { + const XsdParticle::Ptr particle(new XsdParticle()); + const XsdTerm::Ptr term = parseLocalChoice(particle, complexType); + particle->setTerm(term); + complexType->contentType()->setParticle(particle); + hasContent = true; + } else if (isSchemaTag(XsdSchemaToken::Sequence, token, namespaceToken)) { + const XsdParticle::Ptr particle(new XsdParticle()); + const XsdTerm::Ptr term = parseLocalSequence(particle, complexType); + particle->setTerm(term); + complexType->contentType()->setParticle(particle); + hasContent = true; + } else if (isSchemaTag(XsdSchemaToken::Attribute, token, namespaceToken)) { + const XsdAttributeUse::Ptr attributeUse = parseLocalAttribute(complexType); + complexType->addAttributeUse(attributeUse); + } else if (isSchemaTag(XsdSchemaToken::AttributeGroup, token, namespaceToken)) { + const XsdAttributeUse::Ptr attributeUse = parseReferredAttributeGroup(); + complexType->addAttributeUse(attributeUse); + } else if (isSchemaTag(XsdSchemaToken::AnyAttribute, token, namespaceToken)) { + const XsdWildcard::Ptr wildcard = parseAnyAttribute(); + complexType->setAttributeWildcard(wildcard); + } else if (isSchemaTag(XsdSchemaToken::Assert, token, namespaceToken)) { + const XsdAssertion::Ptr assertion = parseAssertion(XsdSchemaToken::Assert, XsdTagScope::Assert); + complexType->addAssertion(assertion); + } else { + parseUnknown(); + } + } + } + + if (!hasContent) + complexType->contentType()->setVariety(XsdComplexType::ContentType::Empty); + + tagValidator.finalize(); +} + + +XsdAssertion::Ptr XsdSchemaParser::parseAssertion(const XsdSchemaToken::NodeName &nodeName, const XsdTagScope::Type &tag) +{ + const ElementNamespaceHandler namespaceHandler(nodeName, this); + + validateElement(tag); + + const XsdAssertion::Ptr assertion(new XsdAssertion()); + + // parse attributes + + const XsdXPathExpression::Ptr expression = readXPathExpression("assertion"); + assertion->setTest(expression); + + const QString test = readXPathAttribute(QString::fromLatin1("test"), XPath20, "assertion"); + expression->setExpression(test); + + validateIdAttribute("assertion"); + + TagValidationHandler tagValidator(tag, this, m_namePool); + + while (!atEnd()) { + readNext(); + + if (isEndElement()) + break; + + if (isStartElement()) { + const XsdSchemaToken::NodeName token = XsdSchemaToken::toToken(name()); + const XsdSchemaToken::NodeName namespaceToken = XsdSchemaToken::toToken(namespaceUri()); + + tagValidator.validate(token); + + if (isSchemaTag(XsdSchemaToken::Annotation, token, namespaceToken)) { + const XsdAnnotation::Ptr annotation = parseAnnotation(); + assertion->addAnnotation(annotation); + } else { + parseUnknown(); + } + } + } + + tagValidator.finalize(); + + return assertion; +} + +XsdComplexType::OpenContent::Ptr XsdSchemaParser::parseOpenContent() +{ + const ElementNamespaceHandler namespaceHandler(XsdSchemaToken::OpenContent, this); + + validateElement(XsdTagScope::OpenContent); + + const XsdComplexType::OpenContent::Ptr openContent(new XsdComplexType::OpenContent()); + + if (hasAttribute(QString::fromLatin1("mode"))) { + const QString mode = readAttribute(QString::fromLatin1("mode")); + + if (mode == QString::fromLatin1("none")) { + m_defaultOpenContent->setMode(XsdComplexType::OpenContent::None); + } else if (mode == QString::fromLatin1("interleave")) { + m_defaultOpenContent->setMode(XsdComplexType::OpenContent::Interleave); + } else if (mode == QString::fromLatin1("suffix")) { + m_defaultOpenContent->setMode(XsdComplexType::OpenContent::Suffix); + } else { + attributeContentError("mode", "openContent", mode); + return openContent; + } + } else { + openContent->setMode(XsdComplexType::OpenContent::Interleave); + } + + validateIdAttribute("openContent"); + + TagValidationHandler tagValidator(XsdTagScope::OpenContent, this, m_namePool); + + while (!atEnd()) { + readNext(); + + if (isEndElement()) + break; + + if (isStartElement()) { + const XsdSchemaToken::NodeName token = XsdSchemaToken::toToken(name()); + const XsdSchemaToken::NodeName namespaceToken = XsdSchemaToken::toToken(namespaceUri()); + + tagValidator.validate(token); + + if (isSchemaTag(XsdSchemaToken::Annotation, token, namespaceToken)) { + const XsdAnnotation::Ptr annotation = parseAnnotation(); + openContent->addAnnotation(annotation); + } else if (isSchemaTag(XsdSchemaToken::Any, token, namespaceToken)) { + const XsdParticle::Ptr particle; + const XsdWildcard::Ptr wildcard = parseAny(particle); + openContent->setWildcard(wildcard); + } else { + parseUnknown(); + } + } + } + + tagValidator.finalize(); + + return openContent; +} + +XsdModelGroup::Ptr XsdSchemaParser::parseNamedGroup() +{ + const ElementNamespaceHandler namespaceHandler(XsdSchemaToken::Group, this); + + validateElement(XsdTagScope::NamedGroup); + + const XsdModelGroup::Ptr modelGroup(new XsdModelGroup()); + XsdModelGroup::Ptr group; + + QXmlName objectName; + if (hasAttribute(QString::fromLatin1("name"))) { + objectName = m_namePool->allocateQName(m_targetNamespace, readNameAttribute("group")); + } + + validateIdAttribute("group"); + + TagValidationHandler tagValidator(XsdTagScope::NamedGroup, this, m_namePool); + + XsdAnnotation::Ptr annotation; + + while (!atEnd()) { + readNext(); + + if (isEndElement()) + break; + + if (isStartElement()) { + const XsdSchemaToken::NodeName token = XsdSchemaToken::toToken(name()); + const XsdSchemaToken::NodeName namespaceToken = XsdSchemaToken::toToken(namespaceUri()); + + tagValidator.validate(token); + + if (isSchemaTag(XsdSchemaToken::Annotation, token, namespaceToken)) { + annotation = parseAnnotation(); + } else if (isSchemaTag(XsdSchemaToken::All, token, namespaceToken)) { + group = parseAll(modelGroup); + } else if (isSchemaTag(XsdSchemaToken::Choice, token, namespaceToken)) { + group = parseChoice(modelGroup); + } else if (isSchemaTag(XsdSchemaToken::Sequence, token, namespaceToken)) { + group = parseSequence(modelGroup); + } else { + parseUnknown(); + } + } + } + + tagValidator.finalize(); + + group->setName(objectName); + + if (annotation) + group->addAnnotation(annotation); + + return group; +} + +XsdTerm::Ptr XsdSchemaParser::parseReferredGroup(const XsdParticle::Ptr &particle) +{ + const ElementNamespaceHandler namespaceHandler(XsdSchemaToken::Group, this); + + validateElement(XsdTagScope::ReferredGroup); + + const XsdReference::Ptr reference(new XsdReference()); + reference->setType(XsdReference::ModelGroup); + reference->setSourceLocation(currentSourceLocation()); + + // parse attributes + if (!parseMinMaxConstraint(particle, "group")) { + return reference; + } + + const QString value = readQNameAttribute(QString::fromLatin1("ref"), "group"); + QXmlName referenceName; + convertName(value, NamespaceSupport::ElementName, referenceName); // translate qualified name into QXmlName + reference->setReferenceName(referenceName); + + validateIdAttribute("group"); + + TagValidationHandler tagValidator(XsdTagScope::ReferredGroup, this, m_namePool); + + while (!atEnd()) { + readNext(); + + if (isEndElement()) + break; + + if (isStartElement()) { + const XsdSchemaToken::NodeName token = XsdSchemaToken::toToken(name()); + const XsdSchemaToken::NodeName namespaceToken = XsdSchemaToken::toToken(namespaceUri()); + + tagValidator.validate(token); + + if (isSchemaTag(XsdSchemaToken::Annotation, token, namespaceToken)) { + const XsdAnnotation::Ptr annotation = parseAnnotation(); + reference->addAnnotation(annotation); + } else { + parseUnknown(); + } + } + } + + tagValidator.finalize(); + + return reference; +} + +XsdModelGroup::Ptr XsdSchemaParser::parseAll(const NamedSchemaComponent::Ptr &parent) +{ + const ElementNamespaceHandler namespaceHandler(XsdSchemaToken::All, this); + + validateElement(XsdTagScope::All); + + const XsdModelGroup::Ptr modelGroup(new XsdModelGroup()); + modelGroup->setCompositor(XsdModelGroup::AllCompositor); + + validateIdAttribute("all"); + + TagValidationHandler tagValidator(XsdTagScope::All, this, m_namePool); + + XsdParticle::List particles; + while (!atEnd()) { + readNext(); + + if (isEndElement()) + break; + + if (isStartElement()) { + const XsdSchemaToken::NodeName token = XsdSchemaToken::toToken(name()); + const XsdSchemaToken::NodeName namespaceToken = XsdSchemaToken::toToken(namespaceUri()); + + tagValidator.validate(token); + + if (isSchemaTag(XsdSchemaToken::Annotation, token, namespaceToken)) { + const XsdAnnotation::Ptr annotation = parseAnnotation(); + modelGroup->addAnnotation(annotation); + } else if (isSchemaTag(XsdSchemaToken::Element, token, namespaceToken)) { + const XsdParticle::Ptr particle(new XsdParticle()); + const XsdTerm::Ptr term = parseLocalElement(particle, parent); + particle->setTerm(term); + + if (particle->maximumOccursUnbounded() || particle->maximumOccurs() > 1) { + error(QtXmlPatterns::tr("%1 attribute of %2 element must be %3 or %4") + .arg(formatAttribute("maxOccurs")) + .arg(formatElement("all")) + .arg(formatData("0")) + .arg(formatData("1"))); + return modelGroup; + } + + particles.append(particle); + } else { + parseUnknown(); + } + } + } + + modelGroup->setParticles(particles); + + tagValidator.finalize(); + + return modelGroup; +} + +XsdModelGroup::Ptr XsdSchemaParser::parseLocalAll(const XsdParticle::Ptr &particle, const NamedSchemaComponent::Ptr &parent) +{ + const ElementNamespaceHandler namespaceHandler(XsdSchemaToken::All, this); + + validateElement(XsdTagScope::LocalAll); + + const XsdModelGroup::Ptr modelGroup(new XsdModelGroup()); + modelGroup->setCompositor(XsdModelGroup::AllCompositor); + + // parse attributes + if (!parseMinMaxConstraint(particle, "all")) { + return modelGroup; + } + if (particle->maximumOccursUnbounded() || particle->maximumOccurs() != 1) { + error(QtXmlPatterns::tr("%1 attribute of %2 element must have a value of %3") + .arg(formatAttribute("maxOccurs")) + .arg(formatElement("all")) + .arg(formatData("1"))); + return modelGroup; + } + if (particle->minimumOccurs() != 0 && particle->minimumOccurs() != 1) { + error(QtXmlPatterns::tr("%1 attribute of %2 element must have a value of %3 or %4") + .arg(formatAttribute("minOccurs")) + .arg(formatElement("all")) + .arg(formatData("0")) + .arg(formatData("1"))); + return modelGroup; + } + + validateIdAttribute("all"); + + TagValidationHandler tagValidator(XsdTagScope::LocalAll, this, m_namePool); + + XsdParticle::List particles; + while (!atEnd()) { + readNext(); + + if (isEndElement()) + break; + + if (isStartElement()) { + const XsdSchemaToken::NodeName token = XsdSchemaToken::toToken(name()); + const XsdSchemaToken::NodeName namespaceToken = XsdSchemaToken::toToken(namespaceUri()); + + tagValidator.validate(token); + + if (isSchemaTag(XsdSchemaToken::Annotation, token, namespaceToken)) { + const XsdAnnotation::Ptr annotation = parseAnnotation(); + modelGroup->addAnnotation(annotation); + } else if (isSchemaTag(XsdSchemaToken::Element, token, namespaceToken)) { + const XsdParticle::Ptr particle(new XsdParticle()); + const XsdTerm::Ptr term = parseLocalElement(particle, parent); + particle->setTerm(term); + + if (particle->maximumOccursUnbounded() || particle->maximumOccurs() > 1) { + error(QtXmlPatterns::tr("%1 attribute of %2 element must have a value of %3 or %4") + .arg(formatAttribute("maxOccurs")) + .arg(formatElement("all")) + .arg(formatData("0")) + .arg(formatData("1"))); + return modelGroup; + } + + particles.append(particle); + } else { + parseUnknown(); + } + } + } + + modelGroup->setParticles(particles); + + tagValidator.finalize(); + + return modelGroup; +} + +XsdModelGroup::Ptr XsdSchemaParser::parseChoice(const NamedSchemaComponent::Ptr &parent) +{ + const ElementNamespaceHandler namespaceHandler(XsdSchemaToken::Choice, this); + + validateElement(XsdTagScope::Choice); + + const XsdModelGroup::Ptr modelGroup(new XsdModelGroup()); + modelGroup->setCompositor(XsdModelGroup::ChoiceCompositor); + + validateIdAttribute("choice"); + + XsdParticle::List particles; + + TagValidationHandler tagValidator(XsdTagScope::Choice, this, m_namePool); + + while (!atEnd()) { + readNext(); + + if (isEndElement()) + break; + + if (isStartElement()) { + const XsdSchemaToken::NodeName token = XsdSchemaToken::toToken(name()); + const XsdSchemaToken::NodeName namespaceToken = XsdSchemaToken::toToken(namespaceUri()); + + tagValidator.validate(token); + + if (isSchemaTag(XsdSchemaToken::Annotation, token, namespaceToken)) { + const XsdAnnotation::Ptr annotation = parseAnnotation(); + modelGroup->addAnnotation(annotation); + } else if (isSchemaTag(XsdSchemaToken::Element, token, namespaceToken)) { + const XsdParticle::Ptr particle(new XsdParticle()); + const XsdTerm::Ptr term = parseLocalElement(particle, parent); + particle->setTerm(term); + particles.append(particle); + } else if (isSchemaTag(XsdSchemaToken::Group, token, namespaceToken)) { + const XsdParticle::Ptr particle(new XsdParticle()); + const XsdTerm::Ptr term = parseReferredGroup(particle); + m_schemaResolver->addAllGroupCheck(term); + particle->setTerm(term); + particles.append(particle); + } else if (isSchemaTag(XsdSchemaToken::Choice, token, namespaceToken)) { + const XsdParticle::Ptr particle(new XsdParticle()); + const XsdTerm::Ptr term = parseLocalChoice(particle, parent); + particle->setTerm(term); + particles.append(particle); + } else if (isSchemaTag(XsdSchemaToken::Sequence, token, namespaceToken)) { + const XsdParticle::Ptr particle(new XsdParticle()); + const XsdTerm::Ptr term = parseLocalSequence(particle, parent); + particle->setTerm(term); + particles.append(particle); + } else if (isSchemaTag(XsdSchemaToken::Any, token, namespaceToken)) { + const XsdParticle::Ptr particle(new XsdParticle()); + const XsdTerm::Ptr term = parseAny(particle); + particle->setTerm(term); + particles.append(particle); + } else { + parseUnknown(); + } + } + } + + modelGroup->setParticles(particles); + + tagValidator.finalize(); + + return modelGroup; +} + +XsdModelGroup::Ptr XsdSchemaParser::parseLocalChoice(const XsdParticle::Ptr &particle, const NamedSchemaComponent::Ptr &parent) +{ + const ElementNamespaceHandler namespaceHandler(XsdSchemaToken::Choice, this); + + validateElement(XsdTagScope::LocalChoice); + + const XsdModelGroup::Ptr modelGroup(new XsdModelGroup()); + modelGroup->setCompositor(XsdModelGroup::ChoiceCompositor); + + // parse attributes + if (!parseMinMaxConstraint(particle, "choice")) { + return modelGroup; + } + + validateIdAttribute("choice"); + + XsdParticle::List particles; + + TagValidationHandler tagValidator(XsdTagScope::LocalChoice, this, m_namePool); + + while (!atEnd()) { + readNext(); + + if (isEndElement()) + break; + + if (isStartElement()) { + const XsdSchemaToken::NodeName token = XsdSchemaToken::toToken(name()); + const XsdSchemaToken::NodeName namespaceToken = XsdSchemaToken::toToken(namespaceUri()); + + tagValidator.validate(token); + + if (isSchemaTag(XsdSchemaToken::Annotation, token, namespaceToken)) { + const XsdAnnotation::Ptr annotation = parseAnnotation(); + modelGroup->addAnnotation(annotation); + } else if (isSchemaTag(XsdSchemaToken::Element, token, namespaceToken)) { + const XsdParticle::Ptr particle(new XsdParticle()); + const XsdTerm::Ptr term = parseLocalElement(particle, parent); + particle->setTerm(term); + particles.append(particle); + } else if (isSchemaTag(XsdSchemaToken::Group, token, namespaceToken)) { + const XsdParticle::Ptr particle(new XsdParticle()); + const XsdTerm::Ptr term = parseReferredGroup(particle); + m_schemaResolver->addAllGroupCheck(term); + particle->setTerm(term); + particles.append(particle); + } else if (isSchemaTag(XsdSchemaToken::Choice, token, namespaceToken)) { + const XsdParticle::Ptr particle(new XsdParticle()); + const XsdTerm::Ptr term = parseLocalChoice(particle, parent); + particle->setTerm(term); + particles.append(particle); + } else if (isSchemaTag(XsdSchemaToken::Sequence, token, namespaceToken)) { + const XsdParticle::Ptr particle(new XsdParticle()); + const XsdTerm::Ptr term = parseLocalSequence(particle, parent); + particle->setTerm(term); + particles.append(particle); + } else if (isSchemaTag(XsdSchemaToken::Any, token, namespaceToken)) { + const XsdParticle::Ptr particle(new XsdParticle()); + const XsdTerm::Ptr term = parseAny(particle); + particle->setTerm(term); + particles.append(particle); + } else { + parseUnknown(); + } + } + } + + modelGroup->setParticles(particles); + + tagValidator.finalize(); + + return modelGroup; +} + +XsdModelGroup::Ptr XsdSchemaParser::parseSequence(const NamedSchemaComponent::Ptr &parent) +{ + const ElementNamespaceHandler namespaceHandler(XsdSchemaToken::Sequence, this); + + validateElement(XsdTagScope::Sequence); + + const XsdModelGroup::Ptr modelGroup(new XsdModelGroup()); + modelGroup->setCompositor(XsdModelGroup::SequenceCompositor); + + validateIdAttribute("sequence"); + + XsdParticle::List particles; + + TagValidationHandler tagValidator(XsdTagScope::Sequence, this, m_namePool); + + while (!atEnd()) { + readNext(); + + if (isEndElement()) + break; + + if (isStartElement()) { + const XsdSchemaToken::NodeName token = XsdSchemaToken::toToken(name()); + const XsdSchemaToken::NodeName namespaceToken = XsdSchemaToken::toToken(namespaceUri()); + + tagValidator.validate(token); + + if (isSchemaTag(XsdSchemaToken::Annotation, token, namespaceToken)) { + const XsdAnnotation::Ptr annotation = parseAnnotation(); + modelGroup->addAnnotation(annotation); + } else if (isSchemaTag(XsdSchemaToken::Element, token, namespaceToken)) { + const XsdParticle::Ptr particle(new XsdParticle()); + const XsdTerm::Ptr term = parseLocalElement(particle, parent); + particle->setTerm(term); + particles.append(particle); + } else if (isSchemaTag(XsdSchemaToken::Group, token, namespaceToken)) { + const XsdParticle::Ptr particle(new XsdParticle()); + const XsdTerm::Ptr term = parseReferredGroup(particle); + m_schemaResolver->addAllGroupCheck(term); + particle->setTerm(term); + particles.append(particle); + } else if (isSchemaTag(XsdSchemaToken::Choice, token, namespaceToken)) { + const XsdParticle::Ptr particle(new XsdParticle()); + const XsdTerm::Ptr term = parseLocalChoice(particle, parent); + particle->setTerm(term); + particles.append(particle); + } else if (isSchemaTag(XsdSchemaToken::Sequence, token, namespaceToken)) { + const XsdParticle::Ptr particle(new XsdParticle()); + const XsdTerm::Ptr term = parseLocalSequence(particle, parent); + particle->setTerm(term); + particles.append(particle); + } else if (isSchemaTag(XsdSchemaToken::Any, token, namespaceToken)) { + const XsdParticle::Ptr particle(new XsdParticle()); + const XsdTerm::Ptr term = parseAny(particle); + particle->setTerm(term); + particles.append(particle); + } else { + parseUnknown(); + } + } + } + + modelGroup->setParticles(particles); + + tagValidator.finalize(); + + return modelGroup; +} + +XsdModelGroup::Ptr XsdSchemaParser::parseLocalSequence(const XsdParticle::Ptr &particle, const NamedSchemaComponent::Ptr &parent) +{ + const ElementNamespaceHandler namespaceHandler(XsdSchemaToken::Sequence, this); + + validateElement(XsdTagScope::LocalSequence); + + const XsdModelGroup::Ptr modelGroup(new XsdModelGroup()); + modelGroup->setCompositor(XsdModelGroup::SequenceCompositor); + + // parse attributes + if (!parseMinMaxConstraint(particle, "sequence")) { + return modelGroup; + } + + validateIdAttribute("sequence"); + + XsdParticle::List particles; + + TagValidationHandler tagValidator(XsdTagScope::LocalSequence, this, m_namePool); + + while (!atEnd()) { + readNext(); + + if (isEndElement()) + break; + + if (isStartElement()) { + const XsdSchemaToken::NodeName token = XsdSchemaToken::toToken(name()); + const XsdSchemaToken::NodeName namespaceToken = XsdSchemaToken::toToken(namespaceUri()); + + tagValidator.validate(token); + + if (isSchemaTag(XsdSchemaToken::Annotation, token, namespaceToken)) { + const XsdAnnotation::Ptr annotation = parseAnnotation(); + modelGroup->addAnnotation(annotation); + } else if (isSchemaTag(XsdSchemaToken::Element, token, namespaceToken)) { + const XsdParticle::Ptr particle(new XsdParticle()); + const XsdTerm::Ptr term = parseLocalElement(particle, parent); + particle->setTerm(term); + particles.append(particle); + } else if (isSchemaTag(XsdSchemaToken::Group, token, namespaceToken)) { + const XsdParticle::Ptr particle(new XsdParticle()); + const XsdTerm::Ptr term = parseReferredGroup(particle); + m_schemaResolver->addAllGroupCheck(term); + particle->setTerm(term); + particles.append(particle); + } else if (isSchemaTag(XsdSchemaToken::Choice, token, namespaceToken)) { + const XsdParticle::Ptr particle(new XsdParticle()); + const XsdTerm::Ptr term = parseLocalChoice(particle, parent); + particle->setTerm(term); + particles.append(particle); + } else if (isSchemaTag(XsdSchemaToken::Sequence, token, namespaceToken)) { + const XsdParticle::Ptr particle(new XsdParticle()); + const XsdTerm::Ptr term = parseLocalSequence(particle, parent); + particle->setTerm(term); + particles.append(particle); + } else if (isSchemaTag(XsdSchemaToken::Any, token, namespaceToken)) { + const XsdParticle::Ptr particle(new XsdParticle()); + const XsdTerm::Ptr term = parseAny(particle); + particle->setTerm(term); + particles.append(particle); + } else { + parseUnknown(); + } + } + } + + modelGroup->setParticles(particles); + + tagValidator.finalize(); + + return modelGroup; +} + +XsdAttribute::Ptr XsdSchemaParser::parseGlobalAttribute() +{ + const ElementNamespaceHandler namespaceHandler(XsdSchemaToken::Attribute, this); + + validateElement(XsdTagScope::GlobalAttribute); + + const XsdAttribute::Ptr attribute(new XsdAttribute()); + attribute->setScope(XsdAttribute::Scope::Ptr(new XsdAttribute::Scope())); + attribute->scope()->setVariety(XsdAttribute::Scope::Global); + + if (hasAttribute(QString::fromLatin1("default")) && hasAttribute(QString::fromLatin1("fixed"))) { + error(QtXmlPatterns::tr("%1 element must not have %2 and %3 attribute together") + .arg(formatElement("attribute")) + .arg(formatAttribute("default")) + .arg(formatAttribute("fixed"))); + return attribute; + } + + // parse attributes + if (hasAttribute(QString::fromLatin1("default"))) { + const QString value = readAttribute(QString::fromLatin1("default")); + attribute->setValueConstraint(XsdAttribute::ValueConstraint::Ptr(new XsdAttribute::ValueConstraint())); + attribute->valueConstraint()->setVariety(XsdAttribute::ValueConstraint::Default); + attribute->valueConstraint()->setValue(value); + } else if (hasAttribute(QString::fromLatin1("fixed"))) { + const QString value = readAttribute(QString::fromLatin1("fixed")); + attribute->setValueConstraint(XsdAttribute::ValueConstraint::Ptr(new XsdAttribute::ValueConstraint())); + attribute->valueConstraint()->setVariety(XsdAttribute::ValueConstraint::Fixed); + attribute->valueConstraint()->setValue(value); + } + + const QXmlName objectName = m_namePool->allocateQName(m_targetNamespace, readNameAttribute("attribute")); + if ((objectName.namespaceURI() == StandardNamespaces::xsi) && + (m_namePool->stringForLocalName(objectName.localName()) != QString::fromLatin1("type")) && + (m_namePool->stringForLocalName(objectName.localName()) != QString::fromLatin1("nil")) && + (m_namePool->stringForLocalName(objectName.localName()) != QString::fromLatin1("schemaLocation")) && + (m_namePool->stringForLocalName(objectName.localName()) != QString::fromLatin1("noNamespaceSchemaLocation"))) { + + error(QtXmlPatterns::tr("content of %1 attribute of %2 element must not be from namespace %3") + .arg(formatAttribute("name")) + .arg(formatElement("attribute")) + .arg(formatURI(QLatin1String("http://www.w3.org/2001/XMLSchema-instance")))); + return attribute; + } + if (m_namePool->stringForLocalName(objectName.localName()) == QString::fromLatin1("xmlns")) { + error(QtXmlPatterns::tr("%1 attribute of %2 element must not be %3") + .arg(formatAttribute("name")) + .arg(formatElement("attribute")) + .arg(formatData("xmlns"))); + return attribute; + } + attribute->setName(objectName); + + bool hasTypeAttribute = false; + bool hasTypeSpecified = false; + + if (hasAttribute(QString::fromLatin1("type"))) { + hasTypeAttribute = true; + + const QString type = readQNameAttribute(QString::fromLatin1("type"), "attribute"); + QXmlName typeName; + convertName(type, NamespaceSupport::ElementName, typeName); // translate qualified name into QXmlName + m_schemaResolver->addAttributeType(attribute, typeName, currentSourceLocation()); // add to resolver + hasTypeSpecified = true; + } + + validateIdAttribute("attribute"); + + TagValidationHandler tagValidator(XsdTagScope::GlobalAttribute, this, m_namePool); + + while (!atEnd()) { + readNext(); + + if (isEndElement()) + break; + + if (isStartElement()) { + const XsdSchemaToken::NodeName token = XsdSchemaToken::toToken(name()); + const XsdSchemaToken::NodeName namespaceToken = XsdSchemaToken::toToken(namespaceUri()); + + tagValidator.validate(token); + + if (isSchemaTag(XsdSchemaToken::Annotation, token, namespaceToken)) { + const XsdAnnotation::Ptr annotation = parseAnnotation(); + attribute->addAnnotation(annotation); + } else if (isSchemaTag(XsdSchemaToken::SimpleType, token, namespaceToken)) { + if (hasTypeAttribute) { + error(QtXmlPatterns::tr("%1 element with %2 child element must not have a %3 attribute") + .arg(formatElement("attribute")) + .arg(formatElement("simpleType")) + .arg(formatAttribute("type"))); + break; + } + + const XsdSimpleType::Ptr type = parseLocalSimpleType(); + type->setContext(attribute); + attribute->setType(type); + hasTypeSpecified = true; + + // add it to list of anonymous types as well + addAnonymousType(type); + } else { + parseUnknown(); + } + } + } + + if (!hasTypeSpecified) { + attribute->setType(BuiltinTypes::xsAnySimpleType); // default value + return attribute; + } + + tagValidator.finalize(); + + return attribute; +} + +XsdAttributeUse::Ptr XsdSchemaParser::parseLocalAttribute(const NamedSchemaComponent::Ptr &parent) +{ + const ElementNamespaceHandler namespaceHandler(XsdSchemaToken::Attribute, this); + + validateElement(XsdTagScope::LocalAttribute); + + bool hasRefAttribute = false; + bool hasTypeAttribute = false; + bool hasTypeSpecified = false; + + XsdAttributeUse::Ptr attributeUse; + if (hasAttribute(QString::fromLatin1("ref"))) { + const XsdAttributeReference::Ptr reference = XsdAttributeReference::Ptr(new XsdAttributeReference()); + reference->setType(XsdAttributeReference::AttributeUse); + reference->setSourceLocation(currentSourceLocation()); + + attributeUse = reference; + hasRefAttribute = true; + } else { + attributeUse = XsdAttributeUse::Ptr(new XsdAttributeUse()); + } + + if (hasAttribute(QString::fromLatin1("default")) && hasAttribute(QString::fromLatin1("fixed"))) { + error(QtXmlPatterns::tr("%1 element must not have %2 and %3 attribute together") + .arg(formatElement("attribute")) + .arg(formatAttribute("default")) + .arg(formatAttribute("fixed"))); + return attributeUse; + } + + if (hasRefAttribute) { + if (hasAttribute(QString::fromLatin1("form"))) { + error(QtXmlPatterns::tr("%1 element must not have %2 and %3 attribute together") + .arg(formatElement("attribute")) + .arg(formatAttribute("ref")) + .arg(formatAttribute("form"))); + return attributeUse; + } + if (hasAttribute(QString::fromLatin1("name"))) { + error(QtXmlPatterns::tr("%1 element must not have %2 and %3 attribute together") + .arg(formatElement("attribute")) + .arg(formatAttribute("ref")) + .arg(formatAttribute("name"))); + return attributeUse; + } + if (hasAttribute(QString::fromLatin1("type"))) { + error(QtXmlPatterns::tr("%1 element must not have %2 and %3 attribute together") + .arg(formatElement("attribute")) + .arg(formatAttribute("ref")) + .arg(formatAttribute("type"))); + return attributeUse; + } + } + + // parse attributes + + // default, fixed and use are handled by both, attribute use and attribute reference + if (hasAttribute(QString::fromLatin1("default"))) { + const QString value = readAttribute(QString::fromLatin1("default")); + attributeUse->setValueConstraint(XsdAttributeUse::ValueConstraint::Ptr(new XsdAttributeUse::ValueConstraint())); + attributeUse->valueConstraint()->setVariety(XsdAttributeUse::ValueConstraint::Default); + attributeUse->valueConstraint()->setValue(value); + } else if (hasAttribute(QString::fromLatin1("fixed"))) { + const QString value = readAttribute(QString::fromLatin1("fixed")); + attributeUse->setValueConstraint(XsdAttributeUse::ValueConstraint::Ptr(new XsdAttributeUse::ValueConstraint())); + attributeUse->valueConstraint()->setVariety(XsdAttributeUse::ValueConstraint::Fixed); + attributeUse->valueConstraint()->setValue(value); + } + + if (hasAttribute(QString::fromLatin1("use"))) { + const QString value = readAttribute(QString::fromLatin1("use")); + if (value != QString::fromLatin1("optional") && + value != QString::fromLatin1("prohibited") && + value != QString::fromLatin1("required")) { + attributeContentError("use", "attribute", value); + return attributeUse; + } + + if (value == QString::fromLatin1("optional")) + attributeUse->setUseType(XsdAttributeUse::OptionalUse); + else if (value == QString::fromLatin1("prohibited")) + attributeUse->setUseType(XsdAttributeUse::ProhibitedUse); + else if (value == QString::fromLatin1("required")) + attributeUse->setUseType(XsdAttributeUse::RequiredUse); + + if (attributeUse->valueConstraint() && attributeUse->valueConstraint()->variety() == XsdAttributeUse::ValueConstraint::Default && value != QString::fromLatin1("optional")) { + error(QtXmlPatterns::tr("%1 attribute of %2 element must have the value %3 because the %4 attribute is set") + .arg(formatAttribute("use")) + .arg(formatElement("attribute")) + .arg(formatData("optional")) + .arg(formatElement("default"))); + return attributeUse; + } + } + + const XsdAttribute::Ptr attribute(new XsdAttribute()); + + attributeUse->setAttribute(attribute); + m_componentLocationHash.insert(attribute, currentSourceLocation()); + + attribute->setScope(XsdAttribute::Scope::Ptr(new XsdAttribute::Scope())); + attribute->scope()->setVariety(XsdAttribute::Scope::Local); + attribute->scope()->setParent(parent); + + // now make a difference between attribute reference and attribute use + if (hasRefAttribute) { + const QString reference = readQNameAttribute(QString::fromLatin1("ref"), "attribute"); + QXmlName referenceName; + convertName(reference, NamespaceSupport::ElementName, referenceName); // translate qualified name into QXmlName + + const XsdAttributeReference::Ptr attributeReference = attributeUse; + attributeReference->setReferenceName(referenceName); + } else { + if (hasAttribute(QString::fromLatin1("name"))) { + const QString attributeName = readNameAttribute("attribute"); + + QXmlName objectName; + if (hasAttribute(QString::fromLatin1("form"))) { + const QString value = readAttribute(QString::fromLatin1("form")); + if (value != QString::fromLatin1("qualified") && value != QString::fromLatin1("unqualified")) { + attributeContentError("form", "attribute", value); + return attributeUse; + } + + if (value == QString::fromLatin1("qualified")) { + objectName = m_namePool->allocateQName(m_targetNamespace, attributeName); + } else { + objectName = m_namePool->allocateQName(QString(), attributeName); + } + } else { + if (m_attributeFormDefault == QString::fromLatin1("qualified")) { + objectName = m_namePool->allocateQName(m_targetNamespace, attributeName); + } else { + objectName = m_namePool->allocateQName(QString(), attributeName); + } + } + + if ((objectName.namespaceURI() == StandardNamespaces::xsi) && + (m_namePool->stringForLocalName(objectName.localName()) != QString::fromLatin1("type")) && + (m_namePool->stringForLocalName(objectName.localName()) != QString::fromLatin1("nil")) && + (m_namePool->stringForLocalName(objectName.localName()) != QString::fromLatin1("schemaLocation")) && + (m_namePool->stringForLocalName(objectName.localName()) != QString::fromLatin1("noNamespaceSchemaLocation"))) { + + error(QtXmlPatterns::tr("content of %1 attribute of %2 element must not be from namespace %3") + .arg(formatAttribute("name")) + .arg(formatElement("attribute")) + .arg(formatURI(QLatin1String("http://www.w3.org/2001/XMLSchema-instance")))); + return attributeUse; + } + if (m_namePool->stringForLocalName(objectName.localName()) == QString::fromLatin1("xmlns")) { + error(QtXmlPatterns::tr("%1 attribute of %2 element must not be %3") + .arg(formatAttribute("name")) + .arg(formatElement("attribute")) + .arg(formatData("xmlns"))); + return attributeUse; + } + + attribute->setName(objectName); + } + + if (hasAttribute(QString::fromLatin1("type"))) { + hasTypeAttribute = true; + + const QString type = readQNameAttribute(QString::fromLatin1("type"), "attribute"); + QXmlName typeName; + convertName(type, NamespaceSupport::ElementName, typeName); // translate qualified name into QXmlName + m_schemaResolver->addAttributeType(attribute, typeName, currentSourceLocation()); // add to resolver + hasTypeSpecified = true; + } + + if (attributeUse->valueConstraint()) { + //TODO: check whether assigning the value constraint of the attribute use to the attribute is correct + if (!attribute->valueConstraint()) + attribute->setValueConstraint(XsdAttribute::ValueConstraint::Ptr(new XsdAttribute::ValueConstraint())); + + attribute->valueConstraint()->setVariety((XsdAttribute::ValueConstraint::Variety)attributeUse->valueConstraint()->variety()); + attribute->valueConstraint()->setValue(attributeUse->valueConstraint()->value()); + attribute->valueConstraint()->setLexicalForm(attributeUse->valueConstraint()->lexicalForm()); + } + } + + validateIdAttribute("attribute"); + + TagValidationHandler tagValidator(XsdTagScope::LocalAttribute, this, m_namePool); + + while (!atEnd()) { + readNext(); + + if (isEndElement()) + break; + + if (isStartElement()) { + const XsdSchemaToken::NodeName token = XsdSchemaToken::toToken(name()); + const XsdSchemaToken::NodeName namespaceToken = XsdSchemaToken::toToken(namespaceUri()); + + tagValidator.validate(token); + + if (isSchemaTag(XsdSchemaToken::Annotation, token, namespaceToken)) { + const XsdAnnotation::Ptr annotation = parseAnnotation(); + attribute->addAnnotation(annotation); + } else if (isSchemaTag(XsdSchemaToken::SimpleType, token, namespaceToken)) { + if (hasTypeAttribute) { + error(QtXmlPatterns::tr("%1 element with %2 child element must not have a %3 attribute") + .arg(formatElement("attribute")) + .arg(formatElement("simpleType")) + .arg(formatAttribute("type"))); + break; + } + if (hasRefAttribute) { + error(QtXmlPatterns::tr("%1 element with %2 child element must not have a %3 attribute") + .arg(formatElement("attribute")) + .arg(formatElement("simpleType")) + .arg(formatAttribute("ref"))); + break; + } + + const XsdSimpleType::Ptr type = parseLocalSimpleType(); + type->setContext(attribute); + attribute->setType(type); + hasTypeSpecified = true; + + // add it to list of anonymous types as well + addAnonymousType(type); + } else { + parseUnknown(); + } + } + } + + if (!hasTypeSpecified) { + attribute->setType(BuiltinTypes::xsAnySimpleType); // default value + } + + tagValidator.finalize(); + + return attributeUse; +} + +XsdAttributeGroup::Ptr XsdSchemaParser::parseNamedAttributeGroup() +{ + const ElementNamespaceHandler namespaceHandler(XsdSchemaToken::AttributeGroup, this); + + validateElement(XsdTagScope::NamedAttributeGroup); + + const XsdAttributeGroup::Ptr attributeGroup(new XsdAttributeGroup()); + + // parse attributes + const QXmlName objectName = m_namePool->allocateQName(m_targetNamespace, readNameAttribute("attributeGroup")); + attributeGroup->setName(objectName); + + validateIdAttribute("attributeGroup"); + + TagValidationHandler tagValidator(XsdTagScope::NamedAttributeGroup, this, m_namePool); + + while (!atEnd()) { + readNext(); + + if (isEndElement()) + break; + + if (isStartElement()) { + const XsdSchemaToken::NodeName token = XsdSchemaToken::toToken(name()); + const XsdSchemaToken::NodeName namespaceToken = XsdSchemaToken::toToken(namespaceUri()); + + tagValidator.validate(token); + + if (isSchemaTag(XsdSchemaToken::Annotation, token, namespaceToken)) { + const XsdAnnotation::Ptr annotation = parseAnnotation(); + attributeGroup->addAnnotation(annotation); + } else if (isSchemaTag(XsdSchemaToken::Attribute, token, namespaceToken)) { + const XsdAttributeUse::Ptr attributeUse = parseLocalAttribute(attributeGroup); + + if (attributeUse->useType() == XsdAttributeUse::ProhibitedUse) { + warning(QtXmlPatterns::tr("specifying use='prohibited' inside an attribute group has no effect")); + } else { + attributeGroup->addAttributeUse(attributeUse); + } + } else if (isSchemaTag(XsdSchemaToken::AttributeGroup, token, namespaceToken)) { + const XsdAttributeUse::Ptr attributeUse = parseReferredAttributeGroup(); + attributeGroup->addAttributeUse(attributeUse); + } else if (isSchemaTag(XsdSchemaToken::AnyAttribute, token, namespaceToken)) { + const XsdWildcard::Ptr wildcard = parseAnyAttribute(); + attributeGroup->setWildcard(wildcard); + } else { + parseUnknown(); + } + } + } + + tagValidator.finalize(); + + return attributeGroup; +} + +XsdAttributeUse::Ptr XsdSchemaParser::parseReferredAttributeGroup() +{ + const ElementNamespaceHandler namespaceHandler(XsdSchemaToken::AttributeGroup, this); + + validateElement(XsdTagScope::ReferredAttributeGroup); + + const XsdAttributeReference::Ptr attributeReference(new XsdAttributeReference()); + attributeReference->setType(XsdAttributeReference::AttributeGroup); + attributeReference->setSourceLocation(currentSourceLocation()); + + // parse attributes + const QString reference = readQNameAttribute(QString::fromLatin1("ref"), "attributeGroup"); + QXmlName referenceName; + convertName(reference, NamespaceSupport::ElementName, referenceName); // translate qualified name into QXmlName + attributeReference->setReferenceName(referenceName); + + validateIdAttribute("attributeGroup"); + + TagValidationHandler tagValidator(XsdTagScope::ReferredAttributeGroup, this, m_namePool); + + while (!atEnd()) { + readNext(); + + if (isEndElement()) + break; + + if (isStartElement()) { + const XsdSchemaToken::NodeName token = XsdSchemaToken::toToken(name()); + const XsdSchemaToken::NodeName namespaceToken = XsdSchemaToken::toToken(namespaceUri()); + + tagValidator.validate(token); + + if (isSchemaTag(XsdSchemaToken::Annotation, token, namespaceToken)) { + const XsdAnnotation::Ptr annotation = parseAnnotation(); + attributeReference->addAnnotation(annotation); + } else { + parseUnknown(); + } + } + } + + tagValidator.finalize(); + + return attributeReference; +} + +XsdElement::Ptr XsdSchemaParser::parseGlobalElement() +{ + const ElementNamespaceHandler namespaceHandler(XsdSchemaToken::Element, this); + + validateElement(XsdTagScope::GlobalElement); + + const XsdElement::Ptr element(new XsdElement()); + element->setScope(XsdElement::Scope::Ptr(new XsdElement::Scope())); + element->scope()->setVariety(XsdElement::Scope::Global); + + bool hasTypeAttribute = false; + bool hasTypeSpecified = false; + bool hasSubstitutionGroup = false; + + // parse attributes + const QXmlName objectName = m_namePool->allocateQName(m_targetNamespace, readNameAttribute("element")); + element->setName(objectName); + + if (hasAttribute(QString::fromLatin1("abstract"))) { + const QString abstract = readAttribute(QString::fromLatin1("abstract")); + + const Boolean::Ptr value = Boolean::fromLexical(abstract); + if (value->hasError()) { + attributeContentError("abstract", "element", abstract, BuiltinTypes::xsBoolean); + return element; + } + + element->setIsAbstract(value->as()->value()); + } else { + element->setIsAbstract(false); // the default value + } + + if (hasAttribute(QString::fromLatin1("default")) && hasAttribute(QString::fromLatin1("fixed"))) { + error(QtXmlPatterns::tr("%1 element must not have %2 and %3 attribute together") + .arg(formatElement("element")) + .arg(formatAttribute("default")) + .arg(formatAttribute("fixed"))); + return element; + } + + if (hasAttribute(QString::fromLatin1("default"))) { + const QString value = readAttribute(QString::fromLatin1("default")); + element->setValueConstraint(XsdElement::ValueConstraint::Ptr(new XsdElement::ValueConstraint())); + element->valueConstraint()->setVariety(XsdElement::ValueConstraint::Default); + element->valueConstraint()->setValue(value); + } else if (hasAttribute(QString::fromLatin1("fixed"))) { + const QString value = readAttribute(QString::fromLatin1("fixed")); + element->setValueConstraint(XsdElement::ValueConstraint::Ptr(new XsdElement::ValueConstraint())); + element->valueConstraint()->setVariety(XsdElement::ValueConstraint::Fixed); + element->valueConstraint()->setValue(value); + } + + element->setDisallowedSubstitutions(readBlockingConstraintAttribute(NamedSchemaComponent::ExtensionConstraint | NamedSchemaComponent::RestrictionConstraint | NamedSchemaComponent::SubstitutionConstraint, "element")); + element->setSubstitutionGroupExclusions(readDerivationConstraintAttribute(SchemaType::ExtensionConstraint | SchemaType::RestrictionConstraint, "element")); + + if (hasAttribute(QString::fromLatin1("nillable"))) { + const QString nillable = readAttribute(QString::fromLatin1("nillable")); + + const Boolean::Ptr value = Boolean::fromLexical(nillable); + if (value->hasError()) { + attributeContentError("nillable", "element", nillable, BuiltinTypes::xsBoolean); + return element; + } + + element->setIsNillable(value->as()->value()); + } else { + element->setIsNillable(false); // the default value + } + + if (hasAttribute(QString::fromLatin1("type"))) { + const QString type = readQNameAttribute(QString::fromLatin1("type"), "element"); + QXmlName typeName; + convertName(type, NamespaceSupport::ElementName, typeName); // translate qualified name into QXmlName + m_schemaResolver->addElementType(element, typeName, currentSourceLocation()); // add to resolver + + hasTypeAttribute = true; + hasTypeSpecified = true; + } + + if (hasAttribute(QString::fromLatin1("substitutionGroup"))) { + QList elementNames; + + const QString value = readAttribute(QString::fromLatin1("substitutionGroup")); + const QStringList substitutionGroups = value.split(QLatin1Char(' '), QString::SkipEmptyParts); + if (substitutionGroups.isEmpty()) { + attributeContentError("substitutionGroup", "element", value, BuiltinTypes::xsQName); + return element; + } + + for (int i = 0; i < substitutionGroups.count(); ++i) { + const QString value = substitutionGroups.at(i).simplified(); + if (!XPathHelper::isQName(value)) { + attributeContentError("substitutionGroup", "element", value, BuiltinTypes::xsQName); + return element; + } + + QXmlName elementName; + convertName(value, NamespaceSupport::ElementName, elementName); // translate qualified name into QXmlName + elementNames.append(elementName); + } + + m_schemaResolver->addSubstitutionGroupAffiliation(element, elementNames, currentSourceLocation()); // add to resolver + + hasSubstitutionGroup = true; + } + + validateIdAttribute("element"); + + XsdAlternative::List alternatives; + + TagValidationHandler tagValidator(XsdTagScope::GlobalElement, this, m_namePool); + + while (!atEnd()) { + readNext(); + + if (isEndElement()) + break; + + if (isStartElement()) { + const XsdSchemaToken::NodeName token = XsdSchemaToken::toToken(name()); + const XsdSchemaToken::NodeName namespaceToken = XsdSchemaToken::toToken(namespaceUri()); + + tagValidator.validate(token); + + if (isSchemaTag(XsdSchemaToken::Annotation, token, namespaceToken)) { + const XsdAnnotation::Ptr annotation = parseAnnotation(); + element->addAnnotation(annotation); + } else if (isSchemaTag(XsdSchemaToken::SimpleType, token, namespaceToken)) { + if (hasTypeAttribute) { + error(QtXmlPatterns::tr("%1 element with %2 child element must not have a %3 attribute") + .arg(formatElement("element")) + .arg(formatElement("simpleType")) + .arg(formatAttribute("type"))); + return element; + } + + const XsdSimpleType::Ptr type = parseLocalSimpleType(); + type->setContext(element); + element->setType(type); + + // add it to list of anonymous types as well + addAnonymousType(type); + + hasTypeSpecified = true; + } else if (isSchemaTag(XsdSchemaToken::ComplexType, token, namespaceToken)) { + if (hasTypeAttribute) { + error(QtXmlPatterns::tr("%1 element with %2 child element must not have a %3 attribute") + .arg(formatElement("element")) + .arg(formatElement("complexType")) + .arg(formatAttribute("type"))); + return element; + } + + const XsdComplexType::Ptr type = parseLocalComplexType(); + type->setContext(element); + element->setType(type); + + // add it to list of anonymous types as well + addAnonymousType(type); + + hasTypeSpecified = true; + } else if (isSchemaTag(XsdSchemaToken::Alternative, token, namespaceToken)) { + const XsdAlternative::Ptr alternative = parseAlternative(); + alternatives.append(alternative); + } else if (isSchemaTag(XsdSchemaToken::Unique, token, namespaceToken)) { + const XsdIdentityConstraint::Ptr constraint = parseUnique(); + element->addIdentityConstraint(constraint); + } else if (isSchemaTag(XsdSchemaToken::Key, token, namespaceToken)) { + const XsdIdentityConstraint::Ptr constraint = parseKey(); + element->addIdentityConstraint(constraint); + } else if (isSchemaTag(XsdSchemaToken::Keyref, token, namespaceToken)) { + const XsdIdentityConstraint::Ptr constraint = parseKeyRef(element); + element->addIdentityConstraint(constraint); + } else { + parseUnknown(); + } + } + } + + tagValidator.finalize(); + + if (!hasTypeSpecified) { + if (hasSubstitutionGroup) + m_schemaResolver->addSubstitutionGroupType(element); + else + element->setType(BuiltinTypes::xsAnyType); + } + + if (!alternatives.isEmpty()) { + element->setTypeTable(XsdElement::TypeTable::Ptr(new XsdElement::TypeTable())); + + for (int i = 0; i < alternatives.count(); ++i) { + if (alternatives.at(i)->test()) + element->typeTable()->addAlternative(alternatives.at(i)); + + if (i == (alternatives.count() - 1)) { // the final one + if (!alternatives.at(i)->test()) { + element->typeTable()->setDefaultTypeDefinition(alternatives.at(i)); + } else { + const XsdAlternative::Ptr alternative(new XsdAlternative()); + if (element->type()) + alternative->setType(element->type()); + else + m_schemaResolver->addAlternativeType(alternative, element); // add to resolver + + element->typeTable()->setDefaultTypeDefinition(alternative); + } + } + } + } + + return element; +} + +XsdTerm::Ptr XsdSchemaParser::parseLocalElement(const XsdParticle::Ptr &particle, const NamedSchemaComponent::Ptr &parent) +{ + const ElementNamespaceHandler namespaceHandler(XsdSchemaToken::Element, this); + + validateElement(XsdTagScope::LocalElement); + + bool hasRefAttribute = false; + bool hasTypeAttribute = false; + bool hasTypeSpecified = false; + + XsdTerm::Ptr term; + XsdElement::Ptr element; + if (hasAttribute(QString::fromLatin1("ref"))) { + term = XsdReference::Ptr(new XsdReference()); + hasRefAttribute = true; + } else { + term = XsdElement::Ptr(new XsdElement()); + element = term; + } + + if (hasRefAttribute) { + if (hasAttribute(QString::fromLatin1("name"))) { + error(QtXmlPatterns::tr("%1 element must not have %2 and %3 attribute together") + .arg(formatElement("element")) + .arg(formatAttribute("ref")) + .arg(formatAttribute("name"))); + return term; + } else if (hasAttribute(QString::fromLatin1("block"))) { + error(QtXmlPatterns::tr("%1 element must not have %2 and %3 attribute together") + .arg(formatElement("element")) + .arg(formatAttribute("ref")) + .arg(formatAttribute("block"))); + return term; + } else if (hasAttribute(QString::fromLatin1("nillable"))) { + error(QtXmlPatterns::tr("%1 element must not have %2 and %3 attribute together") + .arg(formatElement("element")) + .arg(formatAttribute("ref")) + .arg(formatAttribute("nillable"))); + return term; + } else if (hasAttribute(QString::fromLatin1("default"))) { + error(QtXmlPatterns::tr("%1 element must not have %2 and %3 attribute together") + .arg(formatElement("element")) + .arg(formatAttribute("ref")) + .arg(formatAttribute("default"))); + return term; + } else if (hasAttribute(QString::fromLatin1("fixed"))) { + error(QtXmlPatterns::tr("%1 element must not have %2 and %3 attribute together") + .arg(formatElement("element")) + .arg(formatAttribute("ref")) + .arg(formatAttribute("fixed"))); + return term; + } else if (hasAttribute(QString::fromLatin1("form"))) { + error(QtXmlPatterns::tr("%1 element must not have %2 and %3 attribute together") + .arg(formatElement("element")) + .arg(formatAttribute("ref")) + .arg(formatAttribute("form"))); + return term; + } else if (hasAttribute(QString::fromLatin1("type"))) { + error(QtXmlPatterns::tr("%1 element must not have %2 and %3 attribute together") + .arg(formatElement("element")) + .arg(formatAttribute("ref")) + .arg(formatAttribute("type"))); + return term; + } + } + + // parse attributes + if (!parseMinMaxConstraint(particle, "element")) { + return element; + } + + if (!hasAttribute(QString::fromLatin1("name")) && !hasAttribute(QString::fromLatin1("ref"))) { + error(QtXmlPatterns::tr("%1 element must have either %2 or %3 attribute") + .arg(formatElement("element")) + .arg(formatAttribute("name")) + .arg(formatAttribute("ref"))); + return element; + } + + if (hasRefAttribute) { + const QString ref = readQNameAttribute(QString::fromLatin1("ref"), "element"); + QXmlName referenceName; + convertName(ref, NamespaceSupport::ElementName, referenceName); // translate qualified name into QXmlName + + const XsdReference::Ptr reference = term; + reference->setReferenceName(referenceName); + reference->setType(XsdReference::Element); + reference->setSourceLocation(currentSourceLocation()); + } else { + element->setScope(XsdElement::Scope::Ptr(new XsdElement::Scope())); + element->scope()->setVariety(XsdElement::Scope::Local); + element->scope()->setParent(parent); + + if (hasAttribute(QString::fromLatin1("name"))) { + const QString elementName = readNameAttribute("element"); + + QXmlName objectName; + if (hasAttribute(QString::fromLatin1("form"))) { + const QString value = readAttribute(QString::fromLatin1("form")); + if (value != QString::fromLatin1("qualified") && value != QString::fromLatin1("unqualified")) { + attributeContentError("form", "element", value); + return element; + } + + if (value == QString::fromLatin1("qualified")) { + objectName = m_namePool->allocateQName(m_targetNamespace, elementName); + } else { + objectName = m_namePool->allocateQName(QString(), elementName); + } + } else { + if (m_elementFormDefault == QString::fromLatin1("qualified")) { + objectName = m_namePool->allocateQName(m_targetNamespace, elementName); + } else { + objectName = m_namePool->allocateQName(QString(), elementName); + } + } + + element->setName(objectName); + } + + if (hasAttribute(QString::fromLatin1("nillable"))) { + const QString nillable = readAttribute(QString::fromLatin1("nillable")); + + const Boolean::Ptr value = Boolean::fromLexical(nillable); + if (value->hasError()) { + attributeContentError("nillable", "element", nillable, BuiltinTypes::xsBoolean); + return term; + } + + element->setIsNillable(value->as()->value()); + } else { + element->setIsNillable(false); // the default value + } + + if (hasAttribute(QString::fromLatin1("default")) && hasAttribute(QString::fromLatin1("fixed"))) { + error(QtXmlPatterns::tr("%1 element must not have %2 and %3 attribute together") + .arg(formatElement("element")) + .arg(formatAttribute("default")) + .arg(formatAttribute("fixed"))); + return element; + } + + if (hasAttribute(QString::fromLatin1("default"))) { + const QString value = readAttribute(QString::fromLatin1("default")); + element->setValueConstraint(XsdElement::ValueConstraint::Ptr(new XsdElement::ValueConstraint())); + element->valueConstraint()->setVariety(XsdElement::ValueConstraint::Default); + element->valueConstraint()->setValue(value); + } else if (hasAttribute(QString::fromLatin1("fixed"))) { + const QString value = readAttribute(QString::fromLatin1("fixed")); + element->setValueConstraint(XsdElement::ValueConstraint::Ptr(new XsdElement::ValueConstraint())); + element->valueConstraint()->setVariety(XsdElement::ValueConstraint::Fixed); + element->valueConstraint()->setValue(value); + } + + if (hasAttribute(QString::fromLatin1("type"))) { + const QString type = readQNameAttribute(QString::fromLatin1("type"), "element"); + QXmlName typeName; + convertName(type, NamespaceSupport::ElementName, typeName); // translate qualified name into QXmlName + m_schemaResolver->addElementType(element, typeName, currentSourceLocation()); // add to resolver + + hasTypeAttribute = true; + hasTypeSpecified = true; + } + + element->setDisallowedSubstitutions(readBlockingConstraintAttribute(NamedSchemaComponent::ExtensionConstraint | NamedSchemaComponent::RestrictionConstraint | NamedSchemaComponent::SubstitutionConstraint, "element")); + } + + validateIdAttribute("element"); + + XsdAlternative::List alternatives; + + TagValidationHandler tagValidator(XsdTagScope::LocalElement, this, m_namePool); + + while (!atEnd()) { + readNext(); + + if (isEndElement()) + break; + + if (isStartElement()) { + const XsdSchemaToken::NodeName token = XsdSchemaToken::toToken(name()); + const XsdSchemaToken::NodeName namespaceToken = XsdSchemaToken::toToken(namespaceUri()); + + tagValidator.validate(token); + + if (isSchemaTag(XsdSchemaToken::Annotation, token, namespaceToken)) { + const XsdAnnotation::Ptr annotation = parseAnnotation(); + element->addAnnotation(annotation); + } else if (isSchemaTag(XsdSchemaToken::SimpleType, token, namespaceToken)) { + if (hasRefAttribute) { + error(QtXmlPatterns::tr("%1 element with %2 child element must not have a %3 attribute") + .arg(formatElement("element")) + .arg(formatElement("simpleType")) + .arg(formatAttribute("ref"))); + return term; + } else if (hasTypeAttribute) { + error(QtXmlPatterns::tr("%1 element with %2 child element must not have a %3 attribute") + .arg(formatElement("element")) + .arg(formatElement("simpleType")) + .arg(formatAttribute("type"))); + return term; + } + + const XsdSimpleType::Ptr type = parseLocalSimpleType(); + type->setContext(element); + element->setType(type); + + // add it to list of anonymous types as well + addAnonymousType(type); + + hasTypeSpecified = true; + } else if (isSchemaTag(XsdSchemaToken::ComplexType, token, namespaceToken)) { + if (hasRefAttribute) { + error(QtXmlPatterns::tr("%1 element with %2 child element must not have a %3 attribute") + .arg(formatElement("element")) + .arg(formatElement("complexType")) + .arg(formatAttribute("ref"))); + return term; + } else if (hasTypeAttribute) { + error(QtXmlPatterns::tr("%1 element with %2 child element must not have a %3 attribute") + .arg(formatElement("element")) + .arg(formatElement("complexType")) + .arg(formatAttribute("type"))); + return term; + } + + const XsdComplexType::Ptr type = parseLocalComplexType(); + type->setContext(element); + element->setType(type); + + // add it to list of anonymous types as well + addAnonymousType(type); + + hasTypeSpecified = true; + } else if (isSchemaTag(XsdSchemaToken::Alternative, token, namespaceToken)) { + if (hasRefAttribute) { + error(QtXmlPatterns::tr("%1 element with %2 child element must not have a %3 attribute") + .arg(formatElement("element")) + .arg(formatElement("alternative")) + .arg(formatAttribute("ref"))); + return term; + } + + const XsdAlternative::Ptr alternative = parseAlternative(); + alternatives.append(alternative); + } else if (isSchemaTag(XsdSchemaToken::Unique, token, namespaceToken)) { + if (hasRefAttribute) { + error(QtXmlPatterns::tr("%1 element with %2 child element must not have a %3 attribute") + .arg(formatElement("element")) + .arg(formatElement("unique")) + .arg(formatAttribute("ref"))); + return term; + } + + const XsdIdentityConstraint::Ptr constraint = parseUnique(); + element->addIdentityConstraint(constraint); + } else if (isSchemaTag(XsdSchemaToken::Key, token, namespaceToken)) { + if (hasRefAttribute) { + error(QtXmlPatterns::tr("%1 element with %2 child element must not have a %3 attribute") + .arg(formatElement("element")) + .arg(formatElement("key")) + .arg(formatAttribute("ref"))); + return term; + } + + const XsdIdentityConstraint::Ptr constraint = parseKey(); + element->addIdentityConstraint(constraint); + } else if (isSchemaTag(XsdSchemaToken::Keyref, token, namespaceToken)) { + if (hasRefAttribute) { + error(QtXmlPatterns::tr("%1 element with %2 child element must not have a %3 attribute") + .arg(formatElement("element")) + .arg(formatElement("keyref")) + .arg(formatAttribute("ref"))); + return term; + } + + const XsdIdentityConstraint::Ptr constraint = parseKeyRef(element); + element->addIdentityConstraint(constraint); + } else { + parseUnknown(); + } + } + } + + tagValidator.finalize(); + + if (!hasTypeSpecified && !hasRefAttribute) + element->setType(BuiltinTypes::xsAnyType); + + if (!hasRefAttribute && !alternatives.isEmpty()) { + element->setTypeTable(XsdElement::TypeTable::Ptr(new XsdElement::TypeTable())); + + for (int i = 0; i < alternatives.count(); ++i) { + if (alternatives.at(i)->test()) + element->typeTable()->addAlternative(alternatives.at(i)); + + if (i == (alternatives.count() - 1)) { // the final one + if (!alternatives.at(i)->test()) { + element->typeTable()->setDefaultTypeDefinition(alternatives.at(i)); + } else { + const XsdAlternative::Ptr alternative(new XsdAlternative()); + if (element->type()) + alternative->setType(element->type()); + else + m_schemaResolver->addAlternativeType(alternative, element); // add to resolver + + element->typeTable()->setDefaultTypeDefinition(alternative); + } + } + } + } + + return term; +} + +XsdIdentityConstraint::Ptr XsdSchemaParser::parseUnique() +{ + const ElementNamespaceHandler namespaceHandler(XsdSchemaToken::Unique, this); + + validateElement(XsdTagScope::Unique); + + const XsdIdentityConstraint::Ptr constraint(new XsdIdentityConstraint()); + constraint->setCategory(XsdIdentityConstraint::Unique); + + // parse attributes + const QXmlName objectName = m_namePool->allocateQName(m_targetNamespace, readNameAttribute("unique")); + constraint->setName(objectName); + + validateIdAttribute("unique"); + + TagValidationHandler tagValidator(XsdTagScope::Unique, this, m_namePool); + + while (!atEnd()) { + readNext(); + + if (isEndElement()) + break; + + if (isStartElement()) { + const XsdSchemaToken::NodeName token = XsdSchemaToken::toToken(name()); + const XsdSchemaToken::NodeName namespaceToken = XsdSchemaToken::toToken(namespaceUri()); + + tagValidator.validate(token); + + if (isSchemaTag(XsdSchemaToken::Annotation, token, namespaceToken)) { + const XsdAnnotation::Ptr annotation = parseAnnotation(); + constraint->addAnnotation(annotation); + } else if (isSchemaTag(XsdSchemaToken::Selector, token, namespaceToken)) { + parseSelector(constraint); + } else if (isSchemaTag(XsdSchemaToken::Field, token, namespaceToken)) { + parseField(constraint); + } else { + parseUnknown(); + } + } + } + + // add constraint to schema for further checking + addIdentityConstraint(constraint); + + tagValidator.finalize(); + + return constraint; +} + +XsdIdentityConstraint::Ptr XsdSchemaParser::parseKey() +{ + const ElementNamespaceHandler namespaceHandler(XsdSchemaToken::Key, this); + + validateElement(XsdTagScope::Key); + + const XsdIdentityConstraint::Ptr constraint(new XsdIdentityConstraint()); + constraint->setCategory(XsdIdentityConstraint::Key); + + // parse attributes + const QXmlName objectName = m_namePool->allocateQName(m_targetNamespace, readNameAttribute("key")); + constraint->setName(objectName); + + validateIdAttribute("key"); + + TagValidationHandler tagValidator(XsdTagScope::Key, this, m_namePool); + + while (!atEnd()) { + readNext(); + + if (isEndElement()) + break; + + if (isStartElement()) { + const XsdSchemaToken::NodeName token = XsdSchemaToken::toToken(name()); + const XsdSchemaToken::NodeName namespaceToken = XsdSchemaToken::toToken(namespaceUri()); + + tagValidator.validate(token); + + if (isSchemaTag(XsdSchemaToken::Annotation, token, namespaceToken)) { + const XsdAnnotation::Ptr annotation = parseAnnotation(); + constraint->addAnnotation(annotation); + } else if (isSchemaTag(XsdSchemaToken::Selector, token, namespaceToken)) { + parseSelector(constraint); + } else if (isSchemaTag(XsdSchemaToken::Field, token, namespaceToken)) { + parseField(constraint); + } else { + parseUnknown(); + } + } + } + + // add constraint to schema for further checking + addIdentityConstraint(constraint); + + tagValidator.finalize(); + + return constraint; +} + +XsdIdentityConstraint::Ptr XsdSchemaParser::parseKeyRef(const XsdElement::Ptr &element) +{ + const ElementNamespaceHandler namespaceHandler(XsdSchemaToken::Keyref, this); + + validateElement(XsdTagScope::KeyRef); + + const XsdIdentityConstraint::Ptr constraint(new XsdIdentityConstraint()); + constraint->setCategory(XsdIdentityConstraint::KeyReference); + + // parse attributes + const QXmlName objectName = m_namePool->allocateQName(m_targetNamespace, readNameAttribute("keyref")); + constraint->setName(objectName); + + const QString refer = readQNameAttribute(QString::fromLatin1("refer"), "keyref"); + QXmlName referenceName; + convertName(refer, NamespaceSupport::ElementName, referenceName); // translate qualified name into QXmlName + m_schemaResolver->addKeyReference(element, constraint, referenceName, currentSourceLocation()); // add to resolver + + validateIdAttribute("keyref"); + + TagValidationHandler tagValidator(XsdTagScope::KeyRef, this, m_namePool); + + while (!atEnd()) { + readNext(); + + if (isEndElement()) + break; + + if (isStartElement()) { + const XsdSchemaToken::NodeName token = XsdSchemaToken::toToken(name()); + const XsdSchemaToken::NodeName namespaceToken = XsdSchemaToken::toToken(namespaceUri()); + + tagValidator.validate(token); + + if (isSchemaTag(XsdSchemaToken::Annotation, token, namespaceToken)) { + const XsdAnnotation::Ptr annotation = parseAnnotation(); + constraint->addAnnotation(annotation); + } else if (isSchemaTag(XsdSchemaToken::Selector, token, namespaceToken)) { + parseSelector(constraint); + } else if (isSchemaTag(XsdSchemaToken::Field, token, namespaceToken)) { + parseField(constraint); + } else { + parseUnknown(); + } + } + } + + // add constraint to schema for further checking + addIdentityConstraint(constraint); + + tagValidator.finalize(); + + return constraint; +} + +void XsdSchemaParser::parseSelector(const XsdIdentityConstraint::Ptr &ptr) +{ + const ElementNamespaceHandler namespaceHandler(XsdSchemaToken::Selector, this); + + validateElement(XsdTagScope::Selector); + + // parse attributes + const XsdXPathExpression::Ptr expression = readXPathExpression("selector"); + + const QString xpath = readXPathAttribute(QString::fromLatin1("xpath"), XPathSelector, "selector"); + expression->setExpression(xpath); + + ptr->setSelector(expression); + + validateIdAttribute("selector"); + + TagValidationHandler tagValidator(XsdTagScope::Selector, this, m_namePool); + + while (!atEnd()) { + readNext(); + + if (isEndElement()) + break; + + if (isStartElement()) { + const XsdSchemaToken::NodeName token = XsdSchemaToken::toToken(name()); + const XsdSchemaToken::NodeName namespaceToken = XsdSchemaToken::toToken(namespaceUri()); + + tagValidator.validate(token); + + if (isSchemaTag(XsdSchemaToken::Annotation, token, namespaceToken)) { + const XsdAnnotation::Ptr annotation = parseAnnotation(); + expression->addAnnotation(annotation); + } else { + parseUnknown(); + } + } + } + + tagValidator.finalize(); +} + +void XsdSchemaParser::parseField(const XsdIdentityConstraint::Ptr &ptr) +{ + const ElementNamespaceHandler namespaceHandler(XsdSchemaToken::Field, this); + + validateElement(XsdTagScope::Field); + + // parse attributes + const XsdXPathExpression::Ptr expression = readXPathExpression("field"); + + const QString xpath = readXPathAttribute(QString::fromLatin1("xpath"), XPathField, "field"); + expression->setExpression(xpath); + + ptr->addField(expression); + + validateIdAttribute("field"); + + TagValidationHandler tagValidator(XsdTagScope::Field, this, m_namePool); + + while (!atEnd()) { + readNext(); + + if (isEndElement()) + break; + + if (isStartElement()) { + const XsdSchemaToken::NodeName token = XsdSchemaToken::toToken(name()); + const XsdSchemaToken::NodeName namespaceToken = XsdSchemaToken::toToken(namespaceUri()); + + tagValidator.validate(token); + + if (isSchemaTag(XsdSchemaToken::Annotation, token, namespaceToken)) { + const XsdAnnotation::Ptr annotation = parseAnnotation(); + expression->addAnnotation(annotation); + } else { + parseUnknown(); + } + } + } + + tagValidator.finalize(); +} + +XsdAlternative::Ptr XsdSchemaParser::parseAlternative() +{ + const ElementNamespaceHandler namespaceHandler(XsdSchemaToken::Alternative, this); + + validateElement(XsdTagScope::Alternative); + + const XsdAlternative::Ptr alternative(new XsdAlternative()); + + bool hasTypeSpecified = false; + + if (hasAttribute(QString::fromLatin1("test"))) { + const XsdXPathExpression::Ptr expression = readXPathExpression("alternative"); + + const QString test = readXPathAttribute(QString::fromLatin1("test"), XPath20, "alternative"); + expression->setExpression(test); + + alternative->setTest(expression); + } + + if (hasAttribute(QString::fromLatin1("type"))) { + const QString type = readQNameAttribute(QString::fromLatin1("type"), "alternative"); + QXmlName typeName; + convertName(type, NamespaceSupport::ElementName, typeName); // translate qualified name into QXmlName + m_schemaResolver->addAlternativeType(alternative, typeName, currentSourceLocation()); // add to resolver + + hasTypeSpecified = true; + } + + validateIdAttribute("alternative"); + + TagValidationHandler tagValidator(XsdTagScope::Alternative, this, m_namePool); + + while (!atEnd()) { + readNext(); + + if (isEndElement()) + break; + + if (isStartElement()) { + const XsdSchemaToken::NodeName token = XsdSchemaToken::toToken(name()); + const XsdSchemaToken::NodeName namespaceToken = XsdSchemaToken::toToken(namespaceUri()); + + tagValidator.validate(token); + + if (isSchemaTag(XsdSchemaToken::Annotation, token, namespaceToken)) { + const XsdAnnotation::Ptr annotation = parseAnnotation(); + alternative->addAnnotation(annotation); + } else if (isSchemaTag(XsdSchemaToken::SimpleType, token, namespaceToken)) { + const XsdSimpleType::Ptr type = parseLocalSimpleType(); + alternative->setType(type); + + // add it to list of anonymous types as well + addAnonymousType(type); + + hasTypeSpecified = true; + } else if (isSchemaTag(XsdSchemaToken::ComplexType, token, namespaceToken)) { + const XsdComplexType::Ptr type = parseLocalComplexType(); + alternative->setType(type); + + // add it to list of anonymous types as well + addAnonymousType(type); + + hasTypeSpecified = true; + } else { + parseUnknown(); + } + } + } + + tagValidator.finalize(); + + if (!hasTypeSpecified) { + error(QtXmlPatterns::tr("%1 element must have either %2 attribute or %3 or %4 as child element") + .arg(formatElement("alternative")) + .arg(formatAttribute("type")) + .arg(formatElement("simpleType")) + .arg(formatElement("complexType"))); + return alternative; + } + + return alternative; +} + +XsdNotation::Ptr XsdSchemaParser::parseNotation() +{ + const ElementNamespaceHandler namespaceHandler(XsdSchemaToken::Notation, this); + + validateElement(XsdTagScope::Notation); + + const XsdNotation::Ptr notation(new XsdNotation()); + + // parse attributes + const QXmlName objectName = m_namePool->allocateQName(m_targetNamespace, readNameAttribute("notation")); + notation->setName(objectName); + + bool hasOptionalAttribute = false; + + if (hasAttribute(QString::fromLatin1("public"))) { + const QString value = readAttribute(QString::fromLatin1("public")); + if (!value.isEmpty()) { + const DerivedString::Ptr publicId = DerivedString::fromLexical(m_namePool, value); + if (publicId->hasError()) { + attributeContentError("public", "notation", value, BuiltinTypes::xsToken); + return notation; + } + notation->setPublicId(publicId); + } + + hasOptionalAttribute = true; + } + + if (hasAttribute(QString::fromLatin1("system"))) { + const QString value = readAttribute(QString::fromLatin1("system")); + if (!isValidUri(value)) { + attributeContentError("system", "notation", value, BuiltinTypes::xsAnyURI); + return notation; + } + + if (!value.isEmpty()) { + const AnyURI::Ptr systemId = AnyURI::fromLexical(value); + notation->setSystemId(systemId); + } + + hasOptionalAttribute = true; + } + + if (!hasOptionalAttribute) { + error(QtXmlPatterns::tr("%1 element requires either %2 or %3 attribute") + .arg(formatElement("notation")) + .arg(formatAttribute("public")) + .arg(formatAttribute("system"))); + return notation; + } + + validateIdAttribute("notation"); + + TagValidationHandler tagValidator(XsdTagScope::Notation, this, m_namePool); + + while (!atEnd()) { + readNext(); + + if (isEndElement()) + break; + + if (isCharacters() || isEntityReference()) { + if (!text().toString().trimmed().isEmpty()) { + error(QtXmlPatterns::tr("text or entity references not allowed inside %1 element").arg(formatElement("notation"))); + return notation; + } + } + + if (isStartElement()) { + const XsdSchemaToken::NodeName token = XsdSchemaToken::toToken(name()); + const XsdSchemaToken::NodeName namespaceToken = XsdSchemaToken::toToken(namespaceUri()); + + tagValidator.validate(token); + + if (isSchemaTag(XsdSchemaToken::Annotation, token, namespaceToken)) { + const XsdAnnotation::Ptr annotation = parseAnnotation(); + notation->addAnnotation(annotation); + } else { + parseUnknown(); + } + } + } + + tagValidator.finalize(); + + return notation; +} + +XsdWildcard::Ptr XsdSchemaParser::parseAny(const XsdParticle::Ptr &particle) +{ + const ElementNamespaceHandler namespaceHandler(XsdSchemaToken::Any, this); + + validateElement(XsdTagScope::Any); + + const XsdWildcard::Ptr wildcard(new XsdWildcard()); + + // parse attributes + if (!parseMinMaxConstraint(particle, "any")) { + return wildcard; + } + + if (hasAttribute(QString::fromLatin1("namespace"))) { + const QSet values = readAttribute(QString::fromLatin1("namespace")).split(QLatin1Char(' '), QString::SkipEmptyParts).toSet(); + if ((values.contains(QString::fromLatin1("##any")) || values.contains(QString::fromLatin1("##other"))) && values.count() != 1) { + error(QtXmlPatterns::tr("%1 attribute of %2 element must contain %3, %4 or a list of URIs") + .arg(formatAttribute("namespace")) + .arg(formatElement("any")) + .arg(formatData("##any")) + .arg(formatData("##other"))); + return wildcard; + } + + if (values.contains(QString::fromLatin1("##any"))) { + wildcard->namespaceConstraint()->setVariety(XsdWildcard::NamespaceConstraint::Any); + } else if (values.contains(QString::fromLatin1("##other"))) { + wildcard->namespaceConstraint()->setVariety(XsdWildcard::NamespaceConstraint::Not); + if (!m_targetNamespace.isEmpty()) + wildcard->namespaceConstraint()->setNamespaces(QSet() << m_targetNamespace); + else + wildcard->namespaceConstraint()->setNamespaces(QSet() << XsdWildcard::absentNamespace()); + } else { + wildcard->namespaceConstraint()->setVariety(XsdWildcard::NamespaceConstraint::Enumeration); + QStringList newValues = values.toList(); + + // replace the ##targetNamespace entry + for (int i = 0; i < newValues.count(); ++i) { + if (newValues.at(i) == QString::fromLatin1("##targetNamespace")) { + if (!m_targetNamespace.isEmpty()) + newValues[i] = m_targetNamespace; + else + newValues[i] = XsdWildcard::absentNamespace(); + } else if (newValues.at(i) == QString::fromLatin1("##local")) { + newValues[i] = XsdWildcard::absentNamespace(); + } + } + + // check for invalid URIs + for (int i = 0; i < newValues.count(); ++i) { + const QString stringValue = newValues.at(i); + if (stringValue == XsdWildcard::absentNamespace()) + continue; + + if (!isValidUri(stringValue)) { + attributeContentError("namespace", "any", stringValue, BuiltinTypes::xsAnyURI); + return wildcard; + } + } + + wildcard->namespaceConstraint()->setNamespaces(newValues.toSet()); + } + } else { + wildcard->namespaceConstraint()->setVariety(XsdWildcard::NamespaceConstraint::Any); + } + + if (hasAttribute(QString::fromLatin1("processContents"))) { + const QString value = readAttribute(QString::fromLatin1("processContents")); + if (value != QString::fromLatin1("lax") && + value != QString::fromLatin1("skip") && + value != QString::fromLatin1("strict")) { + attributeContentError("processContents", "any", value); + return wildcard; + } + + if (value == QString::fromLatin1("lax")) { + wildcard->setProcessContents(XsdWildcard::Lax); + } else if (value == QString::fromLatin1("skip")) { + wildcard->setProcessContents(XsdWildcard::Skip); + } else if (value == QString::fromLatin1("strict")) { + wildcard->setProcessContents(XsdWildcard::Strict); + } + } else { + wildcard->setProcessContents(XsdWildcard::Strict); + } + + validateIdAttribute("any"); + + TagValidationHandler tagValidator(XsdTagScope::Any, this, m_namePool); + + while (!atEnd()) { + readNext(); + + if (isEndElement()) + break; + + if (isStartElement()) { + const XsdSchemaToken::NodeName token = XsdSchemaToken::toToken(name()); + const XsdSchemaToken::NodeName namespaceToken = XsdSchemaToken::toToken(namespaceUri()); + + tagValidator.validate(token); + + if (isSchemaTag(XsdSchemaToken::Annotation, token, namespaceToken)) { + const XsdAnnotation::Ptr annotation = parseAnnotation(); + wildcard->addAnnotation(annotation); + } else { + parseUnknown(); + } + } + } + + tagValidator.finalize(); + + return wildcard; +} + +XsdWildcard::Ptr XsdSchemaParser::parseAnyAttribute() +{ + const ElementNamespaceHandler namespaceHandler(XsdSchemaToken::AnyAttribute, this); + + validateElement(XsdTagScope::AnyAttribute); + + const XsdWildcard::Ptr wildcard(new XsdWildcard()); + + // parse attributes + if (hasAttribute(QString::fromLatin1("namespace"))) { + const QSet values = readAttribute(QString::fromLatin1("namespace")).split(QLatin1Char(' '), QString::SkipEmptyParts).toSet(); + if ((values.contains(QString::fromLatin1("##any")) || values.contains(QString::fromLatin1("##other"))) && values.count() != 1) { + error(QtXmlPatterns::tr("%1 attribute of %2 element must contain %3, %4 or a list of URIs") + .arg(formatAttribute("namespace")) + .arg(formatElement("anyAttribute")) + .arg(formatData("##any")) + .arg(formatData("##other"))); + return wildcard; + } + + if (values.contains(QString::fromLatin1("##any"))) { + wildcard->namespaceConstraint()->setVariety(XsdWildcard::NamespaceConstraint::Any); + } else if (values.contains(QString::fromLatin1("##other"))) { + wildcard->namespaceConstraint()->setVariety(XsdWildcard::NamespaceConstraint::Not); + if (!m_targetNamespace.isEmpty()) + wildcard->namespaceConstraint()->setNamespaces(QSet() << m_targetNamespace); + else + wildcard->namespaceConstraint()->setNamespaces(QSet() << XsdWildcard::absentNamespace()); + } else { + wildcard->namespaceConstraint()->setVariety(XsdWildcard::NamespaceConstraint::Enumeration); + QStringList newValues = values.toList(); + + // replace the ##targetNamespace entry + for (int i = 0; i < newValues.count(); ++i) { + if (newValues.at(i) == QString::fromLatin1("##targetNamespace")) { + if (!m_targetNamespace.isEmpty()) + newValues[i] = m_targetNamespace; + else + newValues[i] = XsdWildcard::absentNamespace(); + } else if (newValues.at(i) == QString::fromLatin1("##local")) { + newValues[i] = XsdWildcard::absentNamespace(); + } + } + + // check for invalid URIs + for (int i = 0; i < newValues.count(); ++i) { + const QString stringValue = newValues.at(i); + if (stringValue == XsdWildcard::absentNamespace()) + continue; + + if (!isValidUri(stringValue)) { + attributeContentError("namespace", "anyAttribute", stringValue, BuiltinTypes::xsAnyURI); + return wildcard; + } + } + + wildcard->namespaceConstraint()->setNamespaces(newValues.toSet()); + } + } else { + wildcard->namespaceConstraint()->setVariety(XsdWildcard::NamespaceConstraint::Any); + } + + if (hasAttribute(QString::fromLatin1("processContents"))) { + const QString value = readAttribute(QString::fromLatin1("processContents")); + if (value != QString::fromLatin1("lax") && + value != QString::fromLatin1("skip") && + value != QString::fromLatin1("strict")) { + attributeContentError("processContents", "anyAttribute", value); + return wildcard; + } + + if (value == QString::fromLatin1("lax")) { + wildcard->setProcessContents(XsdWildcard::Lax); + } else if (value == QString::fromLatin1("skip")) { + wildcard->setProcessContents(XsdWildcard::Skip); + } else if (value == QString::fromLatin1("strict")) { + wildcard->setProcessContents(XsdWildcard::Strict); + } + } else { + wildcard->setProcessContents(XsdWildcard::Strict); + } + + validateIdAttribute("anyAttribute"); + + TagValidationHandler tagValidator(XsdTagScope::AnyAttribute, this, m_namePool); + + while (!atEnd()) { + readNext(); + + if (isEndElement()) + break; + + if (isStartElement()) { + const XsdSchemaToken::NodeName token = XsdSchemaToken::toToken(name()); + const XsdSchemaToken::NodeName namespaceToken = XsdSchemaToken::toToken(namespaceUri()); + + tagValidator.validate(token); + + if (isSchemaTag(XsdSchemaToken::Annotation, token, namespaceToken)) { + const XsdAnnotation::Ptr annotation = parseAnnotation(); + wildcard->addAnnotation(annotation); + } else { + parseUnknown(); + } + } + } + + tagValidator.finalize(); + + return wildcard; +} + + +void XsdSchemaParser::parseUnknownDocumentation() +{ + Q_ASSERT(isStartElement()); + m_namespaceSupport.pushContext(); + m_namespaceSupport.setPrefixes(namespaceDeclarations()); + + while (!atEnd()) { + readNext(); + + if (isEndElement()) + break; + + if (isStartElement()) + parseUnknownDocumentation(); + } + + m_namespaceSupport.popContext(); +} + +void XsdSchemaParser::parseUnknown() +{ + Q_ASSERT(isStartElement()); + m_namespaceSupport.pushContext(); + m_namespaceSupport.setPrefixes(namespaceDeclarations()); + + error(QtXmlPatterns::tr("%1 element is not allowed in this context").arg(formatElement(name().toString()))); + + while (!atEnd()) { + readNext(); + + if (isEndElement()) + break; + + if (isStartElement()) + parseUnknown(); + } + + m_namespaceSupport.popContext(); +} + +bool XsdSchemaParser::parseMinMaxConstraint(const XsdParticle::Ptr &particle, const char *elementName) +{ + if (hasAttribute(QString::fromLatin1("minOccurs"))) { + const QString value = readAttribute(QString::fromLatin1("minOccurs")); + + DerivedInteger::Ptr integer = DerivedInteger::fromLexical(m_namePool, value); + if (integer->hasError()) { + attributeContentError("minOccurs", elementName, value, BuiltinTypes::xsNonNegativeInteger); + return false; + } else { + particle->setMinimumOccurs(integer->as< DerivedInteger >()->storedValue()); + } + } else { + particle->setMinimumOccurs(1); + } + + if (hasAttribute(QString::fromLatin1("maxOccurs"))) { + const QString value = readAttribute(QString::fromLatin1("maxOccurs")); + + if (value == QString::fromLatin1("unbounded")) { + particle->setMaximumOccursUnbounded(true); + } else { + particle->setMaximumOccursUnbounded(false); + DerivedInteger::Ptr integer = DerivedInteger::fromLexical(m_namePool, value); + if (integer->hasError()) { + attributeContentError("maxOccurs", elementName, value, BuiltinTypes::xsNonNegativeInteger); + return false; + } else { + particle->setMaximumOccurs(integer->as< DerivedInteger >()->storedValue()); + } + } + } else { + particle->setMaximumOccursUnbounded(false); + particle->setMaximumOccurs(1); + } + + if (!particle->maximumOccursUnbounded()) { + if (particle->maximumOccurs() < particle->minimumOccurs()) { + error(QtXmlPatterns::tr("%1 attribute of %2 element has larger value than %3 attribute") + .arg(formatAttribute("minOccurs")) + .arg(formatElement(elementName)) + .arg(formatAttribute("maxOccurs"))); + return false; + } + } + + return true; +} + +QSourceLocation XsdSchemaParser::currentSourceLocation() const +{ + QSourceLocation location; + location.setLine(lineNumber()); + location.setColumn(columnNumber()); + location.setUri(m_documentURI); + + return location; +} + +void XsdSchemaParser::convertName(const QString &qualifiedName, NamespaceSupport::NameType type, QXmlName &name) +{ + bool result = m_namespaceSupport.processName(qualifiedName, type, name); + if (!result) { + error(QtXmlPatterns::tr("prefix of qualified name %1 is not defined").arg(formatKeyword(qualifiedName))); + } +} + +QString XsdSchemaParser::readNameAttribute(const char *elementName) +{ + const QString value = readAttribute(QString::fromLatin1("name")).simplified(); + if (!QXmlUtils::isNCName(value)) { + attributeContentError("name", elementName, value, BuiltinTypes::xsNCName); + return QString(); + } else { + return value; + } +} + +QString XsdSchemaParser::readQNameAttribute(const QString &typeAttribute, const char *elementName) +{ + const QString value = readAttribute(typeAttribute).simplified(); + if (!XPathHelper::isQName(value)) { + attributeContentError(typeAttribute.toLatin1(), elementName, value, BuiltinTypes::xsQName); + return QString(); + } else { + return value; + } +} + +QString XsdSchemaParser::readNamespaceAttribute(const QString &attributeName, const char *elementName) +{ + const QString value = readAttribute(attributeName); + if (value.isEmpty()) { + attributeContentError(attributeName.toLatin1(), elementName, value, BuiltinTypes::xsAnyURI); + return QString(); + } + + return value; +} + +SchemaType::DerivationConstraints XsdSchemaParser::readDerivationConstraintAttribute(const SchemaType::DerivationConstraints &allowedConstraints, const char *elementName) +{ + // first convert the flags into strings for easier comparision + QSet allowedContent; + if (allowedConstraints & SchemaType::RestrictionConstraint) + allowedContent.insert(QString::fromLatin1("restriction")); + if (allowedConstraints & SchemaType::ExtensionConstraint) + allowedContent.insert(QString::fromLatin1("extension")); + if (allowedConstraints & SchemaType::ListConstraint) + allowedContent.insert(QString::fromLatin1("list")); + if (allowedConstraints & SchemaType::UnionConstraint) + allowedContent.insert(QString::fromLatin1("union")); + + // read content from the attribute if available, otherwise use the default definitions from the schema tag + QString content; + if (hasAttribute(QString::fromLatin1("final"))) { + content = readAttribute(QString::fromLatin1("final")); + + // split string into list to validate the content of the attribute + const QStringList values = content.split(QLatin1Char(' '), QString::SkipEmptyParts); + for (int i = 0; i < values.count(); i++) { + const QString value = values.at(i); + if (!allowedContent.contains(value) && (value != QString::fromLatin1("#all"))) { + attributeContentError("final", elementName, value); + return SchemaType::DerivationConstraints(); + } + + if ((value == QString::fromLatin1("#all")) && values.count() != 1) { + error(QtXmlPatterns::tr("%1 attribute of %2 element must either contain %3 or the other values") + .arg(formatAttribute("final")) + .arg(formatElement(elementName)) + .arg(formatData("#all"))); + return SchemaType::DerivationConstraints(); + } + } + } else { + // content of the default value has been validated in parseSchema already + content = m_finalDefault; + } + + QSet contentSet = content.split(QLatin1Char(' '), QString::SkipEmptyParts).toSet(); + + // if the '#all' tag is defined, we return all allowed values + if (contentSet.contains(QString::fromLatin1("#all"))) { + return allowedConstraints; + } else { // return the values from content set that intersects with the allowed values + contentSet.intersect(allowedContent); + + SchemaType::DerivationConstraints constraints; + + if (contentSet.contains(QString::fromLatin1("restriction"))) + constraints |= SchemaType::RestrictionConstraint; + if (contentSet.contains(QString::fromLatin1("extension"))) + constraints |= SchemaType::ExtensionConstraint; + if (contentSet.contains(QString::fromLatin1("list"))) + constraints |= SchemaType::ListConstraint; + if (contentSet.contains(QString::fromLatin1("union"))) + constraints |= SchemaType::UnionConstraint; + + return constraints; + } +} + +NamedSchemaComponent::BlockingConstraints XsdSchemaParser::readBlockingConstraintAttribute(const NamedSchemaComponent::BlockingConstraints &allowedConstraints, const char *elementName) +{ + // first convert the flags into strings for easier comparision + QSet allowedContent; + if (allowedConstraints & NamedSchemaComponent::RestrictionConstraint) + allowedContent.insert(QString::fromLatin1("restriction")); + if (allowedConstraints & NamedSchemaComponent::ExtensionConstraint) + allowedContent.insert(QString::fromLatin1("extension")); + if (allowedConstraints & NamedSchemaComponent::SubstitutionConstraint) + allowedContent.insert(QString::fromLatin1("substitution")); + + // read content from the attribute if available, otherwise use the default definitions from the schema tag + QString content; + if (hasAttribute(QString::fromLatin1("block"))) { + content = readAttribute(QString::fromLatin1("block")); + + // split string into list to validate the content of the attribute + const QStringList values = content.split(QLatin1Char(' '), QString::SkipEmptyParts); + for (int i = 0; i < values.count(); i++) { + const QString value = values.at(i); + if (!allowedContent.contains(value) && (value != QString::fromLatin1("#all"))) { + attributeContentError("block", elementName, value); + return NamedSchemaComponent::BlockingConstraints(); + } + + if ((value == QString::fromLatin1("#all")) && values.count() != 1) { + error(QtXmlPatterns::tr("%1 attribute of %2 element must either contain %3 or the other values") + .arg(formatAttribute("block")) + .arg(formatElement(elementName)) + .arg(formatData("#all"))); + return NamedSchemaComponent::BlockingConstraints(); + } + } + } else { + // content of the default value has been validated in parseSchema already + content = m_blockDefault; + } + + QSet contentSet = content.split(QLatin1Char(' '), QString::SkipEmptyParts).toSet(); + + // if the '#all' tag is defined, we return all allowed values + if (contentSet.contains(QString::fromLatin1("#all"))) { + return allowedConstraints; + } else { // return the values from content set that intersects with the allowed values + contentSet.intersect(allowedContent); + + NamedSchemaComponent::BlockingConstraints constraints; + + if (contentSet.contains(QString::fromLatin1("restriction"))) + constraints |= NamedSchemaComponent::RestrictionConstraint; + if (contentSet.contains(QString::fromLatin1("extension"))) + constraints |= NamedSchemaComponent::ExtensionConstraint; + if (contentSet.contains(QString::fromLatin1("substitution"))) + constraints |= NamedSchemaComponent::SubstitutionConstraint; + + return constraints; + } +} + +XsdXPathExpression::Ptr XsdSchemaParser::readXPathExpression(const char *elementName) +{ + const XsdXPathExpression::Ptr expression(new XsdXPathExpression()); + + const QList namespaceBindings = m_namespaceSupport.namespaceBindings(); + QXmlName emptyName; + for (int i = 0; i < namespaceBindings.count(); ++i) { + if (namespaceBindings.at(i).prefix() == StandardPrefixes::empty) + emptyName = namespaceBindings.at(i); + } + + expression->setNamespaceBindings(namespaceBindings); + + QString xpathDefaultNamespace; + if (hasAttribute(QString::fromLatin1("xpathDefaultNamespace"))) { + xpathDefaultNamespace = readAttribute(QString::fromLatin1("xpathDefaultNamespace")); + if (xpathDefaultNamespace != QString::fromLatin1("##defaultNamespace") && + xpathDefaultNamespace != QString::fromLatin1("##targetNamespace") && + xpathDefaultNamespace != QString::fromLatin1("##local")) { + if (!isValidUri(xpathDefaultNamespace)) { + attributeContentError("xpathDefaultNamespace", elementName, xpathDefaultNamespace, BuiltinTypes::xsAnyURI); + return expression; + } + } + } else { + xpathDefaultNamespace = m_xpathDefaultNamespace; + } + + AnyURI::Ptr namespaceURI; + if (xpathDefaultNamespace == QString::fromLatin1("##defaultNamespace")) { + if (!emptyName.isNull()) + namespaceURI = AnyURI::fromLexical(m_namePool->stringForNamespace(emptyName.namespaceURI())); + } else if (xpathDefaultNamespace == QString::fromLatin1("##targetNamespace")) { + if (!m_targetNamespace.isEmpty()) + namespaceURI = AnyURI::fromLexical(m_targetNamespace); + } else if (xpathDefaultNamespace == QString::fromLatin1("##local")) { + // it is absent + } else { + namespaceURI = AnyURI::fromLexical(xpathDefaultNamespace); + } + if (namespaceURI) { + if (namespaceURI->hasError()) { + attributeContentError("xpathDefaultNamespace", elementName, xpathDefaultNamespace, BuiltinTypes::xsAnyURI); + return expression; + } + + expression->setDefaultNamespace(namespaceURI); + } + + //TODO: read the base uri if qmaintaining reader support it + + return expression; +} + +QString XsdSchemaParser::readXPathAttribute(const QString &attributeName, XPathType type, const char *elementName) +{ + const QString value = readAttribute(attributeName); + if (value.isEmpty() || value.startsWith(QLatin1Char('/'))) { + attributeContentError(attributeName.toLatin1(), elementName, value); + return QString(); + } + + QXmlNamePool namePool(m_namePool.data()); + + QXmlQuery::QueryLanguage language; + switch (type) { + case XPath20: language = QXmlQuery::XPath20; break; + case XPathSelector: language = QXmlQuery::XmlSchema11IdentityConstraintSelector; break; + case XPathField: language = QXmlQuery::XmlSchema11IdentityConstraintField; break; + }; + + QXmlQuery query(language, namePool); + QXmlQueryPrivate *queryPrivate = query.d; + + const QList namespaceBindings = m_namespaceSupport.namespaceBindings(); + for (int i = 0; i < namespaceBindings.count(); ++i) { + if (!namespaceBindings.at(i).prefix() == StandardPrefixes::empty) + queryPrivate->addAdditionalNamespaceBinding(namespaceBindings.at(i)); + } + + query.setQuery(value, m_documentURI); + if (!query.isValid()) { + attributeContentError(attributeName.toLatin1(), elementName, value); + return QString(); + } + + return value; +} + +void XsdSchemaParser::validateIdAttribute(const char *elementName) +{ + if (hasAttribute(QString::fromLatin1("id"))) { + const QString value = readAttribute(QString::fromLatin1("id")); + DerivedString::Ptr id = DerivedString::fromLexical(m_namePool, value); + if (id->hasError()) { + attributeContentError("id", elementName, value, BuiltinTypes::xsID); + } else { + if (m_idCache->hasId(value)) { + error(QtXmlPatterns::tr("component with id %1 has been defined previously").arg(formatData(value))); + } else { + m_idCache->addId(value); + } + } + } +} + +bool XsdSchemaParser::isSchemaTag(XsdSchemaToken::NodeName tag, XsdSchemaToken::NodeName token, XsdSchemaToken::NodeName namespaceToken) const +{ + return ((tag == token) && (namespaceToken == XsdSchemaToken::XML_NS_SCHEMA_URI)); +} + +void XsdSchemaParser::addElement(const XsdElement::Ptr &element) +{ + const QXmlName objectName = element->name(m_namePool); + if (m_schema->element(objectName)) { + error(QtXmlPatterns::tr("element %1 already defined").arg(formatElement(m_namePool->displayName(objectName)))); + } else { + m_schema->addElement(element); + m_componentLocationHash.insert(element, currentSourceLocation()); + } +} + +void XsdSchemaParser::addAttribute(const XsdAttribute::Ptr &attribute) +{ + const QXmlName objectName = attribute->name(m_namePool); + if (m_schema->attribute(objectName)) { + error(QtXmlPatterns::tr("attribute %1 already defined").arg(formatAttribute(m_namePool->displayName(objectName)))); + } else { + m_schema->addAttribute(attribute); + m_componentLocationHash.insert(attribute, currentSourceLocation()); + } +} + +void XsdSchemaParser::addType(const SchemaType::Ptr &type) +{ + // we don't import redefinitions of builtin types, that just causes problems + if (m_builtinTypeNames.contains(type->name(m_namePool))) + return; + + const QXmlName objectName = type->name(m_namePool); + if (m_schema->type(objectName)) { + error(QtXmlPatterns::tr("type %1 already defined").arg(formatType(m_namePool, objectName))); + } else { + m_schema->addType(type); + if (type->isSimpleType()) + m_componentLocationHash.insert(XsdSimpleType::Ptr(type), currentSourceLocation()); + else + m_componentLocationHash.insert(XsdComplexType::Ptr(type), currentSourceLocation()); + } +} + +void XsdSchemaParser::addAnonymousType(const SchemaType::Ptr &type) +{ + m_schema->addAnonymousType(type); + if (type->isSimpleType()) + m_componentLocationHash.insert(XsdSimpleType::Ptr(type), currentSourceLocation()); + else + m_componentLocationHash.insert(XsdComplexType::Ptr(type), currentSourceLocation()); +} + +void XsdSchemaParser::addAttributeGroup(const XsdAttributeGroup::Ptr &group) +{ + const QXmlName objectName = group->name(m_namePool); + if (m_schema->attributeGroup(objectName)) { + error(QtXmlPatterns::tr("attribute group %1 already defined").arg(formatKeyword(m_namePool, objectName))); + } else { + m_schema->addAttributeGroup(group); + m_componentLocationHash.insert(group, currentSourceLocation()); + } +} + +void XsdSchemaParser::addElementGroup(const XsdModelGroup::Ptr &group) +{ + const QXmlName objectName = group->name(m_namePool); + if (m_schema->elementGroup(objectName)) { + error(QtXmlPatterns::tr("element group %1 already defined").arg(formatKeyword(m_namePool, objectName))); + } else { + m_schema->addElementGroup(group); + m_componentLocationHash.insert(group, currentSourceLocation()); + } +} + +void XsdSchemaParser::addNotation(const XsdNotation::Ptr ¬ation) +{ + const QXmlName objectName = notation->name(m_namePool); + if (m_schema->notation(objectName)) { + error(QtXmlPatterns::tr("notation %1 already defined").arg(formatKeyword(m_namePool, objectName))); + } else { + m_schema->addNotation(notation); + m_componentLocationHash.insert(notation, currentSourceLocation()); + } +} + +void XsdSchemaParser::addIdentityConstraint(const XsdIdentityConstraint::Ptr &constraint) +{ + const QXmlName objectName = constraint->name(m_namePool); + if (m_schema->identityConstraint(objectName)) { + error(QtXmlPatterns::tr("identity constraint %1 already defined").arg(formatKeyword(m_namePool, objectName))); + } else { + m_schema->addIdentityConstraint(constraint); + m_componentLocationHash.insert(constraint, currentSourceLocation()); + } +} + +void XsdSchemaParser::addFacet(const XsdFacet::Ptr &facet, XsdFacet::Hash &facets, const SchemaType::Ptr &type) +{ + // @see http://www.w3.org/TR/xmlschema-2/#src-single-facet-value + if (facets.contains(facet->type())) { + error(QtXmlPatterns::tr("duplicated facets in simple type %1").arg(formatType(m_namePool, type))); + return; + } + + facets.insert(facet->type(), facet); +} + +QT_END_NAMESPACE diff --git a/src/xmlpatterns/schema/qxsdschemaparser_p.h b/src/xmlpatterns/schema/qxsdschemaparser_p.h new file mode 100644 index 0000000..960fb86 --- /dev/null +++ b/src/xmlpatterns/schema/qxsdschemaparser_p.h @@ -0,0 +1,691 @@ +/**************************************************************************** +** +** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the $MODULE$ of the Qt Toolkit. +** +** $TROLLTECH_DUAL_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 "qnamespacesupport_p.h" +#include "qxsdalternative_p.h" +#include "qxsdattribute_p.h" +#include "qxsdattributegroup_p.h" +#include "qxsdattributeterm_p.h" +#include "qxsdcomplextype_p.h" +#include "qxsdelement_p.h" +#include "qxsdidcache_p.h" +#include "qxsdmodelgroup_p.h" +#include "qxsdnotation_p.h" +#include "qxsdsimpletype_p.h" +#include "qxsdschemacontext_p.h" +#include "qxsdschemaparsercontext_p.h" +#include "qxsdstatemachine_p.h" + +#include +#include +#include +#include +#include + +QT_BEGIN_HEADER + +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; + + /** + * Sets which @p schemas have been included already, so the parser + * can detect circular includes. + */ + void setIncludedSchemas(const NamespaceSet &schemas); + + /** + * Sets which @p schemas have been imported already, so the parser + * can detect circular imports. + */ + void setImportedSchemas(const NamespaceSet &schemas); + + /** + * Sets which @p schemas have been redefined already, so the parser + * can detect circular redefines. + */ + 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 + +QT_END_HEADER + +#endif diff --git a/src/xmlpatterns/schema/qxsdschemaparser_setup.cpp b/src/xmlpatterns/schema/qxsdschemaparser_setup.cpp new file mode 100644 index 0000000..167af7a --- /dev/null +++ b/src/xmlpatterns/schema/qxsdschemaparser_setup.cpp @@ -0,0 +1,1070 @@ + +#include "qxsdschemaparser_p.h" + +#include "qbuiltintypes_p.h" + +QT_BEGIN_NAMESPACE + +using namespace QPatternist; + +/** + * @page using_dfa_for_schema Using DFA for validation of correct XML tag occurrence + * + * This page describes how to use DFAs for validating that the XML child tags of an + * XML parent tag occur in the right order. + * + * To validate the occurence of XML tags one need a regular expression that describes + * which tags can appear how often in what context. For example the regular expression + * of the global attribute tag in XML Schema is (annotation?, simpleType?). + * That means the attribute tag can contain an annotation tag followed + * by a simpleType tag, or just one simpleType tag and even no child + * tag at all. + * So the regular expression describes some kind of language and all the various occurrences + * of the child tags can be seen as words of that language. + * We can create a DFA now, that accepts all words (and only these words) of that language + * and whenever we want to check if a sequence of child tags belongs to the language, + * we test if the sequence passes the DFA successfully. + * + * The following example shows how to create the DFA for the regular expression method + * above. + * + * \dotfile GlobalAttribute_diagram.dot + * + * At first we need a start state (1), that's the state the DFA is before it + * starts running. As our regular expression allows that there are no child tags, the + * start state is an end state as well (marked by the double circle). + * Now we fetch the first token from the XML file (let's assume it is an annotation tag) + * and check if there is an edge labled with the tag name leaving the current state of the DFA. + * If there is no such edge, the input doesn't fullfill the rules of the regular expression, + * so we throw an error. Otherwise we follow that edge and the DFA is set to the new state (2) the + * edge points to. Now we fetch the next token from the XML file and do the previous steps again. + * If there is no further input from the XML file, we check whether the DFA is in an end state and + * throw an error if not. + * + * So the algorithm for checking is quite simple, the whole logic is encoded in the DFA and creating + * one for a regular expression is sometimes not easy, however the ones for XML Schema are straight + * forward. + * + *

Legend:

+ * \dotfile legend.dot + *
+ * + *

DFA for all tag

+ * \dotfile All_diagram.dot + *
+ *

DFA for alternative tag

+ * \dotfile Alternative_diagram.dot + *
+ *

DFA for annotation tag

+ * \dotfile Annotation_diagram.dot + *
+ *

DFA for anyAttribute tag

+ * \dotfile AnyAttribute_diagram.dot + *
+ *

DFA for any tag

+ * \dotfile Any_diagram.dot + *
+ *

DFA for assert tag

+ * \dotfile Assert_diagram.dot + *
+ *

DFA for choice tag

+ * \dotfile Choice_diagram.dot + *
+ *

DFA for complexContent tag

+ * \dotfile ComplexContent_diagram.dot + *
+ *

DFA for extension tag inside a complexContent tag

+ * \dotfile ComplexContentExtension_diagram.dot + *
+ *

DFA for restriction tag inside a complexContent tag

+ * \dotfile ComplexContentRestriction_diagram.dot + *
+ *

DFA for defaultOpenContent tag

+ * \dotfile DefaultOpenContent_diagram.dot + *
+ *

DFA for enumeration tag

+ * \dotfile EnumerationFacet_diagram.dot + *
+ *

DFA for field tag

+ * \dotfile Field_diagram.dot + *
+ *

DFA for fractionDigits tag

+ * \dotfile FractionDigitsFacet_diagram.dot + *
+ *

DFA for attribute tag

+ * \dotfile GlobalAttribute_diagram.dot + *
+ *

DFA for complexType tag

+ * \dotfile GlobalComplexType_diagram.dot + *
+ *

DFA for element tag

+ * \dotfile GlobalElement_diagram.dot + *
+ *

DFA for simpleType tag

+ * \dotfile GlobalSimpleType_diagram.dot + *
+ *

DFA for import tag

+ * \dotfile Import_diagram.dot + *
+ *

DFA for include tag

+ * \dotfile Include_diagram.dot + *
+ *

DFA for key tag

+ * \dotfile Key_diagram.dot + *
+ *

DFA for keyref tag

+ * \dotfile KeyRef_diagram.dot + *
+ *

DFA for length tag

+ * \dotfile LengthFacet_diagram.dot + *
+ *

DFA for list tag

+ * \dotfile List_diagram.dot + *
+ *

DFA for all tag

+ * \dotfile LocalAll_diagram.dot + *
+ *

DFA for attribute tag

+ * \dotfile LocalAttribute_diagram.dot + *
+ *

DFA for choice tag

+ * \dotfile LocalChoice_diagram.dot + *
+ *

DFA for complexType tag

+ * \dotfile LocalComplexType_diagram.dot + *
+ *

DFA for element tag

+ * \dotfile LocalElement_diagram.dot + *
+ *

DFA for sequence tag

+ * \dotfile LocalSequence_diagram.dot + *
+ *

DFA for simpleType tag that

+ * \dotfile LocalSimpleType_diagram.dot + *
+ *

DFA for maxExclusive tag

+ * \dotfile MaxExclusiveFacet_diagram.dot + *
+ *

DFA for maxInclusive tag

+ * \dotfile MaxInclusiveFacet_diagram.dot + *
+ *

DFA for maxLength tag

+ * \dotfile MaxLengthFacet_diagram.dot + *
+ *

DFA for minExclusive tag

+ * \dotfile MinExclusiveFacet_diagram.dot + *
+ *

DFA for minInclusive tag

+ * \dotfile MinInclusiveFacet_diagram.dot + *
+ *

DFA for minLength tag

+ * \dotfile MinLengthFacet_diagram.dot + *
+ *

DFA for attributeGroup tag without ref attribute

+ * \dotfile NamedAttributeGroup_diagram.dot + *
+ *

DFA for group tag without ref attribute

+ * \dotfile NamedGroup_diagram.dot + *
+ *

DFA for notation tag

+ * \dotfile Notation_diagram.dot + *
+ *

DFA for override tag

+ * \dotfile Override_diagram.dot + *
+ *

DFA for pattern tag

+ * \dotfile PatternFacet_diagram.dot + *
+ *

DFA for redefine tag

+ * \dotfile Redefine_diagram.dot + *
+ *

DFA for attributeGroup tag with ref attribute

+ * \dotfile ReferredAttributeGroup_diagram.dot + *
+ *

DFA for group tag with ref attribute

+ * \dotfile ReferredGroup_diagram.dot + *
+ *

DFA for schema tag

+ * \dotfile Schema_diagram.dot + *
+ *

DFA for selector tag

+ * \dotfile Selector_diagram.dot + *
+ *

DFA for sequence tag

+ * \dotfile Sequence_diagram.dot + *
+ *

DFA for simpleContent tag

+ * \dotfile SimpleContent_diagram.dot + *
+ *

DFA for extension tag inside a simpleContent tag

+ * \dotfile SimpleContentExtension_diagram.dot + *
+ *

DFA for restriction tag inside a simpleContent tag

+ * \dotfile SimpleContentRestriction_diagram.dot + *
+ *

DFA for restriction tag inside a simpleType tag

+ * \dotfile SimpleRestriction_diagram.dot + *
+ *

DFA for totalDigits tag

+ * \dotfile TotalDigitsFacet_diagram.dot + *
+ *

DFA for union tag

+ * \dotfile Union_diagram.dot + *
+ *

DFA for unique tag

+ * \dotfile Unique_diagram.dot + *
+ *

DFA for whiteSpace tag

+ * \dotfile WhiteSpaceFacet_diagram.dot + */ + +void XsdSchemaParser::setupStateMachines() +{ + { + XsdStateMachine machine(m_namePool); + + // setup state machine for (annotation?, simpleType?) : attribute + const XsdStateMachine::StateId startState = machine.addState(XsdStateMachine::StartEndState); + const XsdStateMachine::StateId s1 = machine.addState(XsdStateMachine::EndState); + const XsdStateMachine::StateId s2 = machine.addState(XsdStateMachine::EndState); + + machine.addTransition(startState, XsdSchemaToken::Annotation, s1); + machine.addTransition(startState, XsdSchemaToken::SimpleType, s2); + machine.addTransition(s1, XsdSchemaToken::SimpleType, s2); + + m_stateMachines.insert(XsdTagScope::GlobalAttribute, machine); + m_stateMachines.insert(XsdTagScope::LocalAttribute, machine); + } + + { + XsdStateMachine machine(m_namePool); + + // setup state machine for (annotation?, ((simpleType | complexType)?, alternative*, (unique | key | keyref)*)) : element + const XsdStateMachine::StateId startState = machine.addState(XsdStateMachine::StartEndState); + const XsdStateMachine::StateId s1 = machine.addState(XsdStateMachine::EndState); + const XsdStateMachine::StateId s2 = machine.addState(XsdStateMachine::EndState); + const XsdStateMachine::StateId s3 = machine.addState(XsdStateMachine::EndState); + const XsdStateMachine::StateId s4 = machine.addState(XsdStateMachine::EndState); + + machine.addTransition(startState, XsdSchemaToken::Annotation, s1); + machine.addTransition(startState, XsdSchemaToken::SimpleType, s2); + machine.addTransition(startState, XsdSchemaToken::ComplexType, s2); + machine.addTransition(startState, XsdSchemaToken::Alternative, s3); + machine.addTransition(startState, XsdSchemaToken::Unique, s4); + machine.addTransition(startState, XsdSchemaToken::Key, s4); + machine.addTransition(startState, XsdSchemaToken::Keyref, s4); + + machine.addTransition(s1, XsdSchemaToken::SimpleType, s2); + machine.addTransition(s1, XsdSchemaToken::ComplexType, s2); + machine.addTransition(s1, XsdSchemaToken::Alternative, s3); + machine.addTransition(s1, XsdSchemaToken::Unique, s4); + machine.addTransition(s1, XsdSchemaToken::Key, s4); + machine.addTransition(s1, XsdSchemaToken::Keyref, s4); + + machine.addTransition(s2, XsdSchemaToken::Alternative, s3); + machine.addTransition(s2, XsdSchemaToken::Unique, s4); + machine.addTransition(s2, XsdSchemaToken::Key, s4); + machine.addTransition(s2, XsdSchemaToken::Keyref, s4); + + machine.addTransition(s3, XsdSchemaToken::Alternative, s3); + machine.addTransition(s3, XsdSchemaToken::Unique, s4); + machine.addTransition(s3, XsdSchemaToken::Key, s4); + machine.addTransition(s3, XsdSchemaToken::Keyref, s4); + + machine.addTransition(s4, XsdSchemaToken::Unique, s4); + machine.addTransition(s4, XsdSchemaToken::Key, s4); + machine.addTransition(s4, XsdSchemaToken::Keyref, s4); + + m_stateMachines.insert(XsdTagScope::GlobalElement, machine); + m_stateMachines.insert(XsdTagScope::LocalElement, machine); + } + + { + XsdStateMachine machine(m_namePool); + + // setup state machine for (annotation?, (simpleContent | complexContent | (openContent?, (group | all | choice | sequence)?, ((attribute | attributeGroup)*, anyAttribute?), assert*))) : complexType + const XsdStateMachine::StateId startState = machine.addState(XsdStateMachine::StartEndState); + const XsdStateMachine::StateId s1 = machine.addState(XsdStateMachine::EndState); + const XsdStateMachine::StateId s2 = machine.addState(XsdStateMachine::EndState); + const XsdStateMachine::StateId s3 = machine.addState(XsdStateMachine::EndState); + const XsdStateMachine::StateId s4 = machine.addState(XsdStateMachine::EndState); + const XsdStateMachine::StateId s5 = machine.addState(XsdStateMachine::EndState); + const XsdStateMachine::StateId s6 = machine.addState(XsdStateMachine::EndState); + const XsdStateMachine::StateId s7 = machine.addState(XsdStateMachine::EndState); + + machine.addTransition(startState, XsdSchemaToken::Annotation, s1); + machine.addTransition(startState, XsdSchemaToken::SimpleContent, s2); + machine.addTransition(startState, XsdSchemaToken::ComplexContent, s2); + machine.addTransition(startState, XsdSchemaToken::OpenContent, s3); + machine.addTransition(startState, XsdSchemaToken::Group, s4); + machine.addTransition(startState, XsdSchemaToken::All, s4); + machine.addTransition(startState, XsdSchemaToken::Choice, s4); + machine.addTransition(startState, XsdSchemaToken::Sequence, s4); + machine.addTransition(startState, XsdSchemaToken::Attribute, s5); + machine.addTransition(startState, XsdSchemaToken::AttributeGroup, s5); + machine.addTransition(startState, XsdSchemaToken::AnyAttribute, s6); + machine.addTransition(startState, XsdSchemaToken::Assert, s7); + + machine.addTransition(s1, XsdSchemaToken::SimpleContent, s2); + machine.addTransition(s1, XsdSchemaToken::ComplexContent, s2); + machine.addTransition(s1, XsdSchemaToken::OpenContent, s3); + machine.addTransition(s1, XsdSchemaToken::Group, s4); + machine.addTransition(s1, XsdSchemaToken::All, s4); + machine.addTransition(s1, XsdSchemaToken::Choice, s4); + machine.addTransition(s1, XsdSchemaToken::Sequence, s4); + machine.addTransition(s1, XsdSchemaToken::Attribute, s5); + machine.addTransition(s1, XsdSchemaToken::AttributeGroup, s5); + machine.addTransition(s1, XsdSchemaToken::AnyAttribute, s6); + machine.addTransition(s1, XsdSchemaToken::Assert, s7); + + machine.addTransition(s3, XsdSchemaToken::Group, s4); + machine.addTransition(s3, XsdSchemaToken::All, s4); + machine.addTransition(s3, XsdSchemaToken::Choice, s4); + machine.addTransition(s3, XsdSchemaToken::Sequence, s4); + machine.addTransition(s3, XsdSchemaToken::Attribute, s5); + machine.addTransition(s3, XsdSchemaToken::AttributeGroup, s5); + machine.addTransition(s3, XsdSchemaToken::AnyAttribute, s6); + machine.addTransition(s3, XsdSchemaToken::Assert, s7); + + machine.addTransition(s4, XsdSchemaToken::Attribute, s5); + machine.addTransition(s4, XsdSchemaToken::AttributeGroup, s5); + machine.addTransition(s4, XsdSchemaToken::AnyAttribute, s6); + machine.addTransition(s4, XsdSchemaToken::Assert, s7); + + machine.addTransition(s5, XsdSchemaToken::Attribute, s5); + machine.addTransition(s5, XsdSchemaToken::AttributeGroup, s5); + machine.addTransition(s5, XsdSchemaToken::AnyAttribute, s6); + machine.addTransition(s5, XsdSchemaToken::Assert, s7); + + machine.addTransition(s6, XsdSchemaToken::Assert, s7); + + machine.addTransition(s7, XsdSchemaToken::Assert, s7); + + m_stateMachines.insert(XsdTagScope::GlobalComplexType, machine); + m_stateMachines.insert(XsdTagScope::LocalComplexType, machine); + } + + { + XsdStateMachine machine(m_namePool); + + // setup state machine for (annotation?, (restriction | extension)) : simpleContent/complexContent + const XsdStateMachine::StateId startState = machine.addState(XsdStateMachine::StartState); + const XsdStateMachine::StateId s1 = machine.addState(XsdStateMachine::InternalState); + const XsdStateMachine::StateId s2 = machine.addState(XsdStateMachine::EndState); + + machine.addTransition(startState, XsdSchemaToken::Annotation, s1); + machine.addTransition(startState, XsdSchemaToken::Restriction, s2); + machine.addTransition(startState, XsdSchemaToken::Extension, s2); + + machine.addTransition(s1, XsdSchemaToken::Restriction, s2); + machine.addTransition(s1, XsdSchemaToken::Extension, s2); + + m_stateMachines.insert(XsdTagScope::SimpleContent, machine); + m_stateMachines.insert(XsdTagScope::ComplexContent, machine); + } + + { + XsdStateMachine machine(m_namePool); + + // setup state machine for (annotation?, (simpleType?, (minExclusive | minInclusive | maxExclusive | maxInclusive | totalDigits | fractionDigits | length | minLength | maxLength | enumeration | whiteSpace | pattern | assertion)*)?, ((attribute | attributeGroup)*, anyAttribute?), assert*) : simpleContent restriction + const XsdStateMachine::StateId startState = machine.addState(XsdStateMachine::StartEndState); + const XsdStateMachine::StateId s1 = machine.addState(XsdStateMachine::EndState); + const XsdStateMachine::StateId s2 = machine.addState(XsdStateMachine::EndState); + const XsdStateMachine::StateId s3 = machine.addState(XsdStateMachine::EndState); + const XsdStateMachine::StateId s4 = machine.addState(XsdStateMachine::EndState); + const XsdStateMachine::StateId s5 = machine.addState(XsdStateMachine::EndState); + const XsdStateMachine::StateId s6 = machine.addState(XsdStateMachine::EndState); + + machine.addTransition(startState, XsdSchemaToken::Annotation, s1); + machine.addTransition(startState, XsdSchemaToken::SimpleType, s2); + machine.addTransition(startState, XsdSchemaToken::MinExclusive, s3); + machine.addTransition(startState, XsdSchemaToken::MinInclusive, s3); + machine.addTransition(startState, XsdSchemaToken::MaxExclusive, s3); + machine.addTransition(startState, XsdSchemaToken::MaxInclusive, s3); + machine.addTransition(startState, XsdSchemaToken::TotalDigits, s3); + machine.addTransition(startState, XsdSchemaToken::FractionDigits, s3); + machine.addTransition(startState, XsdSchemaToken::Length, s3); + machine.addTransition(startState, XsdSchemaToken::MinLength, s3); + machine.addTransition(startState, XsdSchemaToken::MaxLength, s3); + machine.addTransition(startState, XsdSchemaToken::Enumeration, s3); + machine.addTransition(startState, XsdSchemaToken::WhiteSpace, s3); + machine.addTransition(startState, XsdSchemaToken::Pattern, s3); + machine.addTransition(startState, XsdSchemaToken::Assertion, s3); + machine.addTransition(startState, XsdSchemaToken::Attribute, s4); + machine.addTransition(startState, XsdSchemaToken::AttributeGroup, s4); + machine.addTransition(startState, XsdSchemaToken::AnyAttribute, s5); + machine.addTransition(startState, XsdSchemaToken::Assert, s6); + + machine.addTransition(s1, XsdSchemaToken::SimpleType, s2); + machine.addTransition(s1, XsdSchemaToken::MinExclusive, s3); + machine.addTransition(s1, XsdSchemaToken::MinInclusive, s3); + machine.addTransition(s1, XsdSchemaToken::MaxExclusive, s3); + machine.addTransition(s1, XsdSchemaToken::MaxInclusive, s3); + machine.addTransition(s1, XsdSchemaToken::TotalDigits, s3); + machine.addTransition(s1, XsdSchemaToken::FractionDigits, s3); + machine.addTransition(s1, XsdSchemaToken::Length, s3); + machine.addTransition(s1, XsdSchemaToken::MinLength, s3); + machine.addTransition(s1, XsdSchemaToken::MaxLength, s3); + machine.addTransition(s1, XsdSchemaToken::Enumeration, s3); + machine.addTransition(s1, XsdSchemaToken::WhiteSpace, s3); + machine.addTransition(s1, XsdSchemaToken::Pattern, s3); + machine.addTransition(s1, XsdSchemaToken::Assertion, s3); + machine.addTransition(s1, XsdSchemaToken::Attribute, s4); + machine.addTransition(s1, XsdSchemaToken::AttributeGroup, s4); + machine.addTransition(s1, XsdSchemaToken::AnyAttribute, s5); + machine.addTransition(s1, XsdSchemaToken::Assert, s6); + + machine.addTransition(s2, XsdSchemaToken::MinExclusive, s3); + machine.addTransition(s2, XsdSchemaToken::MinInclusive, s3); + machine.addTransition(s2, XsdSchemaToken::MaxExclusive, s3); + machine.addTransition(s2, XsdSchemaToken::MaxInclusive, s3); + machine.addTransition(s2, XsdSchemaToken::TotalDigits, s3); + machine.addTransition(s2, XsdSchemaToken::FractionDigits, s3); + machine.addTransition(s2, XsdSchemaToken::Length, s3); + machine.addTransition(s2, XsdSchemaToken::MinLength, s3); + machine.addTransition(s2, XsdSchemaToken::MaxLength, s3); + machine.addTransition(s2, XsdSchemaToken::Enumeration, s3); + machine.addTransition(s2, XsdSchemaToken::WhiteSpace, s3); + machine.addTransition(s2, XsdSchemaToken::Pattern, s3); + machine.addTransition(s2, XsdSchemaToken::Assertion, s3); + machine.addTransition(s2, XsdSchemaToken::Attribute, s4); + machine.addTransition(s2, XsdSchemaToken::AttributeGroup, s4); + machine.addTransition(s2, XsdSchemaToken::AnyAttribute, s5); + machine.addTransition(s2, XsdSchemaToken::Assert, s6); + + machine.addTransition(s3, XsdSchemaToken::MinExclusive, s3); + machine.addTransition(s3, XsdSchemaToken::MinInclusive, s3); + machine.addTransition(s3, XsdSchemaToken::MaxExclusive, s3); + machine.addTransition(s3, XsdSchemaToken::MaxInclusive, s3); + machine.addTransition(s3, XsdSchemaToken::TotalDigits, s3); + machine.addTransition(s3, XsdSchemaToken::FractionDigits, s3); + machine.addTransition(s3, XsdSchemaToken::Length, s3); + machine.addTransition(s3, XsdSchemaToken::MinLength, s3); + machine.addTransition(s3, XsdSchemaToken::MaxLength, s3); + machine.addTransition(s3, XsdSchemaToken::Enumeration, s3); + machine.addTransition(s3, XsdSchemaToken::WhiteSpace, s3); + machine.addTransition(s3, XsdSchemaToken::Pattern, s3); + machine.addTransition(s3, XsdSchemaToken::Assertion, s3); + machine.addTransition(s3, XsdSchemaToken::Attribute, s4); + machine.addTransition(s3, XsdSchemaToken::AttributeGroup, s4); + machine.addTransition(s3, XsdSchemaToken::AnyAttribute, s5); + machine.addTransition(s3, XsdSchemaToken::Assert, s6); + + machine.addTransition(s4, XsdSchemaToken::Attribute, s4); + machine.addTransition(s4, XsdSchemaToken::AttributeGroup, s4); + machine.addTransition(s4, XsdSchemaToken::AnyAttribute, s5); + machine.addTransition(s4, XsdSchemaToken::Assert, s6); + + machine.addTransition(s5, XsdSchemaToken::Assert, s6); + + machine.addTransition(s6, XsdSchemaToken::Assert, s6); + + m_stateMachines.insert(XsdTagScope::SimpleContentRestriction, machine); + } + + { + XsdStateMachine machine(m_namePool); + + // setup state machine for (annotation?, ((attribute | attributeGroup)*, anyAttribute?), assert*) : simple content extension + const XsdStateMachine::StateId startState = machine.addState(XsdStateMachine::StartEndState); + const XsdStateMachine::StateId s1 = machine.addState(XsdStateMachine::EndState); + const XsdStateMachine::StateId s2 = machine.addState(XsdStateMachine::EndState); + const XsdStateMachine::StateId s3 = machine.addState(XsdStateMachine::EndState); + const XsdStateMachine::StateId s4 = machine.addState(XsdStateMachine::EndState); + + machine.addTransition(startState, XsdSchemaToken::Annotation, s1); + machine.addTransition(startState, XsdSchemaToken::Attribute, s2); + machine.addTransition(startState, XsdSchemaToken::AttributeGroup, s2); + machine.addTransition(startState, XsdSchemaToken::AnyAttribute, s3); + machine.addTransition(startState, XsdSchemaToken::Assert, s4); + + machine.addTransition(s1, XsdSchemaToken::Attribute, s2); + machine.addTransition(s1, XsdSchemaToken::AttributeGroup, s2); + machine.addTransition(s1, XsdSchemaToken::AnyAttribute, s3); + machine.addTransition(s1, XsdSchemaToken::Assert, s4); + + machine.addTransition(s2, XsdSchemaToken::Attribute, s2); + machine.addTransition(s2, XsdSchemaToken::AttributeGroup, s2); + machine.addTransition(s2, XsdSchemaToken::AnyAttribute, s3); + machine.addTransition(s2, XsdSchemaToken::Assert, s4); + + machine.addTransition(s3, XsdSchemaToken::Assert, s4); + + machine.addTransition(s4, XsdSchemaToken::Assert, s4); + + m_stateMachines.insert(XsdTagScope::SimpleContentExtension, machine); + } + + { + XsdStateMachine machine(m_namePool); + + // setup state machine for (annotation?, openContent?, ((group | all | choice | sequence)?, ((attribute | attributeGroup)*, anyAttribute?), assert*)) : complex content restriction/complex content extension + const XsdStateMachine::StateId startState = machine.addState(XsdStateMachine::StartEndState); + const XsdStateMachine::StateId s1 = machine.addState(XsdStateMachine::EndState); + const XsdStateMachine::StateId s2 = machine.addState(XsdStateMachine::EndState); + const XsdStateMachine::StateId s3 = machine.addState(XsdStateMachine::EndState); + const XsdStateMachine::StateId s4 = machine.addState(XsdStateMachine::EndState); + const XsdStateMachine::StateId s5 = machine.addState(XsdStateMachine::EndState); + const XsdStateMachine::StateId s6 = machine.addState(XsdStateMachine::EndState); + + machine.addTransition(startState, XsdSchemaToken::Annotation, s1); + machine.addTransition(startState, XsdSchemaToken::OpenContent, s2); + machine.addTransition(startState, XsdSchemaToken::Group, s3); + machine.addTransition(startState, XsdSchemaToken::All, s3); + machine.addTransition(startState, XsdSchemaToken::Choice, s3); + machine.addTransition(startState, XsdSchemaToken::Sequence, s3); + machine.addTransition(startState, XsdSchemaToken::Attribute, s4); + machine.addTransition(startState, XsdSchemaToken::AttributeGroup, s4); + machine.addTransition(startState, XsdSchemaToken::AnyAttribute, s5); + machine.addTransition(startState, XsdSchemaToken::Assert, s6); + + machine.addTransition(s1, XsdSchemaToken::OpenContent, s2); + machine.addTransition(s1, XsdSchemaToken::Group, s3); + machine.addTransition(s1, XsdSchemaToken::All, s3); + machine.addTransition(s1, XsdSchemaToken::Choice, s3); + machine.addTransition(s1, XsdSchemaToken::Sequence, s3); + machine.addTransition(s1, XsdSchemaToken::Attribute, s4); + machine.addTransition(s1, XsdSchemaToken::AttributeGroup, s4); + machine.addTransition(s1, XsdSchemaToken::AnyAttribute, s5); + machine.addTransition(s1, XsdSchemaToken::Assert, s6); + + machine.addTransition(s2, XsdSchemaToken::Group, s3); + machine.addTransition(s2, XsdSchemaToken::All, s3); + machine.addTransition(s2, XsdSchemaToken::Choice, s3); + machine.addTransition(s2, XsdSchemaToken::Sequence, s3); + machine.addTransition(s2, XsdSchemaToken::Attribute, s4); + machine.addTransition(s2, XsdSchemaToken::AttributeGroup, s4); + machine.addTransition(s2, XsdSchemaToken::AnyAttribute, s5); + machine.addTransition(s2, XsdSchemaToken::Assert, s6); + + machine.addTransition(s3, XsdSchemaToken::Attribute, s4); + machine.addTransition(s3, XsdSchemaToken::AttributeGroup, s4); + machine.addTransition(s3, XsdSchemaToken::AnyAttribute, s5); + machine.addTransition(s3, XsdSchemaToken::Assert, s6); + + machine.addTransition(s4, XsdSchemaToken::Attribute, s4); + machine.addTransition(s4, XsdSchemaToken::AttributeGroup, s4); + machine.addTransition(s4, XsdSchemaToken::AnyAttribute, s5); + machine.addTransition(s4, XsdSchemaToken::Assert, s6); + + machine.addTransition(s5, XsdSchemaToken::Assert, s6); + + machine.addTransition(s6, XsdSchemaToken::Assert, s6); + + m_stateMachines.insert(XsdTagScope::ComplexContentRestriction, machine); + m_stateMachines.insert(XsdTagScope::ComplexContentExtension, machine); + } + + { + XsdStateMachine machine(m_namePool); + + // setup state machine for (annotation?, ((attribute | attributeGroup)*, anyAttribute?)) : named attribute group + const XsdStateMachine::StateId startState = machine.addState(XsdStateMachine::StartEndState); + const XsdStateMachine::StateId s1 = machine.addState(XsdStateMachine::EndState); + const XsdStateMachine::StateId s2 = machine.addState(XsdStateMachine::EndState); + const XsdStateMachine::StateId s3 = machine.addState(XsdStateMachine::EndState); + + machine.addTransition(startState, XsdSchemaToken::Annotation, s1); + machine.addTransition(startState, XsdSchemaToken::Attribute, s2); + machine.addTransition(startState, XsdSchemaToken::AttributeGroup, s2); + machine.addTransition(startState, XsdSchemaToken::AnyAttribute, s3); + + machine.addTransition(s1, XsdSchemaToken::Attribute, s2); + machine.addTransition(s1, XsdSchemaToken::AttributeGroup, s2); + machine.addTransition(s1, XsdSchemaToken::AnyAttribute, s3); + + machine.addTransition(s2, XsdSchemaToken::Attribute, s2); + machine.addTransition(s2, XsdSchemaToken::AttributeGroup, s2); + machine.addTransition(s2, XsdSchemaToken::AnyAttribute, s3); + + m_stateMachines.insert(XsdTagScope::NamedAttributeGroup, machine); + } + + { + XsdStateMachine machine(m_namePool); + + // setup state machine for (annotation?, (all | choice | sequence)?) : group + const XsdStateMachine::StateId startState = machine.addState(XsdStateMachine::StartEndState); + const XsdStateMachine::StateId s1 = machine.addState(XsdStateMachine::EndState); + const XsdStateMachine::StateId s2 = machine.addState(XsdStateMachine::EndState); + + machine.addTransition(startState, XsdSchemaToken::Annotation, s1); + machine.addTransition(startState, XsdSchemaToken::All, s2); + machine.addTransition(startState, XsdSchemaToken::Choice, s2); + machine.addTransition(startState, XsdSchemaToken::Sequence, s2); + + machine.addTransition(s1, XsdSchemaToken::All, s2); + machine.addTransition(s1, XsdSchemaToken::Choice, s2); + machine.addTransition(s1, XsdSchemaToken::Sequence, s2); + + m_stateMachines.insert(XsdTagScope::NamedGroup, machine); + m_stateMachines.insert(XsdTagScope::ReferredGroup, machine); + } + + { + XsdStateMachine machine(m_namePool); + + // setup state machine for (annotation?, (element | any)*) : all + const XsdStateMachine::StateId startState = machine.addState(XsdStateMachine::StartEndState); + const XsdStateMachine::StateId s1 = machine.addState(XsdStateMachine::EndState); + const XsdStateMachine::StateId s2 = machine.addState(XsdStateMachine::EndState); + + machine.addTransition(startState, XsdSchemaToken::Annotation, s1); + machine.addTransition(startState, XsdSchemaToken::Element, s2); + machine.addTransition(startState, XsdSchemaToken::Any, s2); + + machine.addTransition(s1, XsdSchemaToken::Element, s2); + machine.addTransition(s1, XsdSchemaToken::Any, s2); + + machine.addTransition(s2, XsdSchemaToken::Element, s2); + machine.addTransition(s2, XsdSchemaToken::Any, s2); + + m_stateMachines.insert(XsdTagScope::All, machine); + m_stateMachines.insert(XsdTagScope::LocalAll, machine); + } + + { + XsdStateMachine machine(m_namePool); + + // setup state machine for (annotation?, (element | group | choice | sequence | any)*) : choice sequence + const XsdStateMachine::StateId startState = machine.addState(XsdStateMachine::StartEndState); + const XsdStateMachine::StateId s1 = machine.addState(XsdStateMachine::EndState); + const XsdStateMachine::StateId s2 = machine.addState(XsdStateMachine::EndState); + + machine.addTransition(startState, XsdSchemaToken::Annotation, s1); + machine.addTransition(startState, XsdSchemaToken::Element, s2); + machine.addTransition(startState, XsdSchemaToken::Group, s2); + machine.addTransition(startState, XsdSchemaToken::Choice, s2); + machine.addTransition(startState, XsdSchemaToken::Sequence, s2); + machine.addTransition(startState, XsdSchemaToken::Any, s2); + + machine.addTransition(s1, XsdSchemaToken::Element, s2); + machine.addTransition(s1, XsdSchemaToken::Group, s2); + machine.addTransition(s1, XsdSchemaToken::Choice, s2); + machine.addTransition(s1, XsdSchemaToken::Sequence, s2); + machine.addTransition(s1, XsdSchemaToken::Any, s2); + + machine.addTransition(s2, XsdSchemaToken::Element, s2); + machine.addTransition(s2, XsdSchemaToken::Group, s2); + machine.addTransition(s2, XsdSchemaToken::Choice, s2); + machine.addTransition(s2, XsdSchemaToken::Sequence, s2); + machine.addTransition(s2, XsdSchemaToken::Any, s2); + + m_stateMachines.insert(XsdTagScope::Choice, machine); + m_stateMachines.insert(XsdTagScope::LocalChoice, machine); + m_stateMachines.insert(XsdTagScope::Sequence, machine); + m_stateMachines.insert(XsdTagScope::LocalSequence, machine); + } + + { + XsdStateMachine machine(m_namePool); + + // setup state machine for (annotation?) : any/selector/field/notation/include/import/referred attribute group/anyAttribute/all facets/assert + const XsdStateMachine::StateId startState = machine.addState(XsdStateMachine::StartEndState); + const XsdStateMachine::StateId s1 = machine.addState(XsdStateMachine::EndState); + + machine.addTransition(startState, XsdSchemaToken::Annotation, s1); + + m_stateMachines.insert(XsdTagScope::Any, machine); + m_stateMachines.insert(XsdTagScope::Selector, machine); + m_stateMachines.insert(XsdTagScope::Field, machine); + m_stateMachines.insert(XsdTagScope::Notation, machine); + m_stateMachines.insert(XsdTagScope::Include, machine); + m_stateMachines.insert(XsdTagScope::Import, machine); + m_stateMachines.insert(XsdTagScope::ReferredAttributeGroup, machine); + m_stateMachines.insert(XsdTagScope::AnyAttribute, machine); + m_stateMachines.insert(XsdTagScope::MinExclusiveFacet, machine); + m_stateMachines.insert(XsdTagScope::MinInclusiveFacet, machine); + m_stateMachines.insert(XsdTagScope::MaxExclusiveFacet, machine); + m_stateMachines.insert(XsdTagScope::MaxInclusiveFacet, machine); + m_stateMachines.insert(XsdTagScope::TotalDigitsFacet, machine); + m_stateMachines.insert(XsdTagScope::FractionDigitsFacet, machine); + m_stateMachines.insert(XsdTagScope::LengthFacet, machine); + m_stateMachines.insert(XsdTagScope::MinLengthFacet, machine); + m_stateMachines.insert(XsdTagScope::MaxLengthFacet, machine); + m_stateMachines.insert(XsdTagScope::EnumerationFacet, machine); + m_stateMachines.insert(XsdTagScope::WhiteSpaceFacet, machine); + m_stateMachines.insert(XsdTagScope::PatternFacet, machine); + m_stateMachines.insert(XsdTagScope::Assert, machine); + m_stateMachines.insert(XsdTagScope::Assertion, machine); + } + + { + XsdStateMachine machine(m_namePool); + + // setup state machine for (annotation?, (selector, field+)) : unique/key/keyref + const XsdStateMachine::StateId startState = machine.addState(XsdStateMachine::StartState); + const XsdStateMachine::StateId s1 = machine.addState(XsdStateMachine::InternalState); + const XsdStateMachine::StateId s2 = machine.addState(XsdStateMachine::InternalState); + const XsdStateMachine::StateId s3 = machine.addState(XsdStateMachine::EndState); + + machine.addTransition(startState, XsdSchemaToken::Annotation, s1); + machine.addTransition(startState, XsdSchemaToken::Selector, s2); + + machine.addTransition(s1, XsdSchemaToken::Selector, s2); + machine.addTransition(s2, XsdSchemaToken::Field, s3); + machine.addTransition(s3, XsdSchemaToken::Field, s3); + + m_stateMachines.insert(XsdTagScope::Unique, machine); + m_stateMachines.insert(XsdTagScope::Key, machine); + m_stateMachines.insert(XsdTagScope::KeyRef, machine); + } + + { + XsdStateMachine machine(m_namePool); + + // setup state machine for (annotation?, (simpleType | complexType)?) : alternative + const XsdStateMachine::StateId startState = machine.addState(XsdStateMachine::StartEndState); + const XsdStateMachine::StateId s1 = machine.addState(XsdStateMachine::EndState); + const XsdStateMachine::StateId s2 = machine.addState(XsdStateMachine::EndState); + + machine.addTransition(startState, XsdSchemaToken::Annotation, s1); + machine.addTransition(startState, XsdSchemaToken::SimpleType, s2); + machine.addTransition(startState, XsdSchemaToken::ComplexType, s2); + + machine.addTransition(s1, XsdSchemaToken::SimpleType, s2); + machine.addTransition(s1, XsdSchemaToken::ComplexType, s2); + + m_stateMachines.insert(XsdTagScope::Alternative, machine); + } + + { + XsdStateMachine machine(m_namePool); + + // setup state machine for (appinfo | documentation)* : annotation + const XsdStateMachine::StateId startState = machine.addState(XsdStateMachine::StartEndState); + const XsdStateMachine::StateId s1 = machine.addState(XsdStateMachine::EndState); + + machine.addTransition(startState, XsdSchemaToken::Appinfo, s1); + machine.addTransition(startState, XsdSchemaToken::Documentation, s1); + + machine.addTransition(s1, XsdSchemaToken::Appinfo, s1); + machine.addTransition(s1, XsdSchemaToken::Documentation, s1); + + m_stateMachines.insert(XsdTagScope::Annotation, machine); + } + + { + XsdStateMachine machine(m_namePool); + + // setup state machine for (annotation?, (restriction | list | union)) : simpleType + const XsdStateMachine::StateId startState = machine.addState(XsdStateMachine::StartState); + const XsdStateMachine::StateId s1 = machine.addState(XsdStateMachine::InternalState); + const XsdStateMachine::StateId s2 = machine.addState(XsdStateMachine::EndState); + + machine.addTransition(startState, XsdSchemaToken::Annotation, s1); + machine.addTransition(startState, XsdSchemaToken::Restriction, s2); + machine.addTransition(startState, XsdSchemaToken::List, s2); + machine.addTransition(startState, XsdSchemaToken::Union, s2); + + machine.addTransition(s1, XsdSchemaToken::Restriction, s2); + machine.addTransition(s1, XsdSchemaToken::List, s2); + machine.addTransition(s1, XsdSchemaToken::Union, s2); + + m_stateMachines.insert(XsdTagScope::GlobalSimpleType, machine); + m_stateMachines.insert(XsdTagScope::LocalSimpleType, machine); + } + + { + XsdStateMachine machine(m_namePool); + + // setup state machine for (annotation?, (simpleType?, (minExclusive | minInclusive | maxExclusive | maxInclusive | totalDigits | fractionDigits | length | minLength | maxLength | enumeration | whiteSpace | pattern | assertion)*)) : simple type restriction + const XsdStateMachine::StateId startState = machine.addState(XsdStateMachine::StartEndState); + const XsdStateMachine::StateId s1 = machine.addState(XsdStateMachine::EndState); + const XsdStateMachine::StateId s2 = machine.addState(XsdStateMachine::EndState); + const XsdStateMachine::StateId s3 = machine.addState(XsdStateMachine::EndState); + + machine.addTransition(startState, XsdSchemaToken::Annotation, s1); + machine.addTransition(startState, XsdSchemaToken::SimpleType, s2); + machine.addTransition(startState, XsdSchemaToken::MinExclusive, s3); + machine.addTransition(startState, XsdSchemaToken::MinInclusive, s3); + machine.addTransition(startState, XsdSchemaToken::MaxExclusive, s3); + machine.addTransition(startState, XsdSchemaToken::MaxInclusive, s3); + machine.addTransition(startState, XsdSchemaToken::TotalDigits, s3); + machine.addTransition(startState, XsdSchemaToken::FractionDigits, s3); + machine.addTransition(startState, XsdSchemaToken::Length, s3); + machine.addTransition(startState, XsdSchemaToken::MinLength, s3); + machine.addTransition(startState, XsdSchemaToken::MaxLength, s3); + machine.addTransition(startState, XsdSchemaToken::Enumeration, s3); + machine.addTransition(startState, XsdSchemaToken::WhiteSpace, s3); + machine.addTransition(startState, XsdSchemaToken::Pattern, s3); + machine.addTransition(startState, XsdSchemaToken::Assertion, s3); + + machine.addTransition(s1, XsdSchemaToken::SimpleType, s2); + machine.addTransition(s1, XsdSchemaToken::MinExclusive, s3); + machine.addTransition(s1, XsdSchemaToken::MinInclusive, s3); + machine.addTransition(s1, XsdSchemaToken::MaxExclusive, s3); + machine.addTransition(s1, XsdSchemaToken::MaxInclusive, s3); + machine.addTransition(s1, XsdSchemaToken::TotalDigits, s3); + machine.addTransition(s1, XsdSchemaToken::FractionDigits, s3); + machine.addTransition(s1, XsdSchemaToken::Length, s3); + machine.addTransition(s1, XsdSchemaToken::MinLength, s3); + machine.addTransition(s1, XsdSchemaToken::MaxLength, s3); + machine.addTransition(s1, XsdSchemaToken::Enumeration, s3); + machine.addTransition(s1, XsdSchemaToken::WhiteSpace, s3); + machine.addTransition(s1, XsdSchemaToken::Pattern, s3); + machine.addTransition(s1, XsdSchemaToken::Assertion, s3); + + machine.addTransition(s2, XsdSchemaToken::MinExclusive, s3); + machine.addTransition(s2, XsdSchemaToken::MinInclusive, s3); + machine.addTransition(s2, XsdSchemaToken::MaxExclusive, s3); + machine.addTransition(s2, XsdSchemaToken::MaxInclusive, s3); + machine.addTransition(s2, XsdSchemaToken::TotalDigits, s3); + machine.addTransition(s2, XsdSchemaToken::FractionDigits, s3); + machine.addTransition(s2, XsdSchemaToken::Length, s3); + machine.addTransition(s2, XsdSchemaToken::MinLength, s3); + machine.addTransition(s2, XsdSchemaToken::MaxLength, s3); + machine.addTransition(s2, XsdSchemaToken::Enumeration, s3); + machine.addTransition(s2, XsdSchemaToken::WhiteSpace, s3); + machine.addTransition(s2, XsdSchemaToken::Pattern, s3); + machine.addTransition(s2, XsdSchemaToken::Assertion, s3); + + machine.addTransition(s3, XsdSchemaToken::MinExclusive, s3); + machine.addTransition(s3, XsdSchemaToken::MinInclusive, s3); + machine.addTransition(s3, XsdSchemaToken::MaxExclusive, s3); + machine.addTransition(s3, XsdSchemaToken::MaxInclusive, s3); + machine.addTransition(s3, XsdSchemaToken::TotalDigits, s3); + machine.addTransition(s3, XsdSchemaToken::FractionDigits, s3); + machine.addTransition(s3, XsdSchemaToken::Length, s3); + machine.addTransition(s3, XsdSchemaToken::MinLength, s3); + machine.addTransition(s3, XsdSchemaToken::MaxLength, s3); + machine.addTransition(s3, XsdSchemaToken::Enumeration, s3); + machine.addTransition(s3, XsdSchemaToken::WhiteSpace, s3); + machine.addTransition(s3, XsdSchemaToken::Pattern, s3); + machine.addTransition(s3, XsdSchemaToken::Assertion, s3); + + m_stateMachines.insert(XsdTagScope::SimpleRestriction, machine); + } + + { + XsdStateMachine machine(m_namePool); + + // setup state machine for (annotation?, simpleType?) : list + const XsdStateMachine::StateId startState = machine.addState(XsdStateMachine::StartEndState); + const XsdStateMachine::StateId s1 = machine.addState(XsdStateMachine::EndState); + const XsdStateMachine::StateId s2 = machine.addState(XsdStateMachine::EndState); + + machine.addTransition(startState, XsdSchemaToken::Annotation, s1); + machine.addTransition(startState, XsdSchemaToken::SimpleType, s2); + + machine.addTransition(s1, XsdSchemaToken::SimpleType, s2); + + m_stateMachines.insert(XsdTagScope::List, machine); + } + + { + XsdStateMachine machine(m_namePool); + + // setup state machine for (annotation?, simpleType*) : union + const XsdStateMachine::StateId startState = machine.addState(XsdStateMachine::StartEndState); + const XsdStateMachine::StateId s1 = machine.addState(XsdStateMachine::EndState); + const XsdStateMachine::StateId s2 = machine.addState(XsdStateMachine::EndState); + + machine.addTransition(startState, XsdSchemaToken::Annotation, s1); + machine.addTransition(startState, XsdSchemaToken::SimpleType, s2); + + machine.addTransition(s1, XsdSchemaToken::SimpleType, s2); + machine.addTransition(s2, XsdSchemaToken::SimpleType, s2); + + m_stateMachines.insert(XsdTagScope::Union, machine); + } + + { + XsdStateMachine machine(m_namePool); + + // setup state machine for ((include | import | redefine |i override | annotation)*, (defaultOpenContent, annotation*)?, (((simpleType | complexType | group | attributeGroup) | element | attribute | notation), annotation*)*) : schema + const XsdStateMachine::StateId startState = machine.addState(XsdStateMachine::StartEndState); + const XsdStateMachine::StateId s1 = machine.addState(XsdStateMachine::EndState); + const XsdStateMachine::StateId s2 = machine.addState(XsdStateMachine::EndState); + const XsdStateMachine::StateId s3 = machine.addState(XsdStateMachine::EndState); + const XsdStateMachine::StateId s4 = machine.addState(XsdStateMachine::EndState); + const XsdStateMachine::StateId s5 = machine.addState(XsdStateMachine::EndState); + + machine.addTransition(startState, XsdSchemaToken::Include, s1); + machine.addTransition(startState, XsdSchemaToken::Import, s1); + machine.addTransition(startState, XsdSchemaToken::Redefine, s1); + machine.addTransition(startState, XsdSchemaToken::Override, s1); + machine.addTransition(startState, XsdSchemaToken::Annotation, s1); + machine.addTransition(startState, XsdSchemaToken::DefaultOpenContent, s2); + machine.addTransition(startState, XsdSchemaToken::SimpleType, s4); + machine.addTransition(startState, XsdSchemaToken::ComplexType, s4); + machine.addTransition(startState, XsdSchemaToken::Group, s4); + machine.addTransition(startState, XsdSchemaToken::AttributeGroup, s4); + machine.addTransition(startState, XsdSchemaToken::Element, s4); + machine.addTransition(startState, XsdSchemaToken::Attribute, s4); + machine.addTransition(startState, XsdSchemaToken::Notation, s4); + + machine.addTransition(s1, XsdSchemaToken::Include, s1); + machine.addTransition(s1, XsdSchemaToken::Import, s1); + machine.addTransition(s1, XsdSchemaToken::Redefine, s1); + machine.addTransition(s1, XsdSchemaToken::Override, s1); + machine.addTransition(s1, XsdSchemaToken::Annotation, s1); + machine.addTransition(s1, XsdSchemaToken::DefaultOpenContent, s2); + machine.addTransition(s1, XsdSchemaToken::SimpleType, s4); + machine.addTransition(s1, XsdSchemaToken::ComplexType, s4); + machine.addTransition(s1, XsdSchemaToken::Group, s4); + machine.addTransition(s1, XsdSchemaToken::AttributeGroup, s4); + machine.addTransition(s1, XsdSchemaToken::Element, s4); + machine.addTransition(s1, XsdSchemaToken::Attribute, s4); + machine.addTransition(s1, XsdSchemaToken::Notation, s4); + + machine.addTransition(s2, XsdSchemaToken::Annotation, s3); + machine.addTransition(s2, XsdSchemaToken::SimpleType, s4); + machine.addTransition(s2, XsdSchemaToken::ComplexType, s4); + machine.addTransition(s2, XsdSchemaToken::Group, s4); + machine.addTransition(s2, XsdSchemaToken::AttributeGroup, s4); + machine.addTransition(s2, XsdSchemaToken::Element, s4); + machine.addTransition(s2, XsdSchemaToken::Attribute, s4); + machine.addTransition(s2, XsdSchemaToken::Notation, s4); + + machine.addTransition(s3, XsdSchemaToken::SimpleType, s4); + machine.addTransition(s3, XsdSchemaToken::ComplexType, s4); + machine.addTransition(s3, XsdSchemaToken::Group, s4); + machine.addTransition(s3, XsdSchemaToken::AttributeGroup, s4); + machine.addTransition(s3, XsdSchemaToken::Element, s4); + machine.addTransition(s3, XsdSchemaToken::Attribute, s4); + machine.addTransition(s3, XsdSchemaToken::Notation, s4); + + machine.addTransition(s4, XsdSchemaToken::SimpleType, s4); + machine.addTransition(s4, XsdSchemaToken::ComplexType, s4); + machine.addTransition(s4, XsdSchemaToken::Group, s4); + machine.addTransition(s4, XsdSchemaToken::AttributeGroup, s4); + machine.addTransition(s4, XsdSchemaToken::Element, s4); + machine.addTransition(s4, XsdSchemaToken::Attribute, s4); + machine.addTransition(s4, XsdSchemaToken::Notation, s4); + machine.addTransition(s4, XsdSchemaToken::Annotation, s5); + + machine.addTransition(s5, XsdSchemaToken::SimpleType, s4); + machine.addTransition(s5, XsdSchemaToken::ComplexType, s4); + machine.addTransition(s5, XsdSchemaToken::Group, s4); + machine.addTransition(s5, XsdSchemaToken::AttributeGroup, s4); + machine.addTransition(s5, XsdSchemaToken::Element, s4); + machine.addTransition(s5, XsdSchemaToken::Attribute, s4); + machine.addTransition(s5, XsdSchemaToken::Notation, s4); + machine.addTransition(s5, XsdSchemaToken::Annotation, s5); + + m_stateMachines.insert(XsdTagScope::Schema, machine); + } + + { + XsdStateMachine machine(m_namePool); + + // setup state machine for (annotation?, any) : defaultOpenContent + const XsdStateMachine::StateId startState = machine.addState(XsdStateMachine::StartEndState); + const XsdStateMachine::StateId s1 = machine.addState(XsdStateMachine::InternalState); + const XsdStateMachine::StateId s2 = machine.addState(XsdStateMachine::EndState); + + machine.addTransition(startState, XsdSchemaToken::Annotation, s1); + machine.addTransition(startState, XsdSchemaToken::Any, s2); + + machine.addTransition(s1, XsdSchemaToken::Any, s2); + + m_stateMachines.insert(XsdTagScope::DefaultOpenContent, machine); + } + + { + XsdStateMachine machine(m_namePool); + + // setup state machine for (annotation | (simpleType | complexType | group | attributeGroup))* : redefine + const XsdStateMachine::StateId startState = machine.addState(XsdStateMachine::StartEndState); + const XsdStateMachine::StateId s1 = machine.addState(XsdStateMachine::EndState); + + machine.addTransition(startState, XsdSchemaToken::Annotation, s1); + machine.addTransition(startState, XsdSchemaToken::SimpleType, s1); + machine.addTransition(startState, XsdSchemaToken::ComplexType, s1); + machine.addTransition(startState, XsdSchemaToken::Group, s1); + machine.addTransition(startState, XsdSchemaToken::AttributeGroup, s1); + + machine.addTransition(s1, XsdSchemaToken::Annotation, s1); + machine.addTransition(s1, XsdSchemaToken::SimpleType, s1); + machine.addTransition(s1, XsdSchemaToken::ComplexType, s1); + machine.addTransition(s1, XsdSchemaToken::Group, s1); + machine.addTransition(s1, XsdSchemaToken::AttributeGroup, s1); + + m_stateMachines.insert(XsdTagScope::Redefine, machine); + } + + { + XsdStateMachine machine(m_namePool); + + // setup state machine for (annotation | (simpleType | complexType | group | attributeGroup | element | attribute | notation))* : override + const XsdStateMachine::StateId startState = machine.addState(XsdStateMachine::StartEndState); + const XsdStateMachine::StateId s1 = machine.addState(XsdStateMachine::EndState); + + machine.addTransition(startState, XsdSchemaToken::Annotation, s1); + machine.addTransition(startState, XsdSchemaToken::SimpleType, s1); + machine.addTransition(startState, XsdSchemaToken::ComplexType, s1); + machine.addTransition(startState, XsdSchemaToken::Group, s1); + machine.addTransition(startState, XsdSchemaToken::AttributeGroup, s1); + machine.addTransition(startState, XsdSchemaToken::Element, s1); + machine.addTransition(startState, XsdSchemaToken::Attribute, s1); + machine.addTransition(startState, XsdSchemaToken::Notation, s1); + + machine.addTransition(s1, XsdSchemaToken::Annotation, s1); + machine.addTransition(s1, XsdSchemaToken::SimpleType, s1); + machine.addTransition(s1, XsdSchemaToken::ComplexType, s1); + machine.addTransition(s1, XsdSchemaToken::Group, s1); + machine.addTransition(s1, XsdSchemaToken::AttributeGroup, s1); + machine.addTransition(s1, XsdSchemaToken::Element, s1); + machine.addTransition(s1, XsdSchemaToken::Attribute, s1); + machine.addTransition(s1, XsdSchemaToken::Notation, s1); + + m_stateMachines.insert(XsdTagScope::Override, machine); + } +} + +void XsdSchemaParser::setupBuiltinTypeNames() +{ + m_builtinTypeNames.reserve(48); + + m_builtinTypeNames.insert(BuiltinTypes::xsAnyType->name(m_namePool)); + m_builtinTypeNames.insert(BuiltinTypes::xsAnySimpleType->name(m_namePool)); + m_builtinTypeNames.insert(BuiltinTypes::xsUntyped->name(m_namePool)); + m_builtinTypeNames.insert(BuiltinTypes::xsAnyAtomicType->name(m_namePool)); + m_builtinTypeNames.insert(BuiltinTypes::xsUntypedAtomic->name(m_namePool)); + m_builtinTypeNames.insert(BuiltinTypes::xsDateTime->name(m_namePool)); + m_builtinTypeNames.insert(BuiltinTypes::xsDate->name(m_namePool)); + m_builtinTypeNames.insert(BuiltinTypes::xsTime->name(m_namePool)); + m_builtinTypeNames.insert(BuiltinTypes::xsDuration->name(m_namePool)); + m_builtinTypeNames.insert(BuiltinTypes::xsYearMonthDuration->name(m_namePool)); + m_builtinTypeNames.insert(BuiltinTypes::xsDayTimeDuration->name(m_namePool)); + m_builtinTypeNames.insert(BuiltinTypes::xsFloat->name(m_namePool)); + m_builtinTypeNames.insert(BuiltinTypes::xsDouble->name(m_namePool)); + m_builtinTypeNames.insert(BuiltinTypes::xsInteger->name(m_namePool)); + m_builtinTypeNames.insert(BuiltinTypes::xsDecimal->name(m_namePool)); + m_builtinTypeNames.insert(BuiltinTypes::xsNonPositiveInteger->name(m_namePool)); + m_builtinTypeNames.insert(BuiltinTypes::xsNegativeInteger->name(m_namePool)); + m_builtinTypeNames.insert(BuiltinTypes::xsLong->name(m_namePool)); + m_builtinTypeNames.insert(BuiltinTypes::xsInt->name(m_namePool)); + m_builtinTypeNames.insert(BuiltinTypes::xsShort->name(m_namePool)); + m_builtinTypeNames.insert(BuiltinTypes::xsByte->name(m_namePool)); + m_builtinTypeNames.insert(BuiltinTypes::xsNonNegativeInteger->name(m_namePool)); + m_builtinTypeNames.insert(BuiltinTypes::xsUnsignedLong->name(m_namePool)); + m_builtinTypeNames.insert(BuiltinTypes::xsUnsignedInt->name(m_namePool)); + m_builtinTypeNames.insert(BuiltinTypes::xsUnsignedShort->name(m_namePool)); + m_builtinTypeNames.insert(BuiltinTypes::xsUnsignedByte->name(m_namePool)); + m_builtinTypeNames.insert(BuiltinTypes::xsPositiveInteger->name(m_namePool)); + m_builtinTypeNames.insert(BuiltinTypes::xsGYearMonth->name(m_namePool)); + m_builtinTypeNames.insert(BuiltinTypes::xsGYear->name(m_namePool)); + m_builtinTypeNames.insert(BuiltinTypes::xsGMonthDay->name(m_namePool)); + m_builtinTypeNames.insert(BuiltinTypes::xsGDay->name(m_namePool)); + m_builtinTypeNames.insert(BuiltinTypes::xsGMonth->name(m_namePool)); + m_builtinTypeNames.insert(BuiltinTypes::xsBoolean->name(m_namePool)); + m_builtinTypeNames.insert(BuiltinTypes::xsBase64Binary->name(m_namePool)); + m_builtinTypeNames.insert(BuiltinTypes::xsHexBinary->name(m_namePool)); + m_builtinTypeNames.insert(BuiltinTypes::xsAnyURI->name(m_namePool)); + m_builtinTypeNames.insert(BuiltinTypes::xsQName->name(m_namePool)); + m_builtinTypeNames.insert(BuiltinTypes::xsString->name(m_namePool)); + m_builtinTypeNames.insert(BuiltinTypes::xsNormalizedString->name(m_namePool)); + m_builtinTypeNames.insert(BuiltinTypes::xsToken->name(m_namePool)); + m_builtinTypeNames.insert(BuiltinTypes::xsLanguage->name(m_namePool)); + m_builtinTypeNames.insert(BuiltinTypes::xsNMTOKEN->name(m_namePool)); + m_builtinTypeNames.insert(BuiltinTypes::xsName->name(m_namePool)); + m_builtinTypeNames.insert(BuiltinTypes::xsNCName->name(m_namePool)); + m_builtinTypeNames.insert(BuiltinTypes::xsID->name(m_namePool)); + m_builtinTypeNames.insert(BuiltinTypes::xsIDREF->name(m_namePool)); + m_builtinTypeNames.insert(BuiltinTypes::xsENTITY->name(m_namePool)); + m_builtinTypeNames.insert(BuiltinTypes::xsNOTATION->name(m_namePool)); +} + +QT_END_NAMESPACE diff --git a/src/xmlpatterns/schema/qxsdschemaparsercontext.cpp b/src/xmlpatterns/schema/qxsdschemaparsercontext.cpp new file mode 100644 index 0000000..896619e --- /dev/null +++ b/src/xmlpatterns/schema/qxsdschemaparsercontext.cpp @@ -0,0 +1,573 @@ +/**************************************************************************** +** +** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the $MODULE$ of the Qt Toolkit. +** +** $TROLLTECH_DUAL_LICENSE$ +** +****************************************************************************/ + +#include "qxsdschemaparsercontext_p.h" + +QT_BEGIN_NAMESPACE + +using namespace QPatternist; + +XsdSchemaParserContext::XsdSchemaParserContext(const NamePool::Ptr &namePool, const XsdSchemaContext::Ptr &context) + : m_namePool(namePool) + , m_schema(new XsdSchema(m_namePool)) + , m_checker(new XsdSchemaChecker(context, this)) + , m_resolver(new XsdSchemaResolver(context, this)) + , m_elementDescriptions(setupElementDescriptions()) +{ +} + +NamePool::Ptr XsdSchemaParserContext::namePool() const +{ + return m_namePool; +} + +XsdSchemaResolver::Ptr XsdSchemaParserContext::resolver() const +{ + return m_resolver; +} + +XsdSchemaChecker::Ptr XsdSchemaParserContext::checker() const +{ + return m_checker; +} + +XsdSchema::Ptr XsdSchemaParserContext::schema() const +{ + return m_schema; +} + +ElementDescription::Hash XsdSchemaParserContext::elementDescriptions() const +{ + return m_elementDescriptions; +} + +QXmlName XsdSchemaParserContext::createAnonymousName(const QString &targetNamespace) const +{ + m_anonymousNameCounter.ref(); + + const QString name = QString::fromLatin1("__AnonymousClass_%1").arg((int)m_anonymousNameCounter); + + return m_namePool->allocateQName(targetNamespace, name); +} + +ElementDescription::Hash XsdSchemaParserContext::setupElementDescriptions() +{ + enum + { + ReservedForElements = 60 + }; + + ElementDescription::Hash elementDescriptions; + elementDescriptions.reserve(ReservedForElements); + + { + ElementDescription &description = elementDescriptions[XsdTagScope::Schema]; + description.optionalAttributes.reserve(10); + //description.tagToken = XsdSchemaToken::Schema; + description.optionalAttributes.insert(XsdSchemaToken::AttributeFormDefault); + description.optionalAttributes.insert(XsdSchemaToken::BlockDefault); + description.optionalAttributes.insert(XsdSchemaToken::DefaultAttributes); + description.optionalAttributes.insert(XsdSchemaToken::XPathDefaultNamespace); + description.optionalAttributes.insert(XsdSchemaToken::ElementFormDefault); + description.optionalAttributes.insert(XsdSchemaToken::FinalDefault); + description.optionalAttributes.insert(XsdSchemaToken::Id); + description.optionalAttributes.insert(XsdSchemaToken::TargetNamespace); + description.optionalAttributes.insert(XsdSchemaToken::Version); + description.optionalAttributes.insert(XsdSchemaToken::XmlLanguage); + } + + { + ElementDescription &description = elementDescriptions[XsdTagScope::Include]; + //description.tagToken = XsdSchemaToken::Include; + description.requiredAttributes.insert(XsdSchemaToken::SchemaLocation); + description.optionalAttributes.insert(XsdSchemaToken::Id); + } + + { + ElementDescription &description = elementDescriptions[XsdTagScope::Import]; + //description.tagToken = XsdSchemaToken::Import; + description.optionalAttributes.insert(XsdSchemaToken::Id); + description.optionalAttributes.insert(XsdSchemaToken::Namespace); + description.optionalAttributes.insert(XsdSchemaToken::SchemaLocation); + } + + { + ElementDescription &description = elementDescriptions[XsdTagScope::Redefine]; + //description.tagToken = XsdSchemaToken::Redefine; + description.optionalAttributes.insert(XsdSchemaToken::Id); + description.requiredAttributes.insert(XsdSchemaToken::SchemaLocation); + } + + { + ElementDescription &description = elementDescriptions[XsdTagScope::Override]; + //description.tagToken = XsdSchemaToken::Override; + description.optionalAttributes.insert(XsdSchemaToken::Id); + description.requiredAttributes.insert(XsdSchemaToken::SchemaLocation); + } + + { + ElementDescription &description = elementDescriptions[XsdTagScope::Annotation]; + //description.tagToken = XsdSchemaToken::Annotation; + description.optionalAttributes.insert(XsdSchemaToken::Id); + } + + { + ElementDescription &description = elementDescriptions[XsdTagScope::AppInfo]; + //description.tagToken = XsdSchemaToken::Appinfo; + description.optionalAttributes.insert(XsdSchemaToken::Source); + } + + { + ElementDescription &description = elementDescriptions[XsdTagScope::Documentation]; + //description.tagToken = XsdSchemaToken::Documentation; + description.optionalAttributes.insert(XsdSchemaToken::Source); + } + + { + ElementDescription &description = elementDescriptions[XsdTagScope::GlobalSimpleType]; + //description.tagToken = XsdSchemaToken::SimpleType; + description.optionalAttributes.insert(XsdSchemaToken::Final); + description.optionalAttributes.insert(XsdSchemaToken::Id); + description.requiredAttributes.insert(XsdSchemaToken::Name); + } + + { + ElementDescription &description = elementDescriptions[XsdTagScope::LocalSimpleType]; + //description.tagToken = XsdSchemaToken::SimpleType; + description.optionalAttributes.insert(XsdSchemaToken::Id); + } + + { + ElementDescription &description = elementDescriptions[XsdTagScope::SimpleRestriction]; + //description.tagToken = XsdSchemaToken::Restriction; + description.optionalAttributes.insert(XsdSchemaToken::Base); + description.optionalAttributes.insert(XsdSchemaToken::Id); + } + + { + ElementDescription &description = elementDescriptions[XsdTagScope::List]; + //description.tagToken = XsdSchemaToken::List; + description.optionalAttributes.insert(XsdSchemaToken::Id); + description.optionalAttributes.insert(XsdSchemaToken::ItemType); + } + + { + ElementDescription &description = elementDescriptions[XsdTagScope::Union]; + //description.tagToken = XsdSchemaToken::Union; + description.optionalAttributes.insert(XsdSchemaToken::Id); + description.optionalAttributes.insert(XsdSchemaToken::MemberTypes); + } + + { + ElementDescription &description = elementDescriptions[XsdTagScope::MinExclusiveFacet]; + //description.tagToken = XsdSchemaToken::MinExclusive; + description.optionalAttributes.insert(XsdSchemaToken::Fixed); + description.optionalAttributes.insert(XsdSchemaToken::Id); + description.requiredAttributes.insert(XsdSchemaToken::Value); + } + + { + ElementDescription &description = elementDescriptions[XsdTagScope::MinInclusiveFacet]; + //description.tagToken = XsdSchemaToken::MinInclusive; + description.optionalAttributes.insert(XsdSchemaToken::Fixed); + description.optionalAttributes.insert(XsdSchemaToken::Id); + description.requiredAttributes.insert(XsdSchemaToken::Value); + } + + { + ElementDescription &description = elementDescriptions[XsdTagScope::MaxExclusiveFacet]; + //description.tagToken = XsdSchemaToken::MaxExclusive; + description.optionalAttributes.insert(XsdSchemaToken::Fixed); + description.optionalAttributes.insert(XsdSchemaToken::Id); + description.requiredAttributes.insert(XsdSchemaToken::Value); + } + + { + ElementDescription &description = elementDescriptions[XsdTagScope::MaxInclusiveFacet]; + //description.tagToken = XsdSchemaToken::MaxInclusive; + description.optionalAttributes.insert(XsdSchemaToken::Fixed); + description.optionalAttributes.insert(XsdSchemaToken::Id); + description.requiredAttributes.insert(XsdSchemaToken::Value); + } + + { + ElementDescription &description = elementDescriptions[XsdTagScope::TotalDigitsFacet]; + //description.tagToken = XsdSchemaToken::TotalDigits; + description.optionalAttributes.insert(XsdSchemaToken::Fixed); + description.optionalAttributes.insert(XsdSchemaToken::Id); + description.requiredAttributes.insert(XsdSchemaToken::Value); + } + + { + ElementDescription &description = elementDescriptions[XsdTagScope::FractionDigitsFacet]; + //description.tagToken = XsdSchemaToken::FractionDigits; + description.optionalAttributes.insert(XsdSchemaToken::Fixed); + description.optionalAttributes.insert(XsdSchemaToken::Id); + description.requiredAttributes.insert(XsdSchemaToken::Value); + } + + { + ElementDescription &description = elementDescriptions[XsdTagScope::LengthFacet]; + //description.tagToken = XsdSchemaToken::Length; + description.optionalAttributes.insert(XsdSchemaToken::Fixed); + description.optionalAttributes.insert(XsdSchemaToken::Id); + description.requiredAttributes.insert(XsdSchemaToken::Value); + } + + { + ElementDescription &description = elementDescriptions[XsdTagScope::MinLengthFacet]; + //description.tagToken = XsdSchemaToken::MinLength; + description.optionalAttributes.insert(XsdSchemaToken::Fixed); + description.optionalAttributes.insert(XsdSchemaToken::Id); + description.requiredAttributes.insert(XsdSchemaToken::Value); + } + + { + ElementDescription &description = elementDescriptions[XsdTagScope::MaxLengthFacet]; + //description.tagToken = XsdSchemaToken::MaxLength; + description.optionalAttributes.insert(XsdSchemaToken::Fixed); + description.optionalAttributes.insert(XsdSchemaToken::Id); + description.requiredAttributes.insert(XsdSchemaToken::Value); + } + + { + ElementDescription &description = elementDescriptions[XsdTagScope::EnumerationFacet]; + //description.tagToken = XsdSchemaToken::Enumeration; + description.optionalAttributes.insert(XsdSchemaToken::Id); + description.requiredAttributes.insert(XsdSchemaToken::Value); + } + + { + ElementDescription &description = elementDescriptions[XsdTagScope::WhiteSpaceFacet]; + //description.tagToken = XsdSchemaToken::WhiteSpace; + description.optionalAttributes.insert(XsdSchemaToken::Fixed); + description.optionalAttributes.insert(XsdSchemaToken::Id); + description.requiredAttributes.insert(XsdSchemaToken::Value); + } + + { + ElementDescription &description = elementDescriptions[XsdTagScope::PatternFacet]; + //description.tagToken = XsdSchemaToken::Pattern; + description.optionalAttributes.insert(XsdSchemaToken::Id); + description.requiredAttributes.insert(XsdSchemaToken::Value); + } + + { + ElementDescription &description = elementDescriptions[XsdTagScope::GlobalComplexType]; + description.optionalAttributes.reserve(7); + //description.tagToken = XsdSchemaToken::ComplexType; + description.optionalAttributes.insert(XsdSchemaToken::Abstract); + description.optionalAttributes.insert(XsdSchemaToken::Block); + description.optionalAttributes.insert(XsdSchemaToken::DefaultAttributesApply); + description.optionalAttributes.insert(XsdSchemaToken::Final); + description.optionalAttributes.insert(XsdSchemaToken::Id); + description.optionalAttributes.insert(XsdSchemaToken::Mixed); + description.requiredAttributes.insert(XsdSchemaToken::Name); + } + + { + ElementDescription &description = elementDescriptions[XsdTagScope::LocalComplexType]; + //description.tagToken = XsdSchemaToken::ComplexType; + description.optionalAttributes.insert(XsdSchemaToken::Id); + description.optionalAttributes.insert(XsdSchemaToken::Mixed); + } + + { + ElementDescription &description = elementDescriptions[XsdTagScope::SimpleContent]; + //description.tagToken = XsdSchemaToken::SimpleContent; + description.optionalAttributes.insert(XsdSchemaToken::Id); + } + + { + ElementDescription &description = elementDescriptions[XsdTagScope::SimpleContentRestriction]; + //description.tagToken = XsdSchemaToken::Restriction; + description.requiredAttributes.insert(XsdSchemaToken::Base); + description.optionalAttributes.insert(XsdSchemaToken::Id); + } + + { + ElementDescription &description = elementDescriptions[XsdTagScope::SimpleContentExtension]; + //description.tagToken = XsdSchemaToken::Extension; + description.requiredAttributes.insert(XsdSchemaToken::Base); + description.optionalAttributes.insert(XsdSchemaToken::Id); + } + + { + ElementDescription &description = elementDescriptions[XsdTagScope::ComplexContent]; + //description.tagToken = XsdSchemaToken::ComplexContent; + description.optionalAttributes.insert(XsdSchemaToken::Id); + description.optionalAttributes.insert(XsdSchemaToken::Mixed); + } + + { + ElementDescription &description = elementDescriptions[XsdTagScope::ComplexContentRestriction]; + //description.tagToken = XsdSchemaToken::Restriction; + description.requiredAttributes.insert(XsdSchemaToken::Base); + description.optionalAttributes.insert(XsdSchemaToken::Id); + } + + { + ElementDescription &description = elementDescriptions[XsdTagScope::ComplexContentExtension]; + //description.tagToken = XsdSchemaToken::Extension; + description.requiredAttributes.insert(XsdSchemaToken::Base); + description.optionalAttributes.insert(XsdSchemaToken::Id); + } + + { + ElementDescription &description = elementDescriptions[XsdTagScope::NamedGroup]; + //description.tagToken = XsdSchemaToken::Group; + description.optionalAttributes.insert(XsdSchemaToken::Id); + description.requiredAttributes.insert(XsdSchemaToken::Name); + } + + { + ElementDescription &description = elementDescriptions[XsdTagScope::ReferredGroup]; + description.optionalAttributes.reserve(4); + //description.tagToken = XsdSchemaToken::Group; + description.optionalAttributes.insert(XsdSchemaToken::Id); + description.optionalAttributes.insert(XsdSchemaToken::MaxOccurs); + description.optionalAttributes.insert(XsdSchemaToken::MinOccurs); + description.requiredAttributes.insert(XsdSchemaToken::Ref); + } + + { + ElementDescription &description = elementDescriptions[XsdTagScope::All]; + //description.tagToken = XsdSchemaToken::All; + description.optionalAttributes.insert(XsdSchemaToken::Id); + } + + { + ElementDescription &description = elementDescriptions[XsdTagScope::LocalAll]; + //description.tagToken = XsdSchemaToken::All; + description.optionalAttributes.insert(XsdSchemaToken::Id); + description.optionalAttributes.insert(XsdSchemaToken::MaxOccurs); + description.optionalAttributes.insert(XsdSchemaToken::MinOccurs); + } + + { + ElementDescription &description = elementDescriptions[XsdTagScope::Choice]; + //description.tagToken = XsdSchemaToken::Choice; + description.optionalAttributes.insert(XsdSchemaToken::Id); + } + + { + ElementDescription &description = elementDescriptions[XsdTagScope::LocalChoice]; + //description.tagToken = XsdSchemaToken::Choice; + description.optionalAttributes.insert(XsdSchemaToken::Id); + description.optionalAttributes.insert(XsdSchemaToken::MaxOccurs); + description.optionalAttributes.insert(XsdSchemaToken::MinOccurs); + } + + { + ElementDescription &description = elementDescriptions[XsdTagScope::Sequence]; + //description.tagToken = XsdSchemaToken::Sequence; + description.optionalAttributes.insert(XsdSchemaToken::Id); + } + + { + ElementDescription &description = elementDescriptions[XsdTagScope::LocalSequence]; + //description.tagToken = XsdSchemaToken::Sequence; + description.optionalAttributes.insert(XsdSchemaToken::Id); + description.optionalAttributes.insert(XsdSchemaToken::MaxOccurs); + description.optionalAttributes.insert(XsdSchemaToken::MinOccurs); + } + + { + ElementDescription &description = elementDescriptions[XsdTagScope::GlobalAttribute]; + description.optionalAttributes.reserve(5); + //description.tagToken = XsdSchemaToken::Attribute; + description.optionalAttributes.insert(XsdSchemaToken::Default); + description.optionalAttributes.insert(XsdSchemaToken::Fixed); + description.optionalAttributes.insert(XsdSchemaToken::Id); + description.requiredAttributes.insert(XsdSchemaToken::Name); + description.optionalAttributes.insert(XsdSchemaToken::Type); + } + + { + ElementDescription &description = elementDescriptions[XsdTagScope::LocalAttribute]; + description.optionalAttributes.reserve(8); + //description.tagToken = XsdSchemaToken::Attribute; + description.optionalAttributes.insert(XsdSchemaToken::Default); + description.optionalAttributes.insert(XsdSchemaToken::Fixed); + description.optionalAttributes.insert(XsdSchemaToken::Form); + description.optionalAttributes.insert(XsdSchemaToken::Id); + description.optionalAttributes.insert(XsdSchemaToken::Name); + description.optionalAttributes.insert(XsdSchemaToken::Ref); + description.optionalAttributes.insert(XsdSchemaToken::Type); + description.optionalAttributes.insert(XsdSchemaToken::Use); + } + + { + ElementDescription &description = elementDescriptions[XsdTagScope::NamedAttributeGroup]; + //description.tagToken = XsdSchemaToken::AttributeGroup; + description.optionalAttributes.insert(XsdSchemaToken::Id); + description.requiredAttributes.insert(XsdSchemaToken::Name); + } + + { + ElementDescription &description = elementDescriptions[XsdTagScope::ReferredAttributeGroup]; + //description.tagToken = XsdSchemaToken::AttributeGroup; + description.optionalAttributes.insert(XsdSchemaToken::Id); + description.requiredAttributes.insert(XsdSchemaToken::Ref); + } + + { + ElementDescription &description = elementDescriptions[XsdTagScope::LocalElement]; + description.optionalAttributes.reserve(11); + //description.tagToken = XsdSchemaToken::Element; + description.optionalAttributes.insert(XsdSchemaToken::Block); + description.optionalAttributes.insert(XsdSchemaToken::Default); + description.optionalAttributes.insert(XsdSchemaToken::Fixed); + description.optionalAttributes.insert(XsdSchemaToken::Form); + description.optionalAttributes.insert(XsdSchemaToken::Id); + description.optionalAttributes.insert(XsdSchemaToken::MinOccurs); + description.optionalAttributes.insert(XsdSchemaToken::MaxOccurs); + description.optionalAttributes.insert(XsdSchemaToken::Name); + description.optionalAttributes.insert(XsdSchemaToken::Nillable); + description.optionalAttributes.insert(XsdSchemaToken::Ref); + description.optionalAttributes.insert(XsdSchemaToken::Type); + } + + { + ElementDescription &description = elementDescriptions[XsdTagScope::GlobalElement]; + description.optionalAttributes.reserve(10); + //description.tagToken = XsdSchemaToken::Element; + description.optionalAttributes.insert(XsdSchemaToken::Abstract); + description.optionalAttributes.insert(XsdSchemaToken::Block); + description.optionalAttributes.insert(XsdSchemaToken::Default); + description.optionalAttributes.insert(XsdSchemaToken::Final); + description.optionalAttributes.insert(XsdSchemaToken::Fixed); + description.optionalAttributes.insert(XsdSchemaToken::Id); + description.requiredAttributes.insert(XsdSchemaToken::Name); + description.optionalAttributes.insert(XsdSchemaToken::Nillable); + description.optionalAttributes.insert(XsdSchemaToken::SubstitutionGroup); + description.optionalAttributes.insert(XsdSchemaToken::Type); + } + + { + ElementDescription &description = elementDescriptions[XsdTagScope::Unique]; + //description.tagToken = XsdSchemaToken::Unique; + description.optionalAttributes.insert(XsdSchemaToken::Id); + description.requiredAttributes.insert(XsdSchemaToken::Name); + } + + { + ElementDescription &description = elementDescriptions[XsdTagScope::Key]; + //description.tagToken = XsdSchemaToken::Key; + description.optionalAttributes.insert(XsdSchemaToken::Id); + description.requiredAttributes.insert(XsdSchemaToken::Name); + } + + { + ElementDescription &description = elementDescriptions[XsdTagScope::KeyRef]; + //description.tagToken = XsdSchemaToken::Keyref; + description.optionalAttributes.insert(XsdSchemaToken::Id); + description.requiredAttributes.insert(XsdSchemaToken::Name); + description.requiredAttributes.insert(XsdSchemaToken::Refer); + } + + { + ElementDescription &description = elementDescriptions[XsdTagScope::Selector]; + //description.tagToken = XsdSchemaToken::Selector; + description.optionalAttributes.insert(XsdSchemaToken::Id); + description.requiredAttributes.insert(XsdSchemaToken::Xpath); + description.optionalAttributes.insert(XsdSchemaToken::XPathDefaultNamespace); + } + + { + ElementDescription &description = elementDescriptions[XsdTagScope::Field]; + //description.tagToken = XsdSchemaToken::Field; + description.optionalAttributes.insert(XsdSchemaToken::Id); + description.requiredAttributes.insert(XsdSchemaToken::Xpath); + description.optionalAttributes.insert(XsdSchemaToken::XPathDefaultNamespace); + } + + { + ElementDescription &description = elementDescriptions[XsdTagScope::Notation]; + description.optionalAttributes.reserve(4); + //description.tagToken = XsdSchemaToken::Notation; + description.optionalAttributes.insert(XsdSchemaToken::Id); + description.requiredAttributes.insert(XsdSchemaToken::Name); + description.optionalAttributes.insert(XsdSchemaToken::Public); + description.optionalAttributes.insert(XsdSchemaToken::System); + } + + { + ElementDescription &description = elementDescriptions[XsdTagScope::Any]; + description.optionalAttributes.reserve(7); + //description.tagToken = XsdSchemaToken::Any; + description.optionalAttributes.insert(XsdSchemaToken::Id); + description.optionalAttributes.insert(XsdSchemaToken::MaxOccurs); + description.optionalAttributes.insert(XsdSchemaToken::MinOccurs); + description.optionalAttributes.insert(XsdSchemaToken::Namespace); + description.optionalAttributes.insert(XsdSchemaToken::NotNamespace); + description.optionalAttributes.insert(XsdSchemaToken::NotQName); + description.optionalAttributes.insert(XsdSchemaToken::ProcessContents); + } + + { + ElementDescription &description = elementDescriptions[XsdTagScope::AnyAttribute]; + description.optionalAttributes.reserve(5); + //description.tagToken = XsdSchemaToken::AnyAttribute; + description.optionalAttributes.insert(XsdSchemaToken::Id); + description.optionalAttributes.insert(XsdSchemaToken::Namespace); + description.optionalAttributes.insert(XsdSchemaToken::NotNamespace); + description.optionalAttributes.insert(XsdSchemaToken::NotQName); + description.optionalAttributes.insert(XsdSchemaToken::ProcessContents); + } + + { + ElementDescription &description = elementDescriptions[XsdTagScope::Alternative]; + //description.tagToken = XsdSchemaToken::Alternative; + description.optionalAttributes.insert(XsdSchemaToken::Id); + description.optionalAttributes.insert(XsdSchemaToken::Test); + description.optionalAttributes.insert(XsdSchemaToken::Type); + description.optionalAttributes.insert(XsdSchemaToken::XPathDefaultNamespace); + } + + { + ElementDescription &description = elementDescriptions[XsdTagScope::OpenContent]; + //description.tagToken = XsdSchemaToken::OpenContent; + description.optionalAttributes.insert(XsdSchemaToken::Id); + description.optionalAttributes.insert(XsdSchemaToken::Mode); + } + + { + ElementDescription &description = elementDescriptions[XsdTagScope::DefaultOpenContent]; + //description.tagToken = XsdSchemaToken::DefaultOpenContent; + description.optionalAttributes.insert(XsdSchemaToken::AppliesToEmpty); + description.optionalAttributes.insert(XsdSchemaToken::Id); + description.optionalAttributes.insert(XsdSchemaToken::Mode); + } + + { + ElementDescription &description = elementDescriptions[XsdTagScope::Assert]; + //description.tagToken = XsdSchemaToken::Assert; + description.optionalAttributes.insert(XsdSchemaToken::Id); + description.requiredAttributes.insert(XsdSchemaToken::Test); + description.optionalAttributes.insert(XsdSchemaToken::XPathDefaultNamespace); + } + + { + ElementDescription &description = elementDescriptions[XsdTagScope::Assertion]; + //description.tagToken = XsdSchemaToken::Assertion; + description.optionalAttributes.insert(XsdSchemaToken::Id); + description.requiredAttributes.insert(XsdSchemaToken::Test); + description.optionalAttributes.insert(XsdSchemaToken::XPathDefaultNamespace); + } + + Q_ASSERT_X(elementDescriptions.count() == ReservedForElements, Q_FUNC_INFO, + qPrintable(QString::fromLatin1("Expected is %1, actual is %2.").arg(ReservedForElements).arg(elementDescriptions.count()))); + + return elementDescriptions; +} + +QT_END_NAMESPACE diff --git a/src/xmlpatterns/schema/qxsdschemaparsercontext_p.h b/src/xmlpatterns/schema/qxsdschemaparsercontext_p.h new file mode 100644 index 0000000..616aff3 --- /dev/null +++ b/src/xmlpatterns/schema/qxsdschemaparsercontext_p.h @@ -0,0 +1,201 @@ +/**************************************************************************** +** +** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the $MODULE$ of the Qt Toolkit. +** +** $TROLLTECH_DUAL_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_XsdSchemaParserContext_H +#define Patternist_XsdSchemaParserContext_H + +#include "qmaintainingreader_p.h" // for definition of ElementDescription +#include "qxsdschematoken_p.h" +#include "qxsdschema_p.h" +#include "qxsdschemachecker_p.h" +#include "qxsdschemacontext_p.h" +#include "qxsdschemaresolver_p.h" + +#include + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +namespace QPatternist +{ + /** + * @short A namespace class that contains identifiers for the different + * scopes a tag from the xml schema spec can appear in. + */ + class XsdTagScope + { + public: + enum Type + { + Schema, + Include, + Import, + Redefine, + Annotation, + AppInfo, + Documentation, + GlobalSimpleType, + LocalSimpleType, + SimpleRestriction, + List, + Union, + MinExclusiveFacet, + MinInclusiveFacet, + MaxExclusiveFacet, + MaxInclusiveFacet, + TotalDigitsFacet, + FractionDigitsFacet, + LengthFacet, + MinLengthFacet, + MaxLengthFacet, + EnumerationFacet, + WhiteSpaceFacet, + PatternFacet, + GlobalComplexType, + LocalComplexType, + SimpleContent, + SimpleContentRestriction, + SimpleContentExtension, + ComplexContent, + ComplexContentRestriction, + ComplexContentExtension, + NamedGroup, + ReferredGroup, + All, + LocalAll, + Choice, + LocalChoice, + Sequence, + LocalSequence, + GlobalAttribute, + LocalAttribute, + NamedAttributeGroup, + ReferredAttributeGroup, + GlobalElement, + LocalElement, + Unique, + Key, + KeyRef, + Selector, + Field, + Notation, + Any, + AnyAttribute, + Alternative, + Assert, + Assertion, + OpenContent, + DefaultOpenContent, + Override + }; + }; + + /** + * A hash that keeps the mapping between the single components that can appear + * in a schema document (e.g. elements, attributes, type definitions) and their + * source locations inside the document. + */ + typedef QHash ComponentLocationHash; + + /** + * @short A context for schema parsing. + * + * This class provides a context for all components that are + * nedded for parsing and compiling the XML schema. + * + * @ingroup Patternist_schema + * @author Tobias Koenig + */ + class XsdSchemaParserContext : public QSharedData + { + public: + /** + * A smart pointer wrapping XsdSchemaParserContext instances. + */ + typedef QExplicitlySharedDataPointer Ptr; + + /** + * Creates a new schema parser context object. + * + * @param namePool The name pool where all names of the schema will be stored in. + * @param context The schema context to use for error reporting etc. + */ + XsdSchemaParserContext(const NamePool::Ptr &namePool, const XsdSchemaContext::Ptr &context); + + /** + * Returns the name pool of the schema parser context. + */ + NamePool::Ptr namePool() const; + + /** + * Returns the schema resolver of the schema context. + */ + XsdSchemaResolver::Ptr resolver() const; + + /** + * Returns the schema resolver of the schema context. + */ + XsdSchemaChecker::Ptr checker() const; + + /** + * Returns the schema object of the schema context. + */ + XsdSchema::Ptr schema() const; + + /** + * Returns the element descriptions for the schema parser. + * + * The element descriptions are a fast lookup table for + * verifying whether certain attributes are allowed for + * a given element type. + */ + ElementDescription::Hash elementDescriptions() const; + + /** + * Returns an unique name that is used by the schema parser + * for anonymous types. + * + * @param targetNamespace The namespace of the name. + */ + QXmlName createAnonymousName(const QString &targetNamespace) const; + + private: + /** + * Fills the element description hash with the required and prohibited + * attributes. + */ + static ElementDescription::Hash setupElementDescriptions(); + + NamePool::Ptr m_namePool; + XsdSchema::Ptr m_schema; + XsdSchemaChecker::Ptr m_checker; + XsdSchemaResolver::Ptr m_resolver; + const ElementDescription::Hash m_elementDescriptions; + mutable QAtomicInt m_anonymousNameCounter; + }; +} + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif diff --git a/src/xmlpatterns/schema/qxsdschemaresolver.cpp b/src/xmlpatterns/schema/qxsdschemaresolver.cpp new file mode 100644 index 0000000..4c6910f --- /dev/null +++ b/src/xmlpatterns/schema/qxsdschemaresolver.cpp @@ -0,0 +1,1706 @@ +/**************************************************************************** +** +** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the $MODULE$ of the Qt Toolkit. +** +** $TROLLTECH_DUAL_LICENSE$ +** +****************************************************************************/ + +#include "qxsdschemaresolver_p.h" + +#include "qderivedinteger_p.h" +#include "qderivedstring_p.h" +#include "qqnamevalue_p.h" +#include "qxsdattributereference_p.h" +#include "qxsdparticlechecker_p.h" +#include "qxsdreference_p.h" +#include "qxsdschemacontext_p.h" +#include "qxsdschemahelper_p.h" +#include "qxsdschemaparsercontext_p.h" +#include "qxsdschematypesfactory_p.h" + +QT_BEGIN_NAMESPACE + +using namespace QPatternist; + +XsdSchemaResolver::XsdSchemaResolver(const QExplicitlySharedDataPointer &context, const XsdSchemaParserContext *parserContext) + : m_context(context) + , m_checker(parserContext->checker()) + , m_namePool(parserContext->namePool()) + , m_schema(parserContext->schema()) +{ + m_keyReferences.reserve(20); + m_simpleRestrictionBases.reserve(20); + m_simpleListTypes.reserve(20); + m_simpleUnionTypes.reserve(20); + m_elementTypes.reserve(20); + m_complexBaseTypes.reserve(20); + m_attributeTypes.reserve(20); + m_alternativeTypes.reserve(20); + m_alternativeTypeElements.reserve(20); + m_substitutionGroupAffiliations.reserve(20); + + m_predefinedSchemaTypes = m_context->schemaTypeFactory()->types().values(); +} + +XsdSchemaResolver::~XsdSchemaResolver() +{ +} + +void XsdSchemaResolver::resolve() +{ + m_checker->addComponentLocationHash(m_componentLocationHash); + + // resolve the base types for all types + resolveSimpleRestrictionBaseTypes(); + resolveComplexBaseTypes(); + + // do the basic checks which depend on having a base type available + m_checker->basicCheck(); + + // resolve further types that only map a type name to a type object + resolveSimpleListType(); + resolveSimpleUnionTypes(); + resolveElementTypes(); + resolveAttributeTypes(); + resolveAlternativeTypes(); + + // resolve objects that do not need information about inheritance + resolveKeyReferences(); + resolveSubstitutionGroupAffiliations(); + + // resolve objects that do need information about inheritance + resolveSimpleRestrictions(); + resolveSimpleContentComplexTypes(); + + // resolve objects which replace place holders + resolveTermReferences(); + resolveAttributeTermReferences(); + + // resolve additional objects that do need information about inheritance + resolveAttributeInheritance(); + resolveComplexContentComplexTypes(); + resolveSubstitutionGroups(); + + resolveEnumerationFacetValues(); + + checkRedefinedGroups(); + checkRedefinedAttributeGroups(); + + // check the constraining facets before we resolve them + m_checker->checkConstrainingFacets(); + + // add it again, as we may have added new components in the meantime + m_checker->addComponentLocationHash(m_componentLocationHash); + + m_checker->check(); +} + +void XsdSchemaResolver::addKeyReference(const XsdElement::Ptr &element, const XsdIdentityConstraint::Ptr &keyRef, const QXmlName &reference, const QSourceLocation &location) +{ + KeyReference item; + item.element = element; + item.keyRef = keyRef; + item.reference = reference; + item.location = location; + + m_keyReferences.append(item); +} + +void XsdSchemaResolver::addSimpleRestrictionBase(const XsdSimpleType::Ptr &simpleType, const QXmlName &baseName, const QSourceLocation &location) +{ + SimpleRestrictionBase item; + item.simpleType = simpleType; + item.baseName = baseName; + item.location = location; + + m_simpleRestrictionBases.append(item); +} + +void XsdSchemaResolver::removeSimpleRestrictionBase(const XsdSimpleType::Ptr &type) +{ + for (int i = 0; i < m_simpleRestrictionBases.count(); ++i) { + if (m_simpleRestrictionBases.at(i).simpleType == type) { + m_simpleRestrictionBases.remove(i); + break; + } + } +} + +void XsdSchemaResolver::addSimpleListType(const XsdSimpleType::Ptr &simpleType, const QXmlName &typeName, const QSourceLocation &location) +{ + SimpleListType item; + item.simpleType = simpleType; + item.typeName = typeName; + item.location = location; + + m_simpleListTypes.append(item); +} + +void XsdSchemaResolver::addSimpleUnionTypes(const XsdSimpleType::Ptr &simpleType, const QList &typeNames, const QSourceLocation &location) +{ + SimpleUnionType item; + item.simpleType = simpleType; + item.typeNames = typeNames; + item.location = location; + + m_simpleUnionTypes.append(item); +} + +void XsdSchemaResolver::addElementType(const XsdElement::Ptr &element, const QXmlName &typeName, const QSourceLocation &location) +{ + ElementType item; + item.element = element; + item.typeName = typeName; + item.location = location; + + m_elementTypes.append(item); +} + +void XsdSchemaResolver::addComplexBaseType(const XsdComplexType::Ptr &complexType, const QXmlName &baseName, const QSourceLocation &location, const XsdFacet::Hash &facets) +{ + ComplexBaseType item; + item.complexType = complexType; + item.baseName = baseName; + item.location = location; + item.facets = facets; + + m_complexBaseTypes.append(item); +} + +void XsdSchemaResolver::removeComplexBaseType(const XsdComplexType::Ptr &type) +{ + for (int i = 0; i < m_complexBaseTypes.count(); ++i) { + if (m_complexBaseTypes.at(i).complexType == type) { + m_complexBaseTypes.remove(i); + break; + } + } +} + +void XsdSchemaResolver::addComplexContentType(const XsdComplexType::Ptr &complexType, const XsdParticle::Ptr &content, bool mixed) +{ + ComplexContentType item; + item.complexType = complexType; + item.explicitContent = content; + item.effectiveMixed = mixed; + m_complexContentTypes.append(item); +} + +void XsdSchemaResolver::addAttributeType(const XsdAttribute::Ptr &attribute, const QXmlName &typeName, const QSourceLocation &location) +{ + AttributeType item; + item.attribute = attribute; + item.typeName = typeName; + item.location = location; + + m_attributeTypes.append(item); +} + +void XsdSchemaResolver::addAlternativeType(const XsdAlternative::Ptr &alternative, const QXmlName &typeName, const QSourceLocation &location) +{ + AlternativeType item; + item.alternative = alternative; + item.typeName = typeName; + item.location = location; + + m_alternativeTypes.append(item); +} + +void XsdSchemaResolver::addAlternativeType(const XsdAlternative::Ptr &alternative, const XsdElement::Ptr &element) +{ + AlternativeTypeElement item; + item.alternative = alternative; + item.element = element; + + m_alternativeTypeElements.append(item); +} + +void XsdSchemaResolver::addSubstitutionGroupAffiliation(const XsdElement::Ptr &element, const QList &elementNames, const QSourceLocation &location) +{ + SubstitutionGroupAffiliation item; + item.element = element; + item.elementNames = elementNames; + item.location = location; + + m_substitutionGroupAffiliations.append(item); +} + +void XsdSchemaResolver::addSubstitutionGroupType(const XsdElement::Ptr &element) +{ + m_substitutionGroupTypes.append(element); +} + +void XsdSchemaResolver::addComponentLocationHash(const ComponentLocationHash &hash) +{ + m_componentLocationHash.unite(hash); +} + +void XsdSchemaResolver::addEnumerationFacetValue(const AtomicValue::Ptr &facetValue, const NamespaceSupport &namespaceSupport) +{ + m_enumerationFacetValues.insert(facetValue, namespaceSupport); +} + +void XsdSchemaResolver::addRedefinedGroups(const XsdModelGroup::Ptr &redefinedGroup, const XsdModelGroup::Ptr &group) +{ + RedefinedGroups item; + item.redefinedGroup = redefinedGroup; + item.group = group; + + m_redefinedGroups.append(item); +} + +void XsdSchemaResolver::addRedefinedAttributeGroups(const XsdAttributeGroup::Ptr &redefinedGroup, const XsdAttributeGroup::Ptr &group) +{ + RedefinedAttributeGroups item; + item.redefinedGroup = redefinedGroup; + item.group = group; + + m_redefinedAttributeGroups.append(item); +} + +void XsdSchemaResolver::addAllGroupCheck(const XsdReference::Ptr &reference) +{ + m_allGroups.insert(reference); +} + +void XsdSchemaResolver::copyDataTo(const XsdSchemaResolver::Ptr &other) const +{ + other->m_keyReferences << m_keyReferences; + other->m_simpleRestrictionBases << m_simpleRestrictionBases; + other->m_simpleListTypes << m_simpleListTypes; + other->m_simpleUnionTypes << m_simpleUnionTypes; + other->m_elementTypes << m_elementTypes; + other->m_complexBaseTypes << m_complexBaseTypes; + other->m_complexContentTypes << m_complexContentTypes; + other->m_attributeTypes << m_attributeTypes; + other->m_alternativeTypes << m_alternativeTypes; + other->m_alternativeTypeElements << m_alternativeTypeElements; + other->m_substitutionGroupAffiliations << m_substitutionGroupAffiliations; + other->m_substitutionGroupTypes << m_substitutionGroupTypes; +} + +QXmlName XsdSchemaResolver::baseTypeNameOfType(const SchemaType::Ptr &type) const +{ + for (int i = 0; i < m_simpleRestrictionBases.count(); ++i) { + if (m_simpleRestrictionBases.at(i).simpleType == type) + return m_simpleRestrictionBases.at(i).baseName; + } + + for (int i = 0; i < m_complexBaseTypes.count(); ++i) { + if (m_complexBaseTypes.at(i).complexType == type) + return m_complexBaseTypes.at(i).baseName; + } + + return QXmlName(); +} + +QXmlName XsdSchemaResolver::typeNameOfAttribute(const XsdAttribute::Ptr &attribute) const +{ + for (int i = 0; i < m_attributeTypes.count(); ++i) { + if (m_attributeTypes.at(i).attribute == attribute) + return m_attributeTypes.at(i).typeName; + } + + return QXmlName(); +} + +void XsdSchemaResolver::setDefaultOpenContent(const XsdComplexType::OpenContent::Ptr &openContent, bool appliesToEmpty) +{ + m_defaultOpenContent = openContent; + m_defaultOpenContentAppliesToEmpty = appliesToEmpty; +} + +void XsdSchemaResolver::resolveKeyReferences() +{ + for (int i = 0; i < m_keyReferences.count(); ++i) { + const KeyReference ref = m_keyReferences.at(i); + + const XsdIdentityConstraint::Ptr constraint = m_schema->identityConstraint(ref.reference); + if (!constraint) { + m_context->error(QtXmlPatterns::tr("%1 references unknown %2 or %3 element %4") + .arg(formatKeyword(ref.keyRef->displayName(m_namePool))) + .arg(formatElement("key")) + .arg(formatElement("unique")) + .arg(formatKeyword(m_namePool, ref.reference)), + XsdSchemaContext::XSDError, ref.location); + return; + } + + if (constraint->category() != XsdIdentityConstraint::Key && constraint->category() != XsdIdentityConstraint::Unique) { // only key and unique can be referenced + m_context->error(QtXmlPatterns::tr("%1 references identity constraint %2 that is no %3 or %4 element") + .arg(formatKeyword(ref.keyRef->displayName(m_namePool))) + .arg(formatKeyword(m_namePool, ref.reference)) + .arg(formatElement("key")) + .arg(formatElement("unique")), + XsdSchemaContext::XSDError, ref.location); + return; + } + + if (constraint->fields().count() != ref.keyRef->fields().count()) { + m_context->error(QtXmlPatterns::tr("%1 has a different number of fields from the identity constraint %2 that it references") + .arg(formatKeyword(ref.keyRef->displayName(m_namePool))) + .arg(formatKeyword(m_namePool, ref.reference)), + XsdSchemaContext::XSDError, ref.location); + return; + } + + ref.keyRef->setReferencedKey(constraint); + } +} + +void XsdSchemaResolver::resolveSimpleRestrictionBaseTypes() +{ + // iterate over all simple types that are derived by restriction + for (int i = 0; i < m_simpleRestrictionBases.count(); ++i) { + const SimpleRestrictionBase item = m_simpleRestrictionBases.at(i); + + // find the base type + SchemaType::Ptr type = m_schema->type(item.baseName); + if (!type) { + // maybe it's a basic type... + type = m_context->schemaTypeFactory()->createSchemaType(item.baseName); + if (!type) { + m_context->error(QtXmlPatterns::tr("base type %1 of %2 element cannot be resolved") + .arg(formatType(m_namePool, item.baseName)) + .arg(formatElement("restriction")), + XsdSchemaContext::XSDError, item.location); + return; + } + } + + item.simpleType->setWxsSuperType(type); + } +} + +void XsdSchemaResolver::resolveSimpleRestrictions() +{ + XsdSimpleType::List simpleTypes; + + // first collect the global simple types + const SchemaType::List types = m_schema->types(); + for (int i = 0; i < types.count(); ++i) { + if (types.at(i)->isSimpleType() && (types.at(i)->derivationMethod() == SchemaType::DerivationRestriction)) + simpleTypes.append(types.at(i)); + } + + // then collect all anonymous simple types + const SchemaType::List anonymousTypes = m_schema->anonymousTypes(); + for (int i = 0; i < anonymousTypes.count(); ++i) { + if (anonymousTypes.at(i)->isSimpleType() && (anonymousTypes.at(i)->derivationMethod() == SchemaType::DerivationRestriction)) + simpleTypes.append(anonymousTypes.at(i)); + } + + QSet visitedTypes; + for (int i = 0; i < simpleTypes.count(); ++i) { + resolveSimpleRestrictions(simpleTypes.at(i), visitedTypes); + } +} + +void XsdSchemaResolver::resolveSimpleRestrictions(const XsdSimpleType::Ptr &simpleType, QSet &visitedTypes) +{ + if (visitedTypes.contains(simpleType)) + return; + else + visitedTypes.insert(simpleType); + + if (simpleType->derivationMethod() != XsdSimpleType::DerivationRestriction) + return; + + // as xs:NMTOKENS, xs:ENTITIES and xs:IDREFS are provided by our XsdSchemaTypesFactory, they are + // setup correctly already and shouldn't be handled here + if (m_predefinedSchemaTypes.contains(simpleType)) + return; + + const SchemaType::Ptr baseType = simpleType->wxsSuperType(); + Q_ASSERT(baseType); + + if (baseType->isDefinedBySchema()) + resolveSimpleRestrictions(XsdSimpleType::Ptr(baseType), visitedTypes); + + simpleType->setCategory(baseType->category()); + + if (simpleType->category() == XsdSimpleType::SimpleTypeAtomic) { + QSet visitedPrimitiveTypes; + const AnySimpleType::Ptr primitiveType = findPrimitiveType(baseType, visitedPrimitiveTypes); + simpleType->setPrimitiveType(primitiveType); + } else if (simpleType->category() == XsdSimpleType::SimpleTypeList) { + const XsdSimpleType::Ptr simpleBaseType = baseType; + simpleType->setItemType(simpleBaseType->itemType()); + } else if (simpleType->category() == XsdSimpleType::SimpleTypeUnion) { + const XsdSimpleType::Ptr simpleBaseType = baseType; + simpleType->setMemberTypes(simpleBaseType->memberTypes()); + } +} + +void XsdSchemaResolver::resolveSimpleListType() +{ + // iterate over all simple types where the item type shall be resolved + for (int i = 0; i < m_simpleListTypes.count(); ++i) { + const SimpleListType item = m_simpleListTypes.at(i); + + // try to resolve the name + SchemaType::Ptr type = m_schema->type(item.typeName); + if (!type) { + // maybe it's a basic type... + type = m_context->schemaTypeFactory()->createSchemaType(item.typeName); + if (!type) { + m_context->error(QtXmlPatterns::tr("item type %1 of %2 element cannot be resolved") + .arg(formatType(m_namePool, item.typeName)) + .arg(formatElement("list")), + XsdSchemaContext::XSDError, item.location); + return; + } + } + + item.simpleType->setItemType(type); + } +} + +void XsdSchemaResolver::resolveSimpleUnionTypes() +{ + // iterate over all simple types where the union member types shall be resolved + for (int i = 0; i < m_simpleUnionTypes.count(); ++i) { + const SimpleUnionType item = m_simpleUnionTypes.at(i); + + AnySimpleType::List memberTypes; + + // iterate over all union member type names + const QList typeNames = item.typeNames; + for (int j = 0; j < typeNames.count(); ++j) { + const QXmlName typeName = typeNames.at(j); + + // try to resolve the name + SchemaType::Ptr type = m_schema->type(typeName); + if (!type) { + // maybe it's a basic type... + type = m_context->schemaTypeFactory()->createSchemaType(typeName); + if (!type) { + m_context->error(QtXmlPatterns::tr("member type %1 of %2 element cannot be resolved") + .arg(formatType(m_namePool, typeName)) + .arg(formatElement("union")), + XsdSchemaContext::XSDError, item.location); + return; + } + } + + memberTypes.append(type); + } + + // append the types that have been defined as children + memberTypes << item.simpleType->memberTypes(); + + item.simpleType->setMemberTypes(memberTypes); + } +} + +void XsdSchemaResolver::resolveElementTypes() +{ + for (int i = 0; i < m_elementTypes.count(); ++i) { + const ElementType item = m_elementTypes.at(i); + + SchemaType::Ptr type = m_schema->type(item.typeName); + if (!type) { + // maybe it's a basic type... + type = m_context->schemaTypeFactory()->createSchemaType(item.typeName); + if (!type) { + m_context->error(QtXmlPatterns::tr("type %1 of %2 element cannot be resolved") + .arg(formatType(m_namePool, item.typeName)) + .arg(formatElement("element")), + XsdSchemaContext::XSDError, item.location); + return; + } + } + + item.element->setType(type); + } +} + +void XsdSchemaResolver::resolveComplexBaseTypes() +{ + for (int i = 0; i < m_complexBaseTypes.count(); ++i) { + const ComplexBaseType item = m_complexBaseTypes.at(i); + + SchemaType::Ptr type = m_schema->type(item.baseName); + if (!type) { + // maybe it's a basic type... + type = m_context->schemaTypeFactory()->createSchemaType(item.baseName); + if (!type) { + m_context->error(QtXmlPatterns::tr("base type %1 of complex type cannot be resolved").arg(formatType(m_namePool, item.baseName)), XsdSchemaContext::XSDError, item.location); + return; + } + } + + if (item.complexType->contentType()->variety() == XsdComplexType::ContentType::Simple) { + if (type->isComplexType() && type->isDefinedBySchema()) { + const XsdComplexType::Ptr baseType = type; + if (baseType->contentType()->variety() != XsdComplexType::ContentType::Simple) { + m_context->error(QtXmlPatterns::tr("%1 cannot have complex base type that has a %2") + .arg(formatElement("simpleContent")) + .arg(formatElement("complexContent")), + XsdSchemaContext::XSDError, item.location); + return; + } + } + } + + item.complexType->setWxsSuperType(type); + } +} + +void XsdSchemaResolver::resolveSimpleContentComplexTypes() +{ + XsdComplexType::List complexTypes; + + // first collect the global complex types + const SchemaType::List types = m_schema->types(); + for (int i = 0; i < types.count(); ++i) { + if (types.at(i)->isComplexType() && types.at(i)->isDefinedBySchema()) + complexTypes.append(types.at(i)); + } + + // then collect all anonymous simple types + const SchemaType::List anonymousTypes = m_schema->anonymousTypes(); + for (int i = 0; i < anonymousTypes.count(); ++i) { + if (anonymousTypes.at(i)->isComplexType() && anonymousTypes.at(i)->isDefinedBySchema()) + complexTypes.append(anonymousTypes.at(i)); + } + + QSet visitedTypes; + for (int i = 0; i < complexTypes.count(); ++i) { + if (XsdComplexType::Ptr(complexTypes.at(i))->contentType()->variety() == XsdComplexType::ContentType::Simple) + resolveSimpleContentComplexTypes(complexTypes.at(i), visitedTypes); + } +} + +void XsdSchemaResolver::resolveSimpleContentComplexTypes(const XsdComplexType::Ptr &complexType, QSet &visitedTypes) +{ + if (visitedTypes.contains(complexType)) + return; + else + visitedTypes.insert(complexType); + + const SchemaType::Ptr baseType = complexType->wxsSuperType(); + + // at this point simple types have been resolved already, so we care about + // complex types here only + + // http://www.w3.org/TR/xmlschema11-1/#dcl.ctd.ctsc + // 1 + if (baseType->isComplexType() && baseType->isDefinedBySchema()) { + const XsdComplexType::Ptr complexBaseType = baseType; + + resolveSimpleContentComplexTypes(complexBaseType, visitedTypes); + + if (complexBaseType->contentType()->variety() == XsdComplexType::ContentType::Simple) { + if (complexType->derivationMethod() == XsdComplexType::DerivationRestriction) { + if (complexType->contentType()->simpleType()) { + // 1.1 contains the content of the already + } else { + // 1.2 + const XsdSimpleType::Ptr anonType(new XsdSimpleType()); + anonType->setCategory(complexBaseType->contentType()->simpleType()->category()); + anonType->setDerivationMethod(XsdSimpleType::DerivationRestriction); + anonType->setWxsSuperType(complexBaseType->contentType()->simpleType()); + anonType->setFacets(complexTypeFacets(complexType)); + + QSet visitedPrimitiveTypes; + const AnySimpleType::Ptr primitiveType = findPrimitiveType(anonType->wxsSuperType(), visitedPrimitiveTypes); + anonType->setPrimitiveType(primitiveType); + + complexType->contentType()->setSimpleType(anonType); + + m_schema->addAnonymousType(anonType); + m_componentLocationHash.insert(anonType, m_componentLocationHash.value(complexType)); + } + } else if (complexBaseType->derivationMethod() == XsdComplexType::DerivationExtension) { // 3 + complexType->contentType()->setSimpleType(complexBaseType->contentType()->simpleType()); + } + } else if (complexBaseType->contentType()->variety() == XsdComplexType::ContentType::Mixed && + complexType->derivationMethod() == XsdComplexType::DerivationRestriction && + XsdSchemaHelper::isParticleEmptiable(complexBaseType->contentType()->particle())) { // 2 + // simple type was already set in parser + + const XsdSimpleType::Ptr anonType(new XsdSimpleType()); + anonType->setCategory(complexType->contentType()->simpleType()->category()); + anonType->setDerivationMethod(XsdSimpleType::DerivationRestriction); + anonType->setWxsSuperType(complexType->contentType()->simpleType()); + anonType->setFacets(complexTypeFacets(complexType)); + + QSet visitedPrimitiveTypes; + const AnySimpleType::Ptr primitiveType = findPrimitiveType(anonType->wxsSuperType(), visitedPrimitiveTypes); + anonType->setPrimitiveType(primitiveType); + + complexType->contentType()->setSimpleType(anonType); + + m_schema->addAnonymousType(anonType); + m_componentLocationHash.insert(anonType, m_componentLocationHash.value(complexType)); + } else { + complexType->contentType()->setSimpleType(BuiltinTypes::xsAnySimpleType); + } + } else if (baseType->isSimpleType()) { // 4 + complexType->contentType()->setSimpleType(baseType); + } else { // 5 + complexType->contentType()->setSimpleType(BuiltinTypes::xsAnySimpleType); + } +} + +void XsdSchemaResolver::resolveComplexContentComplexTypes() +{ + XsdComplexType::List complexTypes; + + // first collect the global complex types + const SchemaType::List types = m_schema->types(); + for (int i = 0; i < types.count(); ++i) { + if (types.at(i)->isComplexType() && types.at(i)->isDefinedBySchema()) + complexTypes.append(types.at(i)); + } + + // then collect all anonymous simple types + const SchemaType::List anonymousTypes = m_schema->anonymousTypes(); + for (int i = 0; i < anonymousTypes.count(); ++i) { + if (anonymousTypes.at(i)->isComplexType() && anonymousTypes.at(i)->isDefinedBySchema()) + complexTypes.append(anonymousTypes.at(i)); + } + + QSet visitedTypes; + for (int i = 0; i < complexTypes.count(); ++i) { + if (XsdComplexType::Ptr(complexTypes.at(i))->contentType()->variety() != XsdComplexType::ContentType::Simple) + resolveComplexContentComplexTypes(complexTypes.at(i), visitedTypes); + } +} + +void XsdSchemaResolver::resolveComplexContentComplexTypes(const XsdComplexType::Ptr &complexType, QSet &visitedTypes) +{ + if (visitedTypes.contains(complexType)) + return; + else + visitedTypes.insert(complexType); + + ComplexContentType item; + bool foundCorrespondingItem = false; + for (int i = 0; i < m_complexContentTypes.count(); ++i) { + if (m_complexContentTypes.at(i).complexType == complexType) { + item = m_complexContentTypes.at(i); + foundCorrespondingItem = true; + break; + } + } + + if (!foundCorrespondingItem) + return; + + const SchemaType::Ptr baseType = complexType->wxsSuperType(); + + // at this point simple types have been resolved already, so we care about + // complex types here only + if (baseType->isComplexType() && baseType->isDefinedBySchema()) + resolveComplexContentComplexTypes(XsdComplexType::Ptr(baseType), visitedTypes); + + + // @see http://www.w3.org/TR/xmlschema11-1/#dcl.ctd.ctcc.common + + // 3 + XsdParticle::Ptr effectiveContent; + if (!item.explicitContent) { // 3.1 + if (item.effectiveMixed == true) { // 3.1.1 + const XsdParticle::Ptr particle(new XsdParticle()); + particle->setMinimumOccurs(1); + particle->setMaximumOccurs(1); + particle->setMaximumOccursUnbounded(false); + + const XsdModelGroup::Ptr sequence(new XsdModelGroup()); + sequence->setCompositor(XsdModelGroup::SequenceCompositor); + particle->setTerm(sequence); + + effectiveContent = particle; + } else { // 3.1.2 + effectiveContent = XsdParticle::Ptr(); + } + } else { // 3.2 + effectiveContent = item.explicitContent; + } + + // 4 + XsdComplexType::ContentType::Ptr explicitContentType(new XsdComplexType::ContentType()); + if (item.complexType->derivationMethod() == XsdComplexType::DerivationRestriction) { // 4.1 + if (!effectiveContent) { // 4.1.1 + explicitContentType->setVariety(XsdComplexType::ContentType::Empty); + } else { // 4.1.2 + if (item.effectiveMixed == true) + explicitContentType->setVariety(XsdComplexType::ContentType::Mixed); + else + explicitContentType->setVariety(XsdComplexType::ContentType::ElementOnly); + + explicitContentType->setParticle(effectiveContent); + } + } else if (item.complexType->derivationMethod() == XsdComplexType::DerivationExtension) { // 4.2 + const SchemaType::Ptr baseType = item.complexType->wxsSuperType(); + if (baseType->isSimpleType() || (baseType->isComplexType() && baseType->isDefinedBySchema() && (XsdComplexType::Ptr(baseType)->contentType()->variety() == XsdComplexType::ContentType::Empty || + XsdComplexType::Ptr(baseType)->contentType()->variety() == XsdComplexType::ContentType::Simple))) { // 4.2.1 + if (!effectiveContent) { + explicitContentType->setVariety(XsdComplexType::ContentType::Empty); + } else { + if (item.effectiveMixed == true) + explicitContentType->setVariety(XsdComplexType::ContentType::Mixed); + else + explicitContentType->setVariety(XsdComplexType::ContentType::ElementOnly); + + explicitContentType->setParticle(effectiveContent); + } + } else if (baseType->isComplexType() && baseType->isDefinedBySchema() && (XsdComplexType::Ptr(baseType)->contentType()->variety() == XsdComplexType::ContentType::ElementOnly || + XsdComplexType::Ptr(baseType)->contentType()->variety() == XsdComplexType::ContentType::Mixed) && !effectiveContent) { // 4.2.2 + const XsdComplexType::Ptr complexBaseType(baseType); + + explicitContentType = complexBaseType->contentType(); + } else { // 4.2.3 + explicitContentType->setVariety(item.effectiveMixed ? XsdComplexType::ContentType::Mixed : XsdComplexType::ContentType::ElementOnly); + + XsdParticle::Ptr baseParticle; + if (baseType == BuiltinTypes::xsAnyType) { + // we need a workaround here, since the xsAnyType is no real (aka XsdComplexType) complex type... + + baseParticle = XsdParticle::Ptr(new XsdParticle()); + baseParticle->setMinimumOccurs(1); + baseParticle->setMaximumOccurs(1); + baseParticle->setMaximumOccursUnbounded(false); + + const XsdModelGroup::Ptr group(new XsdModelGroup()); + group->setCompositor(XsdModelGroup::SequenceCompositor); + + const XsdParticle::Ptr particle(new XsdParticle()); + particle->setMinimumOccurs(0); + particle->setMaximumOccursUnbounded(true); + + const XsdWildcard::Ptr wildcard(new XsdWildcard()); + wildcard->namespaceConstraint()->setVariety(XsdWildcard::NamespaceConstraint::Any); + wildcard->setProcessContents(XsdWildcard::Lax); + + particle->setTerm(wildcard); + XsdParticle::List particles; + particles.append(particle); + group->setParticles(particles); + baseParticle->setTerm(group); + } else { + const XsdComplexType::Ptr complexBaseType(baseType); + baseParticle = complexBaseType->contentType()->particle(); + } + if (baseParticle && baseParticle->term()->isModelGroup() && (XsdModelGroup::Ptr(baseParticle->term())->compositor() == XsdModelGroup::AllCompositor) && + (!item.explicitContent)) { // 4.2.3.1 + + explicitContentType->setParticle(baseParticle); + } else if (baseParticle && baseParticle->term()->isModelGroup() && (XsdModelGroup::Ptr(baseParticle->term())->compositor() == XsdModelGroup::AllCompositor) && + (effectiveContent->term()->isModelGroup() && (XsdModelGroup::Ptr(effectiveContent->term())->compositor() == XsdModelGroup::AllCompositor))) { // 4.2.3.2 + const XsdParticle::Ptr particle(new XsdParticle()); + particle->setMinimumOccurs(effectiveContent->minimumOccurs()); + particle->setMaximumOccurs(1); + particle->setMaximumOccursUnbounded(false); + + const XsdModelGroup::Ptr group(new XsdModelGroup()); + group->setCompositor(XsdModelGroup::AllCompositor); + XsdParticle::List particles = XsdModelGroup::Ptr(baseParticle->term())->particles(); + particles << XsdModelGroup::Ptr(effectiveContent->term())->particles(); + group->setParticles(particles); + particle->setTerm(group); + + explicitContentType->setParticle(particle); + } else { // 4.2.3.3 + const XsdParticle::Ptr particle(new XsdParticle()); + particle->setMinimumOccurs(1); + particle->setMaximumOccurs(1); + particle->setMaximumOccursUnbounded(false); + + const XsdModelGroup::Ptr group(new XsdModelGroup()); + group->setCompositor(XsdModelGroup::SequenceCompositor); + + if (effectiveContent && effectiveContent->term()->isModelGroup() && XsdModelGroup::Ptr(effectiveContent->term())->compositor() == XsdModelGroup::AllCompositor) { + m_context->error(QtXmlPatterns::tr("content model of complex type %1 contains %2 element so it cannot be derived by extension from a non-empty type") + .arg(formatType(m_namePool, complexType)).arg(formatKeyword("all")), XsdSchemaContext::XSDError, sourceLocation(complexType)); + return; + } + + if (baseParticle && baseParticle->term()->isModelGroup() && XsdModelGroup::Ptr(baseParticle->term())->compositor() == XsdModelGroup::AllCompositor) { + m_context->error(QtXmlPatterns::tr("complex type %1 cannot be derived by extension from %2 as the latter contains %3 element in its content model") + .arg(formatType(m_namePool, complexType)) + .arg(formatType(m_namePool, baseType)) + .arg(formatKeyword("all")), XsdSchemaContext::XSDError, sourceLocation(complexType)); + return; + } + + XsdParticle::List particles; + if (baseParticle) + particles << baseParticle; + if (effectiveContent) + particles << effectiveContent; + group->setParticles(particles); + particle->setTerm(group); + + explicitContentType->setParticle(particle); + } + + if (baseType->isDefinedBySchema()) { // xs:anyType has no open content + const XsdComplexType::Ptr complexBaseType(baseType); + explicitContentType->setOpenContent(complexBaseType->contentType()->openContent()); + } + } + } + + // 5 + XsdComplexType::OpenContent::Ptr wildcardElement; + if (item.complexType->contentType()->openContent()) { // 5.1 + wildcardElement = item.complexType->contentType()->openContent(); + } else { + if (m_defaultOpenContent) { // 5.2 + if ((explicitContentType->variety() != XsdComplexType::ContentType::Empty) || // 5.2.1 + (explicitContentType->variety() == XsdComplexType::ContentType::Empty && m_defaultOpenContentAppliesToEmpty)) { // 5.2.2 + wildcardElement = m_defaultOpenContent; + } + } + } + + // 6 + if (!wildcardElement) { // 6.1 + item.complexType->setContentType(explicitContentType); + } else { + if (wildcardElement->mode() == XsdComplexType::OpenContent::None) { // 6.2 + const XsdComplexType::ContentType::Ptr contentType(new XsdComplexType::ContentType()); + contentType->setVariety(explicitContentType->variety()); + contentType->setParticle(explicitContentType->particle()); + + item.complexType->setContentType(contentType); + } else { // 6.3 + const XsdComplexType::ContentType::Ptr contentType(new XsdComplexType::ContentType()); + + if (explicitContentType->variety() == XsdComplexType::ContentType::Empty) + contentType->setVariety(XsdComplexType::ContentType::ElementOnly); + else + contentType->setVariety(explicitContentType->variety()); + + if (explicitContentType->variety() == XsdComplexType::ContentType::Empty) { + const XsdParticle::Ptr particle(new XsdParticle()); + particle->setMinimumOccurs(1); + particle->setMaximumOccurs(1); + const XsdModelGroup::Ptr sequence(new XsdModelGroup()); + sequence->setCompositor(XsdModelGroup::SequenceCompositor); + particle->setTerm(sequence); + contentType->setParticle(particle); + } else { + contentType->setParticle(explicitContentType->particle()); + } + + const XsdComplexType::OpenContent::Ptr openContent(new XsdComplexType::OpenContent()); + if (wildcardElement) + openContent->setMode(wildcardElement->mode()); + else + openContent->setMode(XsdComplexType::OpenContent::Interleave); + + if (wildcardElement) + openContent->setWildcard(wildcardElement->wildcard()); + + item.complexType->setContentType(contentType); + } + } +} + +void XsdSchemaResolver::resolveAttributeTypes() +{ + for (int i = 0; i < m_attributeTypes.count(); ++i) { + const AttributeType item = m_attributeTypes.at(i); + + SchemaType::Ptr type = m_schema->type(item.typeName); + if (!type) { + // maybe it's a basic type... + type = m_context->schemaTypeFactory()->createSchemaType(item.typeName); + if (!type) { + m_context->error(QtXmlPatterns::tr("type %1 of %2 element cannot be resolved") + .arg(formatType(m_namePool, item.typeName)) + .arg(formatElement("attribute")), + XsdSchemaContext::XSDError, item.location); + return; + } + } + + if (!type->isSimpleType() && type->category() != SchemaType::None) { + m_context->error(QtXmlPatterns::tr("type of %1 element must be a simple type, %2 is not") + .arg(formatElement("attribute")) + .arg(formatType(m_namePool, item.typeName)), + XsdSchemaContext::XSDError, item.location); + return; + } + + item.attribute->setType(type); + } +} + +void XsdSchemaResolver::resolveAlternativeTypes() +{ + for (int i = 0; i < m_alternativeTypes.count(); ++i) { + const AlternativeType item = m_alternativeTypes.at(i); + + SchemaType::Ptr type = m_schema->type(item.typeName); + if (!type) { + // maybe it's a basic type... + type = m_context->schemaTypeFactory()->createSchemaType(item.typeName); + if (!type) { + m_context->error(QtXmlPatterns::tr("type %1 of %2 element cannot be resolved") + .arg(formatType(m_namePool, item.typeName)) + .arg(formatElement("alternative")), + XsdSchemaContext::XSDError, item.location); + return; + } + } + + item.alternative->setType(type); + } + + for (int i = 0; i < m_alternativeTypeElements.count(); ++i) { + const AlternativeTypeElement item = m_alternativeTypeElements.at(i); + item.alternative->setType(item.element->type()); + } +} + +bool hasCircularSubstitutionGroup(const XsdElement::Ptr ¤t, const XsdElement::Ptr &head, const NamePool::Ptr &namePool) +{ + if (current == head) + return true; + else { + const XsdElement::List elements = current->substitutionGroupAffiliations(); + for (int i = 0; i < elements.count(); ++i) { + if (hasCircularSubstitutionGroup(elements.at(i), head, namePool)) + return true; + } + } + + return false; +} + +void XsdSchemaResolver::resolveSubstitutionGroupAffiliations() +{ + for (int i = 0; i < m_substitutionGroupAffiliations.count(); ++i) { + const SubstitutionGroupAffiliation item = m_substitutionGroupAffiliations.at(i); + + XsdElement::List affiliations; + for (int j = 0; j < item.elementNames.count(); ++j) { + const XsdElement::Ptr element = m_schema->element(item.elementNames.at(j)); + if (!element) { + m_context->error(QtXmlPatterns::tr("substitution group %1 of %2 element cannot be resolved") + .arg(formatKeyword(m_namePool, item.elementNames.at(j))) + .arg(formatElement("element")), + XsdSchemaContext::XSDError, item.location); + return; + } + + // @see http://www.w3.org/TR/xmlschema11-1/#e-props-correct 5) + if (hasCircularSubstitutionGroup(element, item.element, m_namePool)) { + m_context->error(QtXmlPatterns::tr("substitution group %1 has circular definition").arg(formatKeyword(m_namePool, item.elementNames.at(j))), XsdSchemaContext::XSDError, item.location); + return; + } + + affiliations.append(element); + } + + item.element->setSubstitutionGroupAffiliations(affiliations); + } + + for (int i = 0; i < m_substitutionGroupTypes.count(); ++i) { + const XsdElement::Ptr element = m_substitutionGroupTypes.at(i); + element->setType(element->substitutionGroupAffiliations().first()->type()); + } +} + +bool isSubstGroupHeadOf(const XsdElement::Ptr &head, const XsdElement::Ptr &element, const NamePool::Ptr &namePool) +{ + if (head->name(namePool) == element->name(namePool)) + return true; + + const XsdElement::List affiliations = element->substitutionGroupAffiliations(); + for (int i = 0; i < affiliations.count(); ++i) { + if (isSubstGroupHeadOf(head, affiliations.at(i), namePool)) + return true; + } + + return false; +} + +void XsdSchemaResolver::resolveSubstitutionGroups() +{ + const XsdElement::List elements = m_schema->elements(); + for (int i = 0; i < elements.count(); ++i) { + const XsdElement::Ptr element = elements.at(i); + + // the element is always itself in the substitution group + element->addSubstitutionGroup(element); + + for (int j = 0; j < elements.count(); ++j) { + if (i == j) + continue; + + if (isSubstGroupHeadOf(element, elements.at(j), m_namePool)) + element->addSubstitutionGroup(elements.at(j)); + } + } +} + +void XsdSchemaResolver::resolveTermReferences() +{ + // first the global complex types + const SchemaType::List types = m_schema->types(); + for (int i = 0; i < types.count(); ++i) { + if (!(types.at(i)->isComplexType()) || !types.at(i)->isDefinedBySchema()) + continue; + + const XsdComplexType::Ptr complexType = types.at(i); + if (complexType->contentType()->variety() != XsdComplexType::ContentType::ElementOnly && complexType->contentType()->variety() != XsdComplexType::ContentType::Mixed) + continue; + + resolveTermReference(complexType->contentType()->particle(), QSet()); + } + + // then all anonymous complex types + const SchemaType::List anonymousTypes = m_schema->anonymousTypes(); + for (int i = 0; i < anonymousTypes.count(); ++i) { + if (!(anonymousTypes.at(i)->isComplexType()) || !anonymousTypes.at(i)->isDefinedBySchema()) + continue; + + const XsdComplexType::Ptr complexType = anonymousTypes.at(i); + if (complexType->contentType()->variety() != XsdComplexType::ContentType::ElementOnly && complexType->contentType()->variety() != XsdComplexType::ContentType::Mixed) + continue; + + resolveTermReference(complexType->contentType()->particle(), QSet()); + } + + const XsdModelGroup::List groups = m_schema->elementGroups(); + for (int i = 0; i < groups.count(); ++i) { + const XsdParticle::Ptr particle(new XsdParticle()); + particle->setTerm(groups.at(i)); + resolveTermReference(particle, QSet()); + } +} + +void XsdSchemaResolver::resolveTermReference(const XsdParticle::Ptr &particle, QSet visitedGroups) +{ + if (!particle) + return; + + const XsdTerm::Ptr term = particle->term(); + + // if it is a model group, we iterate over it recursive... + if (term->isModelGroup()) { + const XsdModelGroup::Ptr modelGroup = term; + const XsdParticle::List particles = modelGroup->particles(); + + for (int i = 0; i < particles.count(); ++i) { + resolveTermReference(particles.at(i), visitedGroups); + } + + // check for unique names of elements inside all compositor + if (modelGroup->compositor() != XsdModelGroup::ChoiceCompositor) { + for (int i = 0; i < particles.count(); ++i) { + const XsdParticle::Ptr particle = particles.at(i); + const XsdTerm::Ptr term = particle->term(); + + if (!(term->isElement())) + continue; + + for (int j = 0; j < particles.count(); ++j) { + const XsdParticle::Ptr otherParticle = particles.at(j); + const XsdTerm::Ptr otherTerm = otherParticle->term(); + + if (otherTerm->isElement() && i != j) { + const XsdElement::Ptr element = term; + const XsdElement::Ptr otherElement = otherTerm; + + if (element->name(m_namePool) == otherElement->name(m_namePool)) { + if (modelGroup->compositor() == XsdModelGroup::AllCompositor) { + m_context->error(QtXmlPatterns::tr("duplicated element names %1 in %2 element") + .arg(formatKeyword(element->displayName(m_namePool))) + .arg(formatElement("all")), + XsdSchemaContext::XSDError, sourceLocation(modelGroup)); + return; + } else if (modelGroup->compositor() == XsdModelGroup::SequenceCompositor) { + if (element->type() != otherElement->type()) { // not same variety + m_context->error(QtXmlPatterns::tr("duplicated element names %1 in %2 element") + .arg(formatKeyword(element->displayName(m_namePool))) + .arg(formatElement("sequence")), + XsdSchemaContext::XSDError, sourceLocation(modelGroup)); + return; + } + } + } + } + } + } + } + + return; + } + + // ...otherwise we have reached the end of recursion... + if (!term->isReference()) + return; + + // ...or we have reached a reference term that must be resolved + const XsdReference::Ptr reference = term; + switch (reference->type()) { + case XsdReference::Element: + { + const XsdElement::Ptr element = m_schema->element(reference->referenceName()); + if (element) { + particle->setTerm(element); + } else { + m_context->error(QtXmlPatterns::tr("reference %1 of %2 element cannot be resolved") + .arg(formatKeyword(m_namePool, reference->referenceName())) + .arg(formatElement("element")), + XsdSchemaContext::XSDError, reference->sourceLocation()); + return; + } + } + break; + case XsdReference::ModelGroup: + { + const XsdModelGroup::Ptr modelGroup = m_schema->elementGroup(reference->referenceName()); + if (modelGroup) { + if (visitedGroups.contains(modelGroup->name(m_namePool))) { + m_context->error(QtXmlPatterns::tr("circular group reference for %1").arg(formatKeyword(modelGroup->displayName(m_namePool))), + XsdSchemaContext::XSDError, reference->sourceLocation()); + } else { + visitedGroups.insert(modelGroup->name(m_namePool)); + } + + particle->setTerm(modelGroup); + + // start recursive iteration here as well to get all references resolved + const XsdParticle::List particles = modelGroup->particles(); + for (int i = 0; i < particles.count(); ++i) { + resolveTermReference(particles.at(i), visitedGroups); + } + + if (modelGroup->compositor() == XsdModelGroup::AllCompositor) { + if (m_allGroups.contains(reference)) { + m_context->error(QtXmlPatterns::tr("%1 element is not allowed in this scope").arg(formatElement("all")), + XsdSchemaContext::XSDError, reference->sourceLocation()); + return; + } + if (particle->maximumOccursUnbounded() || particle->maximumOccurs() != 1) { + m_context->error(QtXmlPatterns::tr("%1 element cannot have %2 attribute with value other than %3") + .arg(formatElement("all")) + .arg(formatAttribute("maxOccurs")) + .arg(formatData("1")), + XsdSchemaContext::XSDError, reference->sourceLocation()); + return; + } + if (particle->minimumOccurs() != 0 && particle->minimumOccurs() != 1) { + m_context->error(QtXmlPatterns::tr("%1 element cannot have %2 attribute with value other than %3 or %4") + .arg(formatElement("all")) + .arg(formatAttribute("minOccurs")) + .arg(formatData("0")) + .arg(formatData("1")), + XsdSchemaContext::XSDError, reference->sourceLocation()); + return; + } + } + } else { + m_context->error(QtXmlPatterns::tr("reference %1 of %2 element cannot be resolved") + .arg(formatKeyword(m_namePool, reference->referenceName())) + .arg(formatElement("group")), + XsdSchemaContext::XSDError, reference->sourceLocation()); + return; + } + } + break; + } +} + +void XsdSchemaResolver::resolveAttributeTermReferences() +{ + // first all global attribute groups + const XsdAttributeGroup::List attributeGroups = m_schema->attributeGroups(); + for (int i = 0; i < attributeGroups.count(); ++i) { + XsdWildcard::Ptr wildcard = attributeGroups.at(i)->wildcard(); + const XsdAttributeUse::List uses = resolveAttributeTermReferences(attributeGroups.at(i)->attributeUses(), wildcard, QSet()); + attributeGroups.at(i)->setAttributeUses(uses); + attributeGroups.at(i)->setWildcard(wildcard); + } + + // then the global complex types + const SchemaType::List types = m_schema->types(); + for (int i = 0; i < types.count(); ++i) { + if (!(types.at(i)->isComplexType()) || !types.at(i)->isDefinedBySchema()) + continue; + + const XsdComplexType::Ptr complexType = types.at(i); + const XsdAttributeUse::List attributeUses = complexType->attributeUses(); + + XsdWildcard::Ptr wildcard = complexType->attributeWildcard(); + const XsdAttributeUse::List uses = resolveAttributeTermReferences(attributeUses, wildcard, QSet()); + complexType->setAttributeUses(uses); + complexType->setAttributeWildcard(wildcard); + } + + // and afterwards all anonymous complex types + const SchemaType::List anonymousTypes = m_schema->anonymousTypes(); + for (int i = 0; i < anonymousTypes.count(); ++i) { + if (!(anonymousTypes.at(i)->isComplexType()) || !anonymousTypes.at(i)->isDefinedBySchema()) + continue; + + const XsdComplexType::Ptr complexType = anonymousTypes.at(i); + const XsdAttributeUse::List attributeUses = complexType->attributeUses(); + + XsdWildcard::Ptr wildcard = complexType->attributeWildcard(); + const XsdAttributeUse::List uses = resolveAttributeTermReferences(attributeUses, wildcard, QSet()); + complexType->setAttributeUses(uses); + complexType->setAttributeWildcard(wildcard); + } +} + +XsdAttributeUse::List XsdSchemaResolver::resolveAttributeTermReferences(const XsdAttributeUse::List &attributeUses, XsdWildcard::Ptr &wildcard, QSet visitedAttributeGroups) +{ + XsdAttributeUse::List resolvedAttributeUses; + + for (int i = 0; i < attributeUses.count(); ++i) { + const XsdAttributeUse::Ptr attributeUse = attributeUses.at(i); + if (attributeUse->isAttributeUse()) { + // it is a real attribute use, so no need to resolve it + resolvedAttributeUses.append(attributeUse); + } else if (attributeUse->isReference()) { + // it is just a reference, so resolve it to the real attribute use + + const XsdAttributeReference::Ptr reference = attributeUse; + if (reference->type() == XsdAttributeReference::AttributeUse) { + + // lookup the real attribute + const XsdAttribute::Ptr attribute = m_schema->attribute(reference->referenceName()); + if (!attribute) { + m_context->error(QtXmlPatterns::tr("reference %1 of %2 element cannot be resolved") + .arg(formatKeyword(m_namePool, reference->referenceName())) + .arg(formatElement("attribute")), + XsdSchemaContext::XSDError, reference->sourceLocation()); + return XsdAttributeUse::List(); + } + + // if both, reference and definition have a fixed or default value set, then they must be equal + if (attribute->valueConstraint() && attributeUse->valueConstraint()) { + if (attribute->valueConstraint()->value() != attributeUse->valueConstraint()->value()) { + m_context->error(QtXmlPatterns::tr("%1 or %2 attribute of reference %3 does not match with the attribute declaration %4") + .arg(formatAttribute("fixed")) + .arg(formatAttribute("default")) + .arg(formatKeyword(m_namePool, reference->referenceName())) + .arg(formatKeyword(attribute->displayName(m_namePool))), + XsdSchemaContext::XSDError, reference->sourceLocation()); + return XsdAttributeUse::List(); + } + } + + attributeUse->setAttribute(attribute); + if (!attributeUse->valueConstraint() && attribute->valueConstraint()) + attributeUse->setValueConstraint(XsdAttributeUse::ValueConstraint::fromAttributeValueConstraint(attribute->valueConstraint())); + + resolvedAttributeUses.append(attributeUse); + } else if (reference->type() == XsdAttributeReference::AttributeGroup) { + const XsdAttributeGroup::Ptr attributeGroup = m_schema->attributeGroup(reference->referenceName()); + if (!attributeGroup) { + m_context->error(QtXmlPatterns::tr("reference %1 of %2 element cannot be resolved") + .arg(formatKeyword(m_namePool, reference->referenceName())) + .arg(formatElement("attributeGroup")), + XsdSchemaContext::XSDError, reference->sourceLocation()); + return XsdAttributeUse::List(); + } + if (visitedAttributeGroups.contains(attributeGroup->name(m_namePool))) { + m_context->error(QtXmlPatterns::tr("attribute group %1 has circular reference").arg(formatKeyword(m_namePool, reference->referenceName())), + XsdSchemaContext::XSDError, reference->sourceLocation()); + return XsdAttributeUse::List(); + } else { + visitedAttributeGroups.insert(attributeGroup->name(m_namePool)); + } + + // resolve attribute wildcards as defined in http://www.w3.org/TR/xmlschema11-1/#declare-attributeGroup-wildcard + XsdWildcard::Ptr childWildcard; + resolvedAttributeUses << resolveAttributeTermReferences(attributeGroup->attributeUses(), childWildcard, visitedAttributeGroups); + if (!childWildcard) { + if (attributeGroup->wildcard()) { + if (wildcard) { + const XsdWildcard::ProcessContents contents = wildcard->processContents(); + wildcard = XsdSchemaHelper::wildcardIntersection(wildcard, attributeGroup->wildcard()); + wildcard->setProcessContents(contents); + } else { + wildcard = attributeGroup->wildcard(); + } + } + } else { + XsdWildcard::Ptr newWildcard; + if (attributeGroup->wildcard()) { + const XsdWildcard::ProcessContents contents = attributeGroup->wildcard()->processContents(); + newWildcard = XsdSchemaHelper::wildcardIntersection(attributeGroup->wildcard(), childWildcard); + newWildcard->setProcessContents(contents); + } else { + newWildcard = childWildcard; + } + + if (wildcard) { + const XsdWildcard::ProcessContents contents = wildcard->processContents(); + wildcard = XsdSchemaHelper::wildcardIntersection(wildcard, newWildcard); + wildcard->setProcessContents(contents); + } else { + wildcard = newWildcard; + } + } + } + } + } + + return resolvedAttributeUses; +} + +void XsdSchemaResolver::resolveAttributeInheritance() +{ + // collect the global and anonymous complex types + SchemaType::List types = m_schema->types(); + types << m_schema->anonymousTypes(); + + QSet visitedTypes; + for (int i = 0; i < types.count(); ++i) { + if (!(types.at(i)->isComplexType()) || !types.at(i)->isDefinedBySchema()) + continue; + + const XsdComplexType::Ptr complexType = types.at(i); + + resolveAttributeInheritance(complexType, visitedTypes); + } +} + +bool isValidWildcardRestriction(const XsdWildcard::Ptr &wildcard, const XsdWildcard::Ptr &baseWildcard) +{ + if (wildcard->namespaceConstraint()->variety() == baseWildcard->namespaceConstraint()->variety()) { + if (!XsdSchemaHelper::checkWildcardProcessContents(baseWildcard, wildcard)) + return false; + } + + if (wildcard->namespaceConstraint()->variety() == XsdWildcard::NamespaceConstraint::Any && + baseWildcard->namespaceConstraint()->variety() != XsdWildcard::NamespaceConstraint::Any ) { + return false; + } + if (baseWildcard->namespaceConstraint()->variety() == XsdWildcard::NamespaceConstraint::Not && + wildcard->namespaceConstraint()->variety() == XsdWildcard::NamespaceConstraint::Enumeration) { + if (!baseWildcard->namespaceConstraint()->namespaces().intersect(wildcard->namespaceConstraint()->namespaces()).isEmpty()) + return false; + } + if (baseWildcard->namespaceConstraint()->variety() == XsdWildcard::NamespaceConstraint::Enumeration && + wildcard->namespaceConstraint()->variety() == XsdWildcard::NamespaceConstraint::Enumeration) { + if (!wildcard->namespaceConstraint()->namespaces().subtract(baseWildcard->namespaceConstraint()->namespaces()).isEmpty()) + return false; + } + + return true; +} + +/* + * Since we inherit the attributes from our base class we have to walk up in the + * inheritance hierarchy first and resolve the attribute inheritance top-down. + */ +void XsdSchemaResolver::resolveAttributeInheritance(const XsdComplexType::Ptr &complexType, QSet &visitedTypes) +{ + if (visitedTypes.contains(complexType)) + return; + else + visitedTypes.insert(complexType); + + const SchemaType::Ptr baseType = complexType->wxsSuperType(); + Q_ASSERT(baseType); + + if (!(baseType->isComplexType()) || !baseType->isDefinedBySchema()) + return; + + const XsdComplexType::Ptr complexBaseType = baseType; + + resolveAttributeInheritance(complexBaseType, visitedTypes); + + // @see http://www.w3.org/TR/xmlschema11-1/#dcl.ctd.attuses + + // 1 and 2 (the attribute groups have been resolved here already) + const XsdAttributeUse::List uses = complexBaseType->attributeUses(); + + if (complexType->derivationMethod() == XsdComplexType::DerivationRestriction) { // 3.2 + const XsdAttributeUse::List currentUses = complexType->attributeUses(); + + // 3.2.1 and 3.2.2 As we also keep the prohibited attributes as objects, the algorithm below + // handles both the same way + + // add only these attribute uses of the base type that match one of the following criteria: + // 1: there is no attribute use with the same name in type + // 2: there is no attribute with the same name marked as prohibited in type + for (int j = 0; j < uses.count(); ++j) { + const XsdAttributeUse::Ptr use = uses.at(j); + bool found = false; + for (int k = 0; k < currentUses.count(); ++k) { + if (use->attribute()->name(m_namePool) == currentUses.at(k)->attribute()->name(m_namePool)) { + found = true; + + // check if prohibited usage is violated + if ((use->useType() == XsdAttributeUse::ProhibitedUse) && (currentUses.at(k)->useType() != XsdAttributeUse::ProhibitedUse)) { + m_context->error(QtXmlPatterns::tr("%1 attribute in %2 must have %3 use like in base type %4") + .arg(formatAttribute(use->attribute()->displayName(m_namePool))) + .arg(formatType(m_namePool, complexType)) + .arg(formatData("prohibited")) + .arg(formatType(m_namePool, complexBaseType)), + XsdSchemaContext::XSDError, sourceLocation(complexType)); + return; + } + + break; + } + } + + if (!found && uses.at(j)->useType() != XsdAttributeUse::ProhibitedUse) { + complexType->addAttributeUse(uses.at(j)); + } + } + } else if (complexType->derivationMethod() == XsdComplexType::DerivationExtension) { // 3.1 + QHash availableUses; + + // fill hash with attribute uses of current type for faster lookup + { + const XsdAttributeUse::List attributeUses = complexType->attributeUses(); + + for (int i = 0; i < attributeUses.count(); ++i) { + availableUses.insert(attributeUses.at(i)->attribute()->name(m_namePool), attributeUses.at(i)); + } + } + + // just add the attribute uses of the base type + for (int i = 0; i < uses.count(); ++i) { + const XsdAttributeUse::Ptr currentAttributeUse = uses.at(i); + + // if the base type defines the attribute as prohibited but we override it in current type, then don't copy the prohibited attribute use + if ((currentAttributeUse->useType() == XsdAttributeUse::ProhibitedUse) && availableUses.contains(currentAttributeUse->attribute()->name(m_namePool))) + continue; + + complexType->addAttributeUse(uses.at(i)); + } + } + + // handle attribute wildcards: @see http://www.w3.org/TR/xmlschema11-1/#dcl.ctd.anyatt + + // 1 + const XsdWildcard::Ptr completeWildcard(complexType->attributeWildcard()); + + if (complexType->derivationMethod() == XsdComplexType::DerivationRestriction) { + if (complexType->wxsSuperType()->isComplexType() && complexType->wxsSuperType()->isDefinedBySchema()) { + const XsdComplexType::Ptr complexBaseType(complexType->wxsSuperType()); + if (complexType->attributeWildcard()) { + if (complexBaseType->attributeWildcard()) { + if (!isValidWildcardRestriction(complexType->attributeWildcard(), complexBaseType->attributeWildcard())) { + m_context->error(QtXmlPatterns::tr("attribute wildcard of %1 is not a valid restriction of attribute wildcard of base type %2") + .arg(formatType(m_namePool, complexType)) + .arg(formatType(m_namePool, complexBaseType)), + XsdSchemaContext::XSDError, sourceLocation(complexType)); + return; + } + } else { + m_context->error(QtXmlPatterns::tr("%1 has attribute wildcard but its base type %2 has not") + .arg(formatType(m_namePool, complexType)) + .arg(formatType(m_namePool, complexBaseType)), + XsdSchemaContext::XSDError, sourceLocation(complexType)); + return; + } + } + } + complexType->setAttributeWildcard(completeWildcard); // 2.1 + } else if (complexType->derivationMethod() == XsdComplexType::DerivationExtension) { + XsdWildcard::Ptr baseWildcard; // 2.2.1 + if (complexType->wxsSuperType()->isComplexType() && complexType->wxsSuperType()->isDefinedBySchema()) + baseWildcard = XsdComplexType::Ptr(complexType->wxsSuperType())->attributeWildcard(); // 2.2.1.1 + else + baseWildcard = XsdWildcard::Ptr(); // 2.2.1.2 + + if (!baseWildcard) { + complexType->setAttributeWildcard(completeWildcard); // 2.2.2.1 + } else if (!completeWildcard) { + complexType->setAttributeWildcard(baseWildcard); // 2.2.2.2 + } else { + XsdWildcard::Ptr unionWildcard = XsdSchemaHelper::wildcardUnion(completeWildcard, baseWildcard); + if (unionWildcard) { + unionWildcard->setProcessContents(completeWildcard->processContents()); + complexType->setAttributeWildcard(unionWildcard); // 2.2.2.3 + } else { + m_context->error(QtXmlPatterns::tr("union of attribute wildcard of type %1 and attribute wildcard of its base type %2 is not expressible") + .arg(formatType(m_namePool, complexType)) + .arg(formatType(m_namePool, complexBaseType)), + XsdSchemaContext::XSDError, sourceLocation(complexType)); + return; + } + } + } +} + +void XsdSchemaResolver::resolveEnumerationFacetValues() +{ + XsdSimpleType::List simpleTypes; + + // first collect the global simple types + const SchemaType::List types = m_schema->types(); + for (int i = 0; i < types.count(); ++i) { + if (types.at(i)->isSimpleType()) + simpleTypes.append(types.at(i)); + } + + // then collect all anonymous simple types + const SchemaType::List anonymousTypes = m_schema->anonymousTypes(); + for (int i = 0; i < anonymousTypes.count(); ++i) { + if (anonymousTypes.at(i)->isSimpleType()) + simpleTypes.append(anonymousTypes.at(i)); + } + // process all simple types + for (int i = 0; i < simpleTypes.count(); ++i) { + const XsdSimpleType::Ptr simpleType = simpleTypes.at(i); + + // we resolve the enumeration values only for xs:QName and xs:NOTATION based types + if (BuiltinTypes::xsQName->wxsTypeMatches(simpleType) || + BuiltinTypes::xsNOTATION->wxsTypeMatches(simpleType)) { + const XsdFacet::Hash facets = simpleType->facets(); + if (facets.contains(XsdFacet::Enumeration)) { + AtomicValue::List newValues; + + const XsdFacet::Ptr facet = facets.value(XsdFacet::Enumeration); + const AtomicValue::List values = facet->multiValue(); + for (int j = 0; j < values.count(); ++j) { + const AtomicValue::Ptr value = values.at(j); + + Q_ASSERT(m_enumerationFacetValues.contains(value)); + const NamespaceSupport support( m_enumerationFacetValues.value(value) ); + + const QString qualifiedName = value->as >()->stringValue(); + if (!XPathHelper::isQName(qualifiedName)) { + m_context->error(QtXmlPatterns::tr("enumeration facet contains invalid content: {%1} is not a value of type %2") + .arg(formatData(qualifiedName)) + .arg(formatType(m_namePool, BuiltinTypes::xsQName)), + XsdSchemaContext::XSDError, sourceLocation(simpleType)); + return; + } + + QXmlName qNameValue; + bool result = support.processName(qualifiedName, NamespaceSupport::ElementName, qNameValue); + if (!result) { + m_context->error(QtXmlPatterns::tr("namespace prefix of qualified name %1 is not defined").arg(formatData(qualifiedName)), + XsdSchemaContext::XSDError, sourceLocation(simpleType)); + return; + } + + newValues.append(QNameValue::fromValue(m_namePool, qNameValue)); + } + facet->setMultiValue(newValues); + } + } + } +} + +QSourceLocation XsdSchemaResolver::sourceLocation(const NamedSchemaComponent::Ptr component) const +{ + if (m_componentLocationHash.contains(component)) { + return m_componentLocationHash.value(component); + } else { + QSourceLocation location; + location.setLine(1); + location.setColumn(1); + location.setUri(QString::fromLatin1("dummyUri")); + + return location; + } +} + +XsdFacet::Hash XsdSchemaResolver::complexTypeFacets(const XsdComplexType::Ptr &complexType) const +{ + for (int i = 0; i < m_complexBaseTypes.count(); ++i) { + if (m_complexBaseTypes.at(i).complexType == complexType) + return m_complexBaseTypes.at(i).facets; + } + + return XsdFacet::Hash(); +} + +void XsdSchemaResolver::checkRedefinedGroups() +{ + for (int i = 0; i < m_redefinedGroups.count(); ++i) { + const RedefinedGroups item = m_redefinedGroups.at(i); + + // create dummy particles... + const XsdParticle::Ptr redefinedParticle(new XsdParticle()); + redefinedParticle->setTerm(item.redefinedGroup); + const XsdParticle::Ptr particle(new XsdParticle()); + particle->setTerm(item.group); + + // so that we can pass them to XsdParticleChecker::subsumes() + QString errorMsg; + if (!XsdParticleChecker::subsumes(particle, redefinedParticle, m_context, errorMsg)) { + m_context->error(QtXmlPatterns::tr("%1 element %2 is not a valid restriction of the %3 element it redefines: %4") + .arg(formatElement("group")) + .arg(formatData(item.redefinedGroup->displayName(m_namePool))) + .arg(formatElement("group")) + .arg(errorMsg), + XsdSchemaContext::XSDError, sourceLocation(item.redefinedGroup)); + return; + } + } +} + +void XsdSchemaResolver::checkRedefinedAttributeGroups() +{ + for (int i = 0; i < m_redefinedAttributeGroups.count(); ++i) { + const RedefinedAttributeGroups item = m_redefinedAttributeGroups.at(i); + + QString errorMsg; + if (!XsdSchemaHelper::isValidAttributeGroupRestriction(item.redefinedGroup, item.group, m_context, errorMsg)) { + m_context->error(QtXmlPatterns::tr("%1 element %2 is not a valid restriction of the %3 element it redefines: %4") + .arg(formatElement("attributeGroup")) + .arg(formatData(item.redefinedGroup->displayName(m_namePool))) + .arg(formatElement("attributeGroup")) + .arg(errorMsg), + XsdSchemaContext::XSDError, sourceLocation(item.redefinedGroup)); + return; + } + } +} + +AnySimpleType::Ptr XsdSchemaResolver::findPrimitiveType(const AnySimpleType::Ptr &type, QSet &visitedTypes) +{ + if (visitedTypes.contains(type)) { + // found invalid circular reference... + return AnySimpleType::Ptr(); + } else { + visitedTypes.insert(type); + } + + const QXmlName typeName = type->name(m_namePool); + if (typeName == BuiltinTypes::xsString->name(m_namePool) || + typeName == BuiltinTypes::xsBoolean->name(m_namePool) || + typeName == BuiltinTypes::xsFloat->name(m_namePool) || + typeName == BuiltinTypes::xsDouble->name(m_namePool) || + typeName == BuiltinTypes::xsDecimal->name(m_namePool) || + typeName == BuiltinTypes::xsDuration->name(m_namePool) || + typeName == BuiltinTypes::xsDateTime->name(m_namePool) || + typeName == BuiltinTypes::xsTime->name(m_namePool) || + typeName == BuiltinTypes::xsDate->name(m_namePool) || + typeName == BuiltinTypes::xsGYearMonth->name(m_namePool) || + typeName == BuiltinTypes::xsGYear->name(m_namePool) || + typeName == BuiltinTypes::xsGMonthDay->name(m_namePool) || + typeName == BuiltinTypes::xsGDay->name(m_namePool) || + typeName == BuiltinTypes::xsGMonth->name(m_namePool) || + typeName == BuiltinTypes::xsHexBinary->name(m_namePool) || + typeName == BuiltinTypes::xsBase64Binary->name(m_namePool) || + typeName == BuiltinTypes::xsAnyURI->name(m_namePool) || + typeName == BuiltinTypes::xsQName->name(m_namePool) || + typeName == BuiltinTypes::xsNOTATION->name(m_namePool) || + typeName == BuiltinTypes::xsAnySimpleType->name(m_namePool)) + return type; + else { + if (type->wxsSuperType()) + return findPrimitiveType(type->wxsSuperType(), visitedTypes); + else { + return AnySimpleType::Ptr(); + } + } +} + +QT_END_NAMESPACE diff --git a/src/xmlpatterns/schema/qxsdschemaresolver_p.h b/src/xmlpatterns/schema/qxsdschemaresolver_p.h new file mode 100644 index 0000000..1222619 --- /dev/null +++ b/src/xmlpatterns/schema/qxsdschemaresolver_p.h @@ -0,0 +1,548 @@ +/**************************************************************************** +** +** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the $MODULE$ of the Qt Toolkit. +** +** $TROLLTECH_DUAL_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_XsdSchemaResolver_H +#define Patternist_XsdSchemaResolver_H + +#include "qnamespacesupport_p.h" +#include "qschematype_p.h" +#include "qschematypefactory_p.h" +#include "qxsdalternative_p.h" +#include "qxsdattribute_p.h" +#include "qxsdattributegroup_p.h" +#include "qxsdelement_p.h" +#include "qxsdmodelgroup_p.h" +#include "qxsdnotation_p.h" +#include "qxsdreference_p.h" +#include "qxsdschema_p.h" +#include "qxsdschemachecker_p.h" +#include "qxsdsimpletype_p.h" + +#include + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +namespace QPatternist +{ + class XsdSchemaContext; + class XsdSchemaParserContext; + + /** + * @short Encapsulates the resolving of type/element references in a schema after parsing has finished. + * + * This class collects task for resolving types or element references. After the parsing has finished, + * one can start the resolve process by calling resolve(). + * + * @ingroup Patternist_schema + * @author Tobias Koenig + */ + class XsdSchemaResolver : public QSharedData + { + public: + typedef QExplicitlySharedDataPointer Ptr; + + /** + * Creates a new schema resolver. + * + * @param context The schema context used for error reporting etc.. + * @param parserContext The schema parser context where all objects to resolve belong to. + */ + XsdSchemaResolver(const QExplicitlySharedDataPointer &context, const XsdSchemaParserContext *parserContext); + + /** + * Destroys the schema resolver. + */ + ~XsdSchemaResolver(); + + /** + * Starts the resolve process. + */ + void resolve(); + + /** + * Adds a resolve task for key references. + * + * The resolver will try to set the referencedKey property of @p keyRef to the key or unique object + * of @p element that has the given @p name. + */ + void addKeyReference(const XsdElement::Ptr &element, const XsdIdentityConstraint::Ptr &keyRef, const QXmlName &name, const QSourceLocation &location); + + /** + * Adds a resolve task for the base type of restriction of a simple type. + * + * The resolver will set the base type of @p simpleType to the type named by @p baseName. + */ + void addSimpleRestrictionBase(const XsdSimpleType::Ptr &simpleType, const QXmlName &baseName, const QSourceLocation &location); + + /** + * Removes the resolve task for the base type of restriction of the simple @p type. + */ + void removeSimpleRestrictionBase(const XsdSimpleType::Ptr &type); + + /** + * Adds a resolve task for the list type of a simple type. + * + * The resolver will set the itemType property of @p simpleType to the type named by @p typeName. + */ + void addSimpleListType(const XsdSimpleType::Ptr &simpleType, const QXmlName &typeName, const QSourceLocation &location); + + /** + * Adds a resolve task for the member types of a simple type. + * + * The resolver will set the memberTypes property of @p simpleType to the types named by @p typeNames. + */ + void addSimpleUnionTypes(const XsdSimpleType::Ptr &simpleType, const QList &typeNames, const QSourceLocation &location); + + /** + * Adds a resolve task for the type of an element. + * + * The resolver will set the type of the @p element to the type named by @p typeName. + */ + void addElementType(const XsdElement::Ptr &element, const QXmlName &typeName, const QSourceLocation &location); + + /** + * Adds a resolve task for the base type of a complex type. + * + * The resolver will set the base type of @p complexType to the type named by @p baseName. + */ + void addComplexBaseType(const XsdComplexType::Ptr &complexType, const QXmlName &baseName, const QSourceLocation &location, const XsdFacet::Hash &facets = XsdFacet::Hash()); + + /** + * Removes the resolve task for the base type of the complex @p type. + */ + void removeComplexBaseType(const XsdComplexType::Ptr &type); + + /** + * Adds a resolve task for the content type of a complex type. + * + * The resolver will set the content type properties for @p complexType based on the + * given explicit @p content and effective @p mixed value. + */ + void addComplexContentType(const XsdComplexType::Ptr &complexType, const XsdParticle::Ptr &content, bool mixed); + + /** + * Adds a resolve task for the type of an attribute. + * + * The resolver will set the type of the @p attribute to the type named by @p typeName. + */ + void addAttributeType(const XsdAttribute::Ptr &attribute, const QXmlName &typeName, const QSourceLocation &location); + + /** + * Adds a resolve task for the type of an alternative. + * + * The resolver will set the type of the @p alternative to the type named by @p typeName. + */ + void addAlternativeType(const XsdAlternative::Ptr &alternative, const QXmlName &typeName, const QSourceLocation &location); + + /** + * Adds a resolve task for the type of an alternative. + * + * The resolver will set the type of the @p alternative to the type of the @p element after + * the type of the @p element has been resolved. + */ + void addAlternativeType(const XsdAlternative::Ptr &alternative, const XsdElement::Ptr &element); + + /** + * Adds a resolve task for the substituion group affiliations of an element. + * + * The resolver will set the substitution group affiliations of the @p element to the + * top-level element named by @p elementNames. + */ + void addSubstitutionGroupAffiliation(const XsdElement::Ptr &element, const QList &elementName, const QSourceLocation &location); + + /** + * Adds a resolve task for an element that has no type specified, only a substitution group + * affiliation. + * + * The resolver will set the type of the substitution group affiliation as type for the element. + */ + void addSubstitutionGroupType(const XsdElement::Ptr &element); + + /** + * Adds the component location hash, so the resolver is able to report meaning full + * error messages. + */ + void addComponentLocationHash(const QHash &hash); + + /** + * Add a resolve task for enumeration facet values. + * + * In case the enumeration is of type QName or NOTATION, we have to resolve the QName later, + * so we store the namespace bindings together with the facet value here and resolve it as soon as + * we have all type information available. + */ + void addEnumerationFacetValue(const AtomicValue::Ptr &facetValue, const NamespaceSupport &namespaceSupport); + + /** + * Add a check job for redefined groups. + * + * When an element group is redefined, we have to check whether the redefined group is a valid + * restriction of the group it redefines. As we need all type information for that, we keep them + * here for later checking. + */ + void addRedefinedGroups(const XsdModelGroup::Ptr &redefinedGroup, const XsdModelGroup::Ptr &group); + + /** + * Add a check job for redefined attribute groups. + * + * When an attribute group is redefined, we have to check whether the redefined group is a valid + * restriction of the group it redefines. As we need all type information for that, we keep them + * here for later checking. + */ + void addRedefinedAttributeGroups(const XsdAttributeGroup::Ptr &redefinedGroup, const XsdAttributeGroup::Ptr &group); + + /** + * Adds a check for nested all groups. + */ + void addAllGroupCheck(const XsdReference::Ptr &reference); + + /** + * Copies the data to resolve to an @p other resolver. + * + * @note That functionality is only used by the redefine algorithm in the XsdSchemaParser. + */ + void copyDataTo(const XsdSchemaResolver::Ptr &other) const; + + /** + * Returns the to resolve base type name for the given @p type. + * + * @note That functionality is only used by the redefine algorithm in the XsdSchemaParser. + */ + QXmlName baseTypeNameOfType(const SchemaType::Ptr &type) const; + + /** + * Returns the to resolve type name for the given @p attribute. + * + * @note That functionality is only used by the redefine algorithm in the XsdSchemaParser. + */ + QXmlName typeNameOfAttribute(const XsdAttribute::Ptr &attribute) const; + + /** + * Sets the defaultOpenContent object from the schema parser. + */ + void setDefaultOpenContent(const XsdComplexType::OpenContent::Ptr &openContent, bool appliesToEmpty); + + private: + /** + * Resolves key references. + */ + void resolveKeyReferences(); + + /** + * Resolves the base types of simple types derived by restriction. + */ + void resolveSimpleRestrictionBaseTypes(); + + /** + * Resolves the other properties except the base type + * of all simple restrictions. + */ + void resolveSimpleRestrictions(); + + /** + * Resolves the other properties except the base type + * of the given simple restriction. + * + * @param simpleType The restricted type to resolve. + * @param visitedTypes A set of already resolved types, used for termination of recursion. + */ + void resolveSimpleRestrictions(const XsdSimpleType::Ptr &simpleType, QSet &visitedTypes); + + /** + * Resolves the item type property of simple types derived by list. + */ + void resolveSimpleListType(); + + /** + * Resolves the member types property of simple types derived by union. + */ + void resolveSimpleUnionTypes(); + + /** + * Resolves element types. + */ + void resolveElementTypes(); + + /** + * Resolves base type of complex types. + */ + void resolveComplexBaseTypes(); + + /** + * Resolves the simple content model of a complex type + * depending on its base type. + */ + void resolveSimpleContentComplexTypes(); + + /** + * Resolves the complex content model of a complex type + * depending on its base type. + */ + void resolveComplexContentComplexTypes(); + + /** + * Resolves the simple content model of a complex type + * depending on its base type. + * + * @param complexType The complex type to resolve. + * @param visitedTypes A set of already resolved types, used for termination of recursion. + */ + void resolveSimpleContentComplexTypes(const XsdComplexType::Ptr &complexType, QSet &visitedTypes); + + /** + * Resolves the complex content model of a complex type + * depending on its base type. + * + * @param complexType The complex type to resolve. + * @param visitedTypes A set of already resolved types, used for termination of recursion. + */ + void resolveComplexContentComplexTypes(const XsdComplexType::Ptr &complexType, QSet &visitedTypes); + + /** + * Resolves attribute types. + */ + void resolveAttributeTypes(); + + /** + * Resolves alternative types. + */ + void resolveAlternativeTypes(); + + /** + * Resolves substitution group affiliations. + */ + void resolveSubstitutionGroupAffiliations(); + + /** + * Resolves substitution groups. + */ + void resolveSubstitutionGroups(); + + /** + * Resolves all XsdReferences in the schema by their corresponding XsdElement or XsdModelGroup terms. + */ + void resolveTermReferences(); + + /** + * Resolves all XsdReferences in the @p particle recursive by their corresponding XsdElement or XsdModelGroup terms. + */ + void resolveTermReference(const XsdParticle::Ptr &particle, QSet visitedGroups); + + /** + * Resolves all XsdAttributeReferences in the schema by their corresponding XsdAttributeUse objects. + */ + void resolveAttributeTermReferences(); + + /** + * Resolves all XsdAttributeReferences in the list of @p attributeUses by their corresponding XsdAttributeUse objects. + */ + XsdAttributeUse::List resolveAttributeTermReferences(const XsdAttributeUse::List &attributeUses, XsdWildcard::Ptr &wildcard, QSet visitedAttributeGroups); + + /** + * Resolves the attribute inheritance of complex types. + * + * @note This method must be called after all base types have been resolved. + */ + void resolveAttributeInheritance(); + + /** + * Resolves the attribute inheritance of the given complex types. + * + * @param complexType The complex type to resolve. + * @param visitedTypes A set of already resolved types, used for termination of recursion. + * + * @note This method must be called after all base types have been resolved. + */ + void resolveAttributeInheritance(const XsdComplexType::Ptr &complexType, QSet &visitedTypes); + + /** + * Resolves the enumeration facet values for QName and NOTATION based facets. + */ + void resolveEnumerationFacetValues(); + + /** + * Returns the source location of the given schema @p component or a dummy + * source location if the component is not found in the component location hash. + */ + QSourceLocation sourceLocation(const NamedSchemaComponent::Ptr component) const; + + /** + * Returns the facets that are marked for the given complex @p type with a simple + * type restriction. + */ + XsdFacet::Hash complexTypeFacets(const XsdComplexType::Ptr &complexType) const; + + /** + * Finds the primitive type for the given simple @p type. + * + * The type is found by walking up the inheritance tree, until one of the builtin + * primitive type definitions is reached. + */ + AnySimpleType::Ptr findPrimitiveType(const AnySimpleType::Ptr &type, QSet &visitedTypes); + + /** + * Checks the redefined groups. + */ + void checkRedefinedGroups(); + + /** + * Checks the redefined attribute groups. + */ + void checkRedefinedAttributeGroups(); + + class KeyReference + { + public: + XsdElement::Ptr element; + XsdIdentityConstraint::Ptr keyRef; + QXmlName reference; + QSourceLocation location; + }; + + class SimpleRestrictionBase + { + public: + XsdSimpleType::Ptr simpleType; + QXmlName baseName; + QSourceLocation location; + }; + + class SimpleListType + { + public: + XsdSimpleType::Ptr simpleType; + QXmlName typeName; + QSourceLocation location; + }; + + class SimpleUnionType + { + public: + XsdSimpleType::Ptr simpleType; + QList typeNames; + QSourceLocation location; + }; + + class ElementType + { + public: + XsdElement::Ptr element; + QXmlName typeName; + QSourceLocation location; + }; + + class ComplexBaseType + { + public: + XsdComplexType::Ptr complexType; + QXmlName baseName; + QSourceLocation location; + XsdFacet::Hash facets; + }; + + class ComplexContentType + { + public: + XsdComplexType::Ptr complexType; + XsdParticle::Ptr explicitContent; + bool effectiveMixed; + }; + + class AttributeType + { + public: + XsdAttribute::Ptr attribute; + QXmlName typeName; + QSourceLocation location; + }; + + class AlternativeType + { + public: + XsdAlternative::Ptr alternative; + QXmlName typeName; + QSourceLocation location; + }; + + class AlternativeTypeElement + { + public: + XsdAlternative::Ptr alternative; + XsdElement::Ptr element; + }; + + class SubstitutionGroupAffiliation + { + public: + XsdElement::Ptr element; + QList elementNames; + QSourceLocation location; + }; + + class RedefinedGroups + { + public: + XsdModelGroup::Ptr redefinedGroup; + XsdModelGroup::Ptr group; + }; + + class RedefinedAttributeGroups + { + public: + XsdAttributeGroup::Ptr redefinedGroup; + XsdAttributeGroup::Ptr group; + }; + + QVector m_keyReferences; + QVector m_simpleRestrictionBases; + QVector m_simpleListTypes; + QVector m_simpleUnionTypes; + QVector m_elementTypes; + QVector m_complexBaseTypes; + QVector m_complexContentTypes; + QVector m_attributeTypes; + QVector m_alternativeTypes; + QVector m_alternativeTypeElements; + QVector m_substitutionGroupAffiliations; + QVector m_substitutionGroupTypes; + QVector m_redefinedGroups; + QVector m_redefinedAttributeGroups; + QHash m_enumerationFacetValues; + QSet m_allGroups; + + QExplicitlySharedDataPointer m_context; + QExplicitlySharedDataPointer m_checker; + NamePool::Ptr m_namePool; + XsdSchema::Ptr m_schema; + QHash m_componentLocationHash; + XsdComplexType::OpenContent::Ptr m_defaultOpenContent; + bool m_defaultOpenContentAppliesToEmpty; + SchemaType::List m_predefinedSchemaTypes; + }; +} + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif diff --git a/src/xmlpatterns/schema/qxsdschematoken.cpp b/src/xmlpatterns/schema/qxsdschematoken.cpp new file mode 100644 index 0000000..b527de6 --- /dev/null +++ b/src/xmlpatterns/schema/qxsdschematoken.cpp @@ -0,0 +1,2951 @@ +/**************************************************************************** +** +** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the $MODULE$ of the Qt Toolkit. +** +** $TROLLTECH_DUAL_LICENSE$ +** +****************************************************************************/ + +/* NOTE: This file is AUTO GENERATED by qautomaton2cpp.xsl. */ + +#include "qxsdschematoken_p.h" + +QT_BEGIN_NAMESPACE + +XsdSchemaToken::NodeName XsdSchemaToken::classifier2(const QChar *data) + + { + + static const unsigned short string[] = + { + 105, 100 + }; + if(memcmp(&data[0], &string, sizeof(QChar) * 2) == 0) + + + return Id; + + + return NoKeyword; + } + XsdSchemaToken::NodeName XsdSchemaToken::classifier3(const QChar *data) + + { + if (data[0] == 97) + + + { + if (data[1] == 108) + + + { + + if(data[2] == 108) + + + return All; + + } + + else if (data[1] == 110) + + + { + + if(data[2] == 121) + + + return Any; + + } + + + } + + else if (data[0] == 107) + + + { + + static const unsigned short string[] = + { + 101, 121 + }; + if(memcmp(&data[1], &string, sizeof(QChar) * 2) == 0) + + + return Key; + + } + + else if (data[0] == 114) + + + { + + static const unsigned short string[] = + { + 101, 102 + }; + if(memcmp(&data[1], &string, sizeof(QChar) * 2) == 0) + + + return Ref; + + } + + else if (data[0] == 117) + + + { + + static const unsigned short string[] = + { + 115, 101 + }; + if(memcmp(&data[1], &string, sizeof(QChar) * 2) == 0) + + + return Use; + + } + + + + return NoKeyword; + } + XsdSchemaToken::NodeName XsdSchemaToken::classifier4(const QChar *data) + + { + if (data[0] == 98) + + + { + + static const unsigned short string[] = + { + 97, 115, 101 + }; + if(memcmp(&data[1], &string, sizeof(QChar) * 3) == 0) + + + return Base; + + } + + else if (data[0] == 102) + + + { + + static const unsigned short string[] = + { + 111, 114, 109 + }; + if(memcmp(&data[1], &string, sizeof(QChar) * 3) == 0) + + + return Form; + + } + + else if (data[0] == 108) + + + { + + static const unsigned short string[] = + { + 105, 115, 116 + }; + if(memcmp(&data[1], &string, sizeof(QChar) * 3) == 0) + + + return List; + + } + + else if (data[0] == 109) + + + { + + static const unsigned short string[] = + { + 111, 100, 101 + }; + if(memcmp(&data[1], &string, sizeof(QChar) * 3) == 0) + + + return Mode; + + } + + else if (data[0] == 110) + + + { + + static const unsigned short string[] = + { + 97, 109, 101 + }; + if(memcmp(&data[1], &string, sizeof(QChar) * 3) == 0) + + + return Name; + + } + + else if (data[0] == 116) + + + { + if (data[1] == 101) + + + { + + static const unsigned short string[] = + { + 115, 116 + }; + if(memcmp(&data[2], &string, sizeof(QChar) * 2) == 0) + + + return Test; + + } + + else if (data[1] == 121) + + + { + + static const unsigned short string[] = + { + 112, 101 + }; + if(memcmp(&data[2], &string, sizeof(QChar) * 2) == 0) + + + return Type; + + } + + + } + + + + return NoKeyword; + } + XsdSchemaToken::NodeName XsdSchemaToken::classifier5(const QChar *data) + + { + if (data[0] == 98) + + + { + + static const unsigned short string[] = + { + 108, 111, 99, 107 + }; + if(memcmp(&data[1], &string, sizeof(QChar) * 4) == 0) + + + return Block; + + } + + else if (data[0] == 102) + + + { + if (data[1] == 105) + + + { + if (data[2] == 101) + + + { + + static const unsigned short string[] = + { + 108, 100 + }; + if(memcmp(&data[3], &string, sizeof(QChar) * 2) == 0) + + + return Field; + + } + + else if (data[2] == 110) + + + { + + static const unsigned short string[] = + { + 97, 108 + }; + if(memcmp(&data[3], &string, sizeof(QChar) * 2) == 0) + + + return Final; + + } + + else if (data[2] == 120) + + + { + + static const unsigned short string[] = + { + 101, 100 + }; + if(memcmp(&data[3], &string, sizeof(QChar) * 2) == 0) + + + return Fixed; + + } + + + } + + + } + + else if (data[0] == 103) + + + { + + static const unsigned short string[] = + { + 114, 111, 117, 112 + }; + if(memcmp(&data[1], &string, sizeof(QChar) * 4) == 0) + + + return Group; + + } + + else if (data[0] == 109) + + + { + + static const unsigned short string[] = + { + 105, 120, 101, 100 + }; + if(memcmp(&data[1], &string, sizeof(QChar) * 4) == 0) + + + return Mixed; + + } + + else if (data[0] == 114) + + + { + + static const unsigned short string[] = + { + 101, 102, 101, 114 + }; + if(memcmp(&data[1], &string, sizeof(QChar) * 4) == 0) + + + return Refer; + + } + + else if (data[0] == 117) + + + { + + static const unsigned short string[] = + { + 110, 105, 111, 110 + }; + if(memcmp(&data[1], &string, sizeof(QChar) * 4) == 0) + + + return Union; + + } + + else if (data[0] == 118) + + + { + + static const unsigned short string[] = + { + 97, 108, 117, 101 + }; + if(memcmp(&data[1], &string, sizeof(QChar) * 4) == 0) + + + return Value; + + } + + else if (data[0] == 120) + + + { + + static const unsigned short string[] = + { + 112, 97, 116, 104 + }; + if(memcmp(&data[1], &string, sizeof(QChar) * 4) == 0) + + + return Xpath; + + } + + + + return NoKeyword; + } + XsdSchemaToken::NodeName XsdSchemaToken::classifier6(const QChar *data) + + { + if (data[0] == 97) + + + { + + static const unsigned short string[] = + { + 115, 115, 101, 114, 116 + }; + if(memcmp(&data[1], &string, sizeof(QChar) * 5) == 0) + + + return Assert; + + } + + else if (data[0] == 99) + + + { + + static const unsigned short string[] = + { + 104, 111, 105, 99, 101 + }; + if(memcmp(&data[1], &string, sizeof(QChar) * 5) == 0) + + + return Choice; + + } + + else if (data[0] == 105) + + + { + + static const unsigned short string[] = + { + 109, 112, 111, 114, 116 + }; + if(memcmp(&data[1], &string, sizeof(QChar) * 5) == 0) + + + return Import; + + } + + else if (data[0] == 107) + + + { + + static const unsigned short string[] = + { + 101, 121, 114, 101, 102 + }; + if(memcmp(&data[1], &string, sizeof(QChar) * 5) == 0) + + + return Keyref; + + } + + else if (data[0] == 108) + + + { + + static const unsigned short string[] = + { + 101, 110, 103, 116, 104 + }; + if(memcmp(&data[1], &string, sizeof(QChar) * 5) == 0) + + + return Length; + + } + + else if (data[0] == 112) + + + { + + static const unsigned short string[] = + { + 117, 98, 108, 105, 99 + }; + if(memcmp(&data[1], &string, sizeof(QChar) * 5) == 0) + + + return Public; + + } + + else if (data[0] == 115) + + + { + if (data[1] == 99) + + + { + + static const unsigned short string[] = + { + 104, 101, 109, 97 + }; + if(memcmp(&data[2], &string, sizeof(QChar) * 4) == 0) + + + return Schema; + + } + + else if (data[1] == 111) + + + { + + static const unsigned short string[] = + { + 117, 114, 99, 101 + }; + if(memcmp(&data[2], &string, sizeof(QChar) * 4) == 0) + + + return Source; + + } + + else if (data[1] == 121) + + + { + + static const unsigned short string[] = + { + 115, 116, 101, 109 + }; + if(memcmp(&data[2], &string, sizeof(QChar) * 4) == 0) + + + return System; + + } + + + } + + else if (data[0] == 117) + + + { + + static const unsigned short string[] = + { + 110, 105, 113, 117, 101 + }; + if(memcmp(&data[1], &string, sizeof(QChar) * 5) == 0) + + + return Unique; + + } + + + + return NoKeyword; + } + XsdSchemaToken::NodeName XsdSchemaToken::classifier7(const QChar *data) + + { + if (data[0] == 97) + + + { + + static const unsigned short string[] = + { + 112, 112, 105, 110, 102, 111 + }; + if(memcmp(&data[1], &string, sizeof(QChar) * 6) == 0) + + + return Appinfo; + + } + + else if (data[0] == 100) + + + { + + static const unsigned short string[] = + { + 101, 102, 97, 117, 108, 116 + }; + if(memcmp(&data[1], &string, sizeof(QChar) * 6) == 0) + + + return Default; + + } + + else if (data[0] == 101) + + + { + + static const unsigned short string[] = + { + 108, 101, 109, 101, 110, 116 + }; + if(memcmp(&data[1], &string, sizeof(QChar) * 6) == 0) + + + return Element; + + } + + else if (data[0] == 105) + + + { + + static const unsigned short string[] = + { + 110, 99, 108, 117, 100, 101 + }; + if(memcmp(&data[1], &string, sizeof(QChar) * 6) == 0) + + + return Include; + + } + + else if (data[0] == 112) + + + { + + static const unsigned short string[] = + { + 97, 116, 116, 101, 114, 110 + }; + if(memcmp(&data[1], &string, sizeof(QChar) * 6) == 0) + + + return Pattern; + + } + + else if (data[0] == 114) + + + { + + static const unsigned short string[] = + { + 101, 112, 108, 97, 99, 101 + }; + if(memcmp(&data[1], &string, sizeof(QChar) * 6) == 0) + + + return Replace; + + } + + else if (data[0] == 118) + + + { + + static const unsigned short string[] = + { + 101, 114, 115, 105, 111, 110 + }; + if(memcmp(&data[1], &string, sizeof(QChar) * 6) == 0) + + + return Version; + + } + + + + return NoKeyword; + } + XsdSchemaToken::NodeName XsdSchemaToken::classifier8(const QChar *data) + + { + if (data[0] == 97) + + + { + + static const unsigned short string[] = + { + 98, 115, 116, 114, 97, 99, 116 + }; + if(memcmp(&data[1], &string, sizeof(QChar) * 7) == 0) + + + return Abstract; + + } + + else if (data[0] == 99) + + + { + + static const unsigned short string[] = + { + 111, 108, 108, 97, 112, 115, 101 + }; + if(memcmp(&data[1], &string, sizeof(QChar) * 7) == 0) + + + return Collapse; + + } + + else if (data[0] == 105) + + + { + + static const unsigned short string[] = + { + 116, 101, 109, 84, 121, 112, 101 + }; + if(memcmp(&data[1], &string, sizeof(QChar) * 7) == 0) + + + return ItemType; + + } + + else if (data[0] == 110) + + + { + if (data[1] == 105) + + + { + + static const unsigned short string[] = + { + 108, 108, 97, 98, 108, 101 + }; + if(memcmp(&data[2], &string, sizeof(QChar) * 6) == 0) + + + return Nillable; + + } + + else if (data[1] == 111) + + + { + if (data[2] == 116) + + + { + if (data[3] == 97) + + + { + + static const unsigned short string[] = + { + 116, 105, 111, 110 + }; + if(memcmp(&data[4], &string, sizeof(QChar) * 4) == 0) + + + return Notation; + + } + + else if (data[3] == 81) + + + { + + static const unsigned short string[] = + { + 78, 97, 109, 101 + }; + if(memcmp(&data[4], &string, sizeof(QChar) * 4) == 0) + + + return NotQName; + + } + + + } + + + } + + + } + + else if (data[0] == 111) + + + { + + static const unsigned short string[] = + { + 118, 101, 114, 114, 105, 100, 101 + }; + if(memcmp(&data[1], &string, sizeof(QChar) * 7) == 0) + + + return Override; + + } + + else if (data[0] == 112) + + + { + + static const unsigned short string[] = + { + 114, 101, 115, 101, 114, 118, 101 + }; + if(memcmp(&data[1], &string, sizeof(QChar) * 7) == 0) + + + return Preserve; + + } + + else if (data[0] == 114) + + + { + + static const unsigned short string[] = + { + 101, 100, 101, 102, 105, 110, 101 + }; + if(memcmp(&data[1], &string, sizeof(QChar) * 7) == 0) + + + return Redefine; + + } + + else if (data[0] == 115) + + + { + if (data[1] == 101) + + + { + if (data[2] == 108) + + + { + + static const unsigned short string[] = + { + 101, 99, 116, 111, 114 + }; + if(memcmp(&data[3], &string, sizeof(QChar) * 5) == 0) + + + return Selector; + + } + + else if (data[2] == 113) + + + { + + static const unsigned short string[] = + { + 117, 101, 110, 99, 101 + }; + if(memcmp(&data[3], &string, sizeof(QChar) * 5) == 0) + + + return Sequence; + + } + + + } + + + } + + else if (data[0] == 120) + + + { + + static const unsigned short string[] = + { + 109, 108, 58, 108, 97, 110, 103 + }; + if(memcmp(&data[1], &string, sizeof(QChar) * 7) == 0) + + + return XmlLanguage; + + } + + + + return NoKeyword; + } + XsdSchemaToken::NodeName XsdSchemaToken::classifier9(const QChar *data) + + { + if (data[0] == 97) + + + { + if (data[1] == 115) + + + { + + static const unsigned short string[] = + { + 115, 101, 114, 116, 105, 111, 110 + }; + if(memcmp(&data[2], &string, sizeof(QChar) * 7) == 0) + + + return Assertion; + + } + + else if (data[1] == 116) + + + { + + static const unsigned short string[] = + { + 116, 114, 105, 98, 117, 116, 101 + }; + if(memcmp(&data[2], &string, sizeof(QChar) * 7) == 0) + + + return Attribute; + + } + + + } + + else if (data[0] == 101) + + + { + + static const unsigned short string[] = + { + 120, 116, 101, 110, 115, 105, 111, 110 + }; + if(memcmp(&data[1], &string, sizeof(QChar) * 8) == 0) + + + return Extension; + + } + + else if (data[0] == 109) + + + { + if (data[1] == 97) + + + { + if (data[2] == 120) + + + { + if (data[3] == 76) + + + { + + static const unsigned short string[] = + { + 101, 110, 103, 116, 104 + }; + if(memcmp(&data[4], &string, sizeof(QChar) * 5) == 0) + + + return MaxLength; + + } + + else if (data[3] == 79) + + + { + + static const unsigned short string[] = + { + 99, 99, 117, 114, 115 + }; + if(memcmp(&data[4], &string, sizeof(QChar) * 5) == 0) + + + return MaxOccurs; + + } + + + } + + + } + + else if (data[1] == 105) + + + { + if (data[2] == 110) + + + { + if (data[3] == 76) + + + { + + static const unsigned short string[] = + { + 101, 110, 103, 116, 104 + }; + if(memcmp(&data[4], &string, sizeof(QChar) * 5) == 0) + + + return MinLength; + + } + + else if (data[3] == 79) + + + { + + static const unsigned short string[] = + { + 99, 99, 117, 114, 115 + }; + if(memcmp(&data[4], &string, sizeof(QChar) * 5) == 0) + + + return MinOccurs; + + } + + + } + + + } + + + } + + else if (data[0] == 110) + + + { + + static const unsigned short string[] = + { + 97, 109, 101, 115, 112, 97, 99, 101 + }; + if(memcmp(&data[1], &string, sizeof(QChar) * 8) == 0) + + + return Namespace; + + } + + + + return NoKeyword; + } + XsdSchemaToken::NodeName XsdSchemaToken::classifier10(const QChar *data) + + { + if (data[0] == 97) + + + { + + static const unsigned short string[] = + { + 110, 110, 111, 116, 97, 116, 105, 111, 110 + }; + if(memcmp(&data[1], &string, sizeof(QChar) * 9) == 0) + + + return Annotation; + + } + + else if (data[0] == 115) + + + { + + static const unsigned short string[] = + { + 105, 109, 112, 108, 101, 84, 121, 112, 101 + }; + if(memcmp(&data[1], &string, sizeof(QChar) * 9) == 0) + + + return SimpleType; + + } + + else if (data[0] == 119) + + + { + + static const unsigned short string[] = + { + 104, 105, 116, 101, 83, 112, 97, 99, 101 + }; + if(memcmp(&data[1], &string, sizeof(QChar) * 9) == 0) + + + return WhiteSpace; + + } + + + + return NoKeyword; + } + XsdSchemaToken::NodeName XsdSchemaToken::classifier11(const QChar *data) + + { + if (data[0] == 97) + + + { + + static const unsigned short string[] = + { + 108, 116, 101, 114, 110, 97, 116, 105, 118, 101 + }; + if(memcmp(&data[1], &string, sizeof(QChar) * 10) == 0) + + + return Alternative; + + } + + else if (data[0] == 99) + + + { + + static const unsigned short string[] = + { + 111, 109, 112, 108, 101, 120, 84, 121, 112, 101 + }; + if(memcmp(&data[1], &string, sizeof(QChar) * 10) == 0) + + + return ComplexType; + + } + + else if (data[0] == 101) + + + { + + static const unsigned short string[] = + { + 110, 117, 109, 101, 114, 97, 116, 105, 111, 110 + }; + if(memcmp(&data[1], &string, sizeof(QChar) * 10) == 0) + + + return Enumeration; + + } + + else if (data[0] == 109) + + + { + + static const unsigned short string[] = + { + 101, 109, 98, 101, 114, 84, 121, 112, 101, 115 + }; + if(memcmp(&data[1], &string, sizeof(QChar) * 10) == 0) + + + return MemberTypes; + + } + + else if (data[0] == 111) + + + { + + static const unsigned short string[] = + { + 112, 101, 110, 67, 111, 110, 116, 101, 110, 116 + }; + if(memcmp(&data[1], &string, sizeof(QChar) * 10) == 0) + + + return OpenContent; + + } + + else if (data[0] == 114) + + + { + + static const unsigned short string[] = + { + 101, 115, 116, 114, 105, 99, 116, 105, 111, 110 + }; + if(memcmp(&data[1], &string, sizeof(QChar) * 10) == 0) + + + return Restriction; + + } + + else if (data[0] == 116) + + + { + + static const unsigned short string[] = + { + 111, 116, 97, 108, 68, 105, 103, 105, 116, 115 + }; + if(memcmp(&data[1], &string, sizeof(QChar) * 10) == 0) + + + return TotalDigits; + + } + + + + return NoKeyword; + } + XsdSchemaToken::NodeName XsdSchemaToken::classifier12(const QChar *data) + + { + if (data[0] == 97) + + + { + + static const unsigned short string[] = + { + 110, 121, 65, 116, 116, 114, 105, 98, 117, 116, 101 + }; + if(memcmp(&data[1], &string, sizeof(QChar) * 11) == 0) + + + return AnyAttribute; + + } + + else if (data[0] == 98) + + + { + + static const unsigned short string[] = + { + 108, 111, 99, 107, 68, 101, 102, 97, 117, 108, 116 + }; + if(memcmp(&data[1], &string, sizeof(QChar) * 11) == 0) + + + return BlockDefault; + + } + + else if (data[0] == 102) + + + { + + static const unsigned short string[] = + { + 105, 110, 97, 108, 68, 101, 102, 97, 117, 108, 116 + }; + if(memcmp(&data[1], &string, sizeof(QChar) * 11) == 0) + + + return FinalDefault; + + } + + else if (data[0] == 109) + + + { + if (data[1] == 97) + + + { + if (data[2] == 120) + + + { + if (data[3] == 69) + + + { + + static const unsigned short string[] = + { + 120, 99, 108, 117, 115, 105, 118, 101 + }; + if(memcmp(&data[4], &string, sizeof(QChar) * 8) == 0) + + + return MaxExclusive; + + } + + else if (data[3] == 73) + + + { + + static const unsigned short string[] = + { + 110, 99, 108, 117, 115, 105, 118, 101 + }; + if(memcmp(&data[4], &string, sizeof(QChar) * 8) == 0) + + + return MaxInclusive; + + } + + + } + + + } + + else if (data[1] == 105) + + + { + if (data[2] == 110) + + + { + if (data[3] == 69) + + + { + + static const unsigned short string[] = + { + 120, 99, 108, 117, 115, 105, 118, 101 + }; + if(memcmp(&data[4], &string, sizeof(QChar) * 8) == 0) + + + return MinExclusive; + + } + + else if (data[3] == 73) + + + { + + static const unsigned short string[] = + { + 110, 99, 108, 117, 115, 105, 118, 101 + }; + if(memcmp(&data[4], &string, sizeof(QChar) * 8) == 0) + + + return MinInclusive; + + } + + + } + + + } + + + } + + else if (data[0] == 110) + + + { + + static const unsigned short string[] = + { + 111, 116, 78, 97, 109, 101, 115, 112, 97, 99, 101 + }; + if(memcmp(&data[1], &string, sizeof(QChar) * 11) == 0) + + + return NotNamespace; + + } + + + + return NoKeyword; + } + XsdSchemaToken::NodeName XsdSchemaToken::classifier13(const QChar *data) + + { + if (data[0] == 100) + + + { + + static const unsigned short string[] = + { + 111, 99, 117, 109, 101, 110, 116, 97, 116, 105, 111, 110 + }; + if(memcmp(&data[1], &string, sizeof(QChar) * 12) == 0) + + + return Documentation; + + } + + else if (data[0] == 115) + + + { + + static const unsigned short string[] = + { + 105, 109, 112, 108, 101, 67, 111, 110, 116, 101, 110, 116 + }; + if(memcmp(&data[1], &string, sizeof(QChar) * 12) == 0) + + + return SimpleContent; + + } + + + + return NoKeyword; + } + XsdSchemaToken::NodeName XsdSchemaToken::classifier14(const QChar *data) + + { + if (data[0] == 97) + + + { + if (data[1] == 112) + + + { + + static const unsigned short string[] = + { + 112, 108, 105, 101, 115, 84, 111, 69, 109, 112, 116, 121 + }; + if(memcmp(&data[2], &string, sizeof(QChar) * 12) == 0) + + + return AppliesToEmpty; + + } + + else if (data[1] == 116) + + + { + + static const unsigned short string[] = + { + 116, 114, 105, 98, 117, 116, 101, 71, 114, 111, 117, 112 + }; + if(memcmp(&data[2], &string, sizeof(QChar) * 12) == 0) + + + return AttributeGroup; + + } + + + } + + else if (data[0] == 99) + + + { + + static const unsigned short string[] = + { + 111, 109, 112, 108, 101, 120, 67, 111, 110, 116, 101, 110, 116 + }; + if(memcmp(&data[1], &string, sizeof(QChar) * 13) == 0) + + + return ComplexContent; + + } + + else if (data[0] == 102) + + + { + + static const unsigned short string[] = + { + 114, 97, 99, 116, 105, 111, 110, 68, 105, 103, 105, 116, 115 + }; + if(memcmp(&data[1], &string, sizeof(QChar) * 13) == 0) + + + return FractionDigits; + + } + + else if (data[0] == 115) + + + { + + static const unsigned short string[] = + { + 99, 104, 101, 109, 97, 76, 111, 99, 97, 116, 105, 111, 110 + }; + if(memcmp(&data[1], &string, sizeof(QChar) * 13) == 0) + + + return SchemaLocation; + + } + + + + return NoKeyword; + } + XsdSchemaToken::NodeName XsdSchemaToken::classifier15(const QChar *data) + + { + if (data[0] == 112) + + + { + + static const unsigned short string[] = + { + 114, 111, 99, 101, 115, 115, 67, 111, 110, 116, 101, 110, 116, 115 + }; + if(memcmp(&data[1], &string, sizeof(QChar) * 14) == 0) + + + return ProcessContents; + + } + + else if (data[0] == 116) + + + { + + static const unsigned short string[] = + { + 97, 114, 103, 101, 116, 78, 97, 109, 101, 115, 112, 97, 99, 101 + }; + if(memcmp(&data[1], &string, sizeof(QChar) * 14) == 0) + + + return TargetNamespace; + + } + + + + return NoKeyword; + } + XsdSchemaToken::NodeName XsdSchemaToken::classifier17(const QChar *data) + + { + if (data[0] == 100) + + + { + + static const unsigned short string[] = + { + 101, 102, 97, 117, 108, 116, 65, 116, 116, 114, 105, 98, 117, 116, 101, 115 + }; + if(memcmp(&data[1], &string, sizeof(QChar) * 16) == 0) + + + return DefaultAttributes; + + } + + else if (data[0] == 115) + + + { + + static const unsigned short string[] = + { + 117, 98, 115, 116, 105, 116, 117, 116, 105, 111, 110, 71, 114, 111, 117, 112 + }; + if(memcmp(&data[1], &string, sizeof(QChar) * 16) == 0) + + + return SubstitutionGroup; + + } + + + + return NoKeyword; + } + XsdSchemaToken::NodeName XsdSchemaToken::classifier18(const QChar *data) + + { + if (data[0] == 100) + + + { + + static const unsigned short string[] = + { + 101, 102, 97, 117, 108, 116, 79, 112, 101, 110, 67, 111, 110, 116, 101, 110, 116 + }; + if(memcmp(&data[1], &string, sizeof(QChar) * 17) == 0) + + + return DefaultOpenContent; + + } + + else if (data[0] == 101) + + + { + + static const unsigned short string[] = + { + 108, 101, 109, 101, 110, 116, 70, 111, 114, 109, 68, 101, 102, 97, 117, 108, 116 + }; + if(memcmp(&data[1], &string, sizeof(QChar) * 17) == 0) + + + return ElementFormDefault; + + } + + + + return NoKeyword; + } + XsdSchemaToken::NodeName XsdSchemaToken::classifier20(const QChar *data) + + { + + static const unsigned short string[] = + { + 97, 116, 116, 114, 105, 98, 117, 116, 101, 70, 111, 114, 109, 68, 101, 102, 97, 117, 108, 116 + }; + if(memcmp(&data[0], &string, sizeof(QChar) * 20) == 0) + + + return AttributeFormDefault; + + + return NoKeyword; + } + XsdSchemaToken::NodeName XsdSchemaToken::classifier21(const QChar *data) + + { + + static const unsigned short string[] = + { + 120, 112, 97, 116, 104, 68, 101, 102, 97, 117, 108, 116, 78, 97, 109, 101, 115, 112, 97, 99, 101 + }; + if(memcmp(&data[0], &string, sizeof(QChar) * 21) == 0) + + + return XPathDefaultNamespace; + + + return NoKeyword; + } + XsdSchemaToken::NodeName XsdSchemaToken::classifier22(const QChar *data) + + { + + static const unsigned short string[] = + { + 100, 101, 102, 97, 117, 108, 116, 65, 116, 116, 114, 105, 98, 117, 116, 101, 115, 65, 112, 112, 108, 121 + }; + if(memcmp(&data[0], &string, sizeof(QChar) * 22) == 0) + + + return DefaultAttributesApply; + + + return NoKeyword; + } + XsdSchemaToken::NodeName XsdSchemaToken::classifier32(const QChar *data) + + { + + static const unsigned short string[] = + { + 104, 116, 116, 112, 58, 47, 47, 119, 119, 119, 46, 119, 51, 46, 111, 114, 103, 47, 50, 48, 48, 49, 47, 88, 77, 76, 83, 99, 104, 101, 109, 97 + }; + if(memcmp(&data[0], &string, sizeof(QChar) * 32) == 0) + + + return XML_NS_SCHEMA_URI; + + + return NoKeyword; + } + XsdSchemaToken::NodeName XsdSchemaToken::toToken(const QChar *data, int length) + { + switch(length) + { + + case 2: + return classifier2(data); + + + case 3: + return classifier3(data); + + + case 4: + return classifier4(data); + + + case 5: + return classifier5(data); + + + case 6: + return classifier6(data); + + + case 7: + return classifier7(data); + + + case 8: + return classifier8(data); + + + case 9: + return classifier9(data); + + + case 10: + return classifier10(data); + + + case 11: + return classifier11(data); + + + case 12: + return classifier12(data); + + + case 13: + return classifier13(data); + + + case 14: + return classifier14(data); + + + case 15: + return classifier15(data); + + + case 17: + return classifier17(data); + + + case 18: + return classifier18(data); + + + case 20: + return classifier20(data); + + + case 21: + return classifier21(data); + + + case 22: + return classifier22(data); + + + case 32: + return classifier32(data); + + + default: + return NoKeyword; + } + } + + + QString XsdSchemaToken::toString(NodeName token) + { + const unsigned short *data = 0; + int length = 0; + + switch(token) + { + + case Abstract: + { + static const unsigned short staticallyStoredAbstract[] = + { + 97, 98, 115, 116, 114, 97, 99, 116, 0 + }; + data = staticallyStoredAbstract; + length = 8; + break; + } + + case All: + { + static const unsigned short staticallyStoredAll[] = + { + 97, 108, 108, 0 + }; + data = staticallyStoredAll; + length = 3; + break; + } + + case Alternative: + { + static const unsigned short staticallyStoredAlternative[] = + { + 97, 108, 116, 101, 114, 110, 97, 116, 105, 118, 101, 0 + }; + data = staticallyStoredAlternative; + length = 11; + break; + } + + case Annotation: + { + static const unsigned short staticallyStoredAnnotation[] = + { + 97, 110, 110, 111, 116, 97, 116, 105, 111, 110, 0 + }; + data = staticallyStoredAnnotation; + length = 10; + break; + } + + case Any: + { + static const unsigned short staticallyStoredAny[] = + { + 97, 110, 121, 0 + }; + data = staticallyStoredAny; + length = 3; + break; + } + + case AnyAttribute: + { + static const unsigned short staticallyStoredAnyAttribute[] = + { + 97, 110, 121, 65, 116, 116, 114, 105, 98, 117, 116, 101, 0 + }; + data = staticallyStoredAnyAttribute; + length = 12; + break; + } + + case Appinfo: + { + static const unsigned short staticallyStoredAppinfo[] = + { + 97, 112, 112, 105, 110, 102, 111, 0 + }; + data = staticallyStoredAppinfo; + length = 7; + break; + } + + case AppliesToEmpty: + { + static const unsigned short staticallyStoredAppliesToEmpty[] = + { + 97, 112, 112, 108, 105, 101, 115, 84, 111, 69, 109, 112, 116, 121, 0 + }; + data = staticallyStoredAppliesToEmpty; + length = 14; + break; + } + + case Assert: + { + static const unsigned short staticallyStoredAssert[] = + { + 97, 115, 115, 101, 114, 116, 0 + }; + data = staticallyStoredAssert; + length = 6; + break; + } + + case Assertion: + { + static const unsigned short staticallyStoredAssertion[] = + { + 97, 115, 115, 101, 114, 116, 105, 111, 110, 0 + }; + data = staticallyStoredAssertion; + length = 9; + break; + } + + case Attribute: + { + static const unsigned short staticallyStoredAttribute[] = + { + 97, 116, 116, 114, 105, 98, 117, 116, 101, 0 + }; + data = staticallyStoredAttribute; + length = 9; + break; + } + + case AttributeFormDefault: + { + static const unsigned short staticallyStoredAttributeFormDefault[] = + { + 97, 116, 116, 114, 105, 98, 117, 116, 101, 70, 111, 114, 109, 68, 101, 102, 97, 117, 108, 116, 0 + }; + data = staticallyStoredAttributeFormDefault; + length = 20; + break; + } + + case AttributeGroup: + { + static const unsigned short staticallyStoredAttributeGroup[] = + { + 97, 116, 116, 114, 105, 98, 117, 116, 101, 71, 114, 111, 117, 112, 0 + }; + data = staticallyStoredAttributeGroup; + length = 14; + break; + } + + case Base: + { + static const unsigned short staticallyStoredBase[] = + { + 98, 97, 115, 101, 0 + }; + data = staticallyStoredBase; + length = 4; + break; + } + + case Block: + { + static const unsigned short staticallyStoredBlock[] = + { + 98, 108, 111, 99, 107, 0 + }; + data = staticallyStoredBlock; + length = 5; + break; + } + + case BlockDefault: + { + static const unsigned short staticallyStoredBlockDefault[] = + { + 98, 108, 111, 99, 107, 68, 101, 102, 97, 117, 108, 116, 0 + }; + data = staticallyStoredBlockDefault; + length = 12; + break; + } + + case Choice: + { + static const unsigned short staticallyStoredChoice[] = + { + 99, 104, 111, 105, 99, 101, 0 + }; + data = staticallyStoredChoice; + length = 6; + break; + } + + case Collapse: + { + static const unsigned short staticallyStoredCollapse[] = + { + 99, 111, 108, 108, 97, 112, 115, 101, 0 + }; + data = staticallyStoredCollapse; + length = 8; + break; + } + + case ComplexContent: + { + static const unsigned short staticallyStoredComplexContent[] = + { + 99, 111, 109, 112, 108, 101, 120, 67, 111, 110, 116, 101, 110, 116, 0 + }; + data = staticallyStoredComplexContent; + length = 14; + break; + } + + case ComplexType: + { + static const unsigned short staticallyStoredComplexType[] = + { + 99, 111, 109, 112, 108, 101, 120, 84, 121, 112, 101, 0 + }; + data = staticallyStoredComplexType; + length = 11; + break; + } + + case Default: + { + static const unsigned short staticallyStoredDefault[] = + { + 100, 101, 102, 97, 117, 108, 116, 0 + }; + data = staticallyStoredDefault; + length = 7; + break; + } + + case DefaultAttributes: + { + static const unsigned short staticallyStoredDefaultAttributes[] = + { + 100, 101, 102, 97, 117, 108, 116, 65, 116, 116, 114, 105, 98, 117, 116, 101, 115, 0 + }; + data = staticallyStoredDefaultAttributes; + length = 17; + break; + } + + case DefaultAttributesApply: + { + static const unsigned short staticallyStoredDefaultAttributesApply[] = + { + 100, 101, 102, 97, 117, 108, 116, 65, 116, 116, 114, 105, 98, 117, 116, 101, 115, 65, 112, 112, 108, 121, 0 + }; + data = staticallyStoredDefaultAttributesApply; + length = 22; + break; + } + + case DefaultOpenContent: + { + static const unsigned short staticallyStoredDefaultOpenContent[] = + { + 100, 101, 102, 97, 117, 108, 116, 79, 112, 101, 110, 67, 111, 110, 116, 101, 110, 116, 0 + }; + data = staticallyStoredDefaultOpenContent; + length = 18; + break; + } + + case Documentation: + { + static const unsigned short staticallyStoredDocumentation[] = + { + 100, 111, 99, 117, 109, 101, 110, 116, 97, 116, 105, 111, 110, 0 + }; + data = staticallyStoredDocumentation; + length = 13; + break; + } + + case Element: + { + static const unsigned short staticallyStoredElement[] = + { + 101, 108, 101, 109, 101, 110, 116, 0 + }; + data = staticallyStoredElement; + length = 7; + break; + } + + case ElementFormDefault: + { + static const unsigned short staticallyStoredElementFormDefault[] = + { + 101, 108, 101, 109, 101, 110, 116, 70, 111, 114, 109, 68, 101, 102, 97, 117, 108, 116, 0 + }; + data = staticallyStoredElementFormDefault; + length = 18; + break; + } + + case Enumeration: + { + static const unsigned short staticallyStoredEnumeration[] = + { + 101, 110, 117, 109, 101, 114, 97, 116, 105, 111, 110, 0 + }; + data = staticallyStoredEnumeration; + length = 11; + break; + } + + case Extension: + { + static const unsigned short staticallyStoredExtension[] = + { + 101, 120, 116, 101, 110, 115, 105, 111, 110, 0 + }; + data = staticallyStoredExtension; + length = 9; + break; + } + + case Field: + { + static const unsigned short staticallyStoredField[] = + { + 102, 105, 101, 108, 100, 0 + }; + data = staticallyStoredField; + length = 5; + break; + } + + case Final: + { + static const unsigned short staticallyStoredFinal[] = + { + 102, 105, 110, 97, 108, 0 + }; + data = staticallyStoredFinal; + length = 5; + break; + } + + case FinalDefault: + { + static const unsigned short staticallyStoredFinalDefault[] = + { + 102, 105, 110, 97, 108, 68, 101, 102, 97, 117, 108, 116, 0 + }; + data = staticallyStoredFinalDefault; + length = 12; + break; + } + + case Fixed: + { + static const unsigned short staticallyStoredFixed[] = + { + 102, 105, 120, 101, 100, 0 + }; + data = staticallyStoredFixed; + length = 5; + break; + } + + case Form: + { + static const unsigned short staticallyStoredForm[] = + { + 102, 111, 114, 109, 0 + }; + data = staticallyStoredForm; + length = 4; + break; + } + + case FractionDigits: + { + static const unsigned short staticallyStoredFractionDigits[] = + { + 102, 114, 97, 99, 116, 105, 111, 110, 68, 105, 103, 105, 116, 115, 0 + }; + data = staticallyStoredFractionDigits; + length = 14; + break; + } + + case Group: + { + static const unsigned short staticallyStoredGroup[] = + { + 103, 114, 111, 117, 112, 0 + }; + data = staticallyStoredGroup; + length = 5; + break; + } + + case Id: + { + static const unsigned short staticallyStoredId[] = + { + 105, 100, 0 + }; + data = staticallyStoredId; + length = 2; + break; + } + + case Import: + { + static const unsigned short staticallyStoredImport[] = + { + 105, 109, 112, 111, 114, 116, 0 + }; + data = staticallyStoredImport; + length = 6; + break; + } + + case Include: + { + static const unsigned short staticallyStoredInclude[] = + { + 105, 110, 99, 108, 117, 100, 101, 0 + }; + data = staticallyStoredInclude; + length = 7; + break; + } + + case ItemType: + { + static const unsigned short staticallyStoredItemType[] = + { + 105, 116, 101, 109, 84, 121, 112, 101, 0 + }; + data = staticallyStoredItemType; + length = 8; + break; + } + + case Key: + { + static const unsigned short staticallyStoredKey[] = + { + 107, 101, 121, 0 + }; + data = staticallyStoredKey; + length = 3; + break; + } + + case Keyref: + { + static const unsigned short staticallyStoredKeyref[] = + { + 107, 101, 121, 114, 101, 102, 0 + }; + data = staticallyStoredKeyref; + length = 6; + break; + } + + case Length: + { + static const unsigned short staticallyStoredLength[] = + { + 108, 101, 110, 103, 116, 104, 0 + }; + data = staticallyStoredLength; + length = 6; + break; + } + + case List: + { + static const unsigned short staticallyStoredList[] = + { + 108, 105, 115, 116, 0 + }; + data = staticallyStoredList; + length = 4; + break; + } + + case MaxExclusive: + { + static const unsigned short staticallyStoredMaxExclusive[] = + { + 109, 97, 120, 69, 120, 99, 108, 117, 115, 105, 118, 101, 0 + }; + data = staticallyStoredMaxExclusive; + length = 12; + break; + } + + case MaxInclusive: + { + static const unsigned short staticallyStoredMaxInclusive[] = + { + 109, 97, 120, 73, 110, 99, 108, 117, 115, 105, 118, 101, 0 + }; + data = staticallyStoredMaxInclusive; + length = 12; + break; + } + + case MaxLength: + { + static const unsigned short staticallyStoredMaxLength[] = + { + 109, 97, 120, 76, 101, 110, 103, 116, 104, 0 + }; + data = staticallyStoredMaxLength; + length = 9; + break; + } + + case MaxOccurs: + { + static const unsigned short staticallyStoredMaxOccurs[] = + { + 109, 97, 120, 79, 99, 99, 117, 114, 115, 0 + }; + data = staticallyStoredMaxOccurs; + length = 9; + break; + } + + case MemberTypes: + { + static const unsigned short staticallyStoredMemberTypes[] = + { + 109, 101, 109, 98, 101, 114, 84, 121, 112, 101, 115, 0 + }; + data = staticallyStoredMemberTypes; + length = 11; + break; + } + + case MinExclusive: + { + static const unsigned short staticallyStoredMinExclusive[] = + { + 109, 105, 110, 69, 120, 99, 108, 117, 115, 105, 118, 101, 0 + }; + data = staticallyStoredMinExclusive; + length = 12; + break; + } + + case MinInclusive: + { + static const unsigned short staticallyStoredMinInclusive[] = + { + 109, 105, 110, 73, 110, 99, 108, 117, 115, 105, 118, 101, 0 + }; + data = staticallyStoredMinInclusive; + length = 12; + break; + } + + case MinLength: + { + static const unsigned short staticallyStoredMinLength[] = + { + 109, 105, 110, 76, 101, 110, 103, 116, 104, 0 + }; + data = staticallyStoredMinLength; + length = 9; + break; + } + + case MinOccurs: + { + static const unsigned short staticallyStoredMinOccurs[] = + { + 109, 105, 110, 79, 99, 99, 117, 114, 115, 0 + }; + data = staticallyStoredMinOccurs; + length = 9; + break; + } + + case Mixed: + { + static const unsigned short staticallyStoredMixed[] = + { + 109, 105, 120, 101, 100, 0 + }; + data = staticallyStoredMixed; + length = 5; + break; + } + + case Mode: + { + static const unsigned short staticallyStoredMode[] = + { + 109, 111, 100, 101, 0 + }; + data = staticallyStoredMode; + length = 4; + break; + } + + case Name: + { + static const unsigned short staticallyStoredName[] = + { + 110, 97, 109, 101, 0 + }; + data = staticallyStoredName; + length = 4; + break; + } + + case Namespace: + { + static const unsigned short staticallyStoredNamespace[] = + { + 110, 97, 109, 101, 115, 112, 97, 99, 101, 0 + }; + data = staticallyStoredNamespace; + length = 9; + break; + } + + case Nillable: + { + static const unsigned short staticallyStoredNillable[] = + { + 110, 105, 108, 108, 97, 98, 108, 101, 0 + }; + data = staticallyStoredNillable; + length = 8; + break; + } + + case NotNamespace: + { + static const unsigned short staticallyStoredNotNamespace[] = + { + 110, 111, 116, 78, 97, 109, 101, 115, 112, 97, 99, 101, 0 + }; + data = staticallyStoredNotNamespace; + length = 12; + break; + } + + case NotQName: + { + static const unsigned short staticallyStoredNotQName[] = + { + 110, 111, 116, 81, 78, 97, 109, 101, 0 + }; + data = staticallyStoredNotQName; + length = 8; + break; + } + + case Notation: + { + static const unsigned short staticallyStoredNotation[] = + { + 110, 111, 116, 97, 116, 105, 111, 110, 0 + }; + data = staticallyStoredNotation; + length = 8; + break; + } + + case OpenContent: + { + static const unsigned short staticallyStoredOpenContent[] = + { + 111, 112, 101, 110, 67, 111, 110, 116, 101, 110, 116, 0 + }; + data = staticallyStoredOpenContent; + length = 11; + break; + } + + case Override: + { + static const unsigned short staticallyStoredOverride[] = + { + 111, 118, 101, 114, 114, 105, 100, 101, 0 + }; + data = staticallyStoredOverride; + length = 8; + break; + } + + case Pattern: + { + static const unsigned short staticallyStoredPattern[] = + { + 112, 97, 116, 116, 101, 114, 110, 0 + }; + data = staticallyStoredPattern; + length = 7; + break; + } + + case Preserve: + { + static const unsigned short staticallyStoredPreserve[] = + { + 112, 114, 101, 115, 101, 114, 118, 101, 0 + }; + data = staticallyStoredPreserve; + length = 8; + break; + } + + case ProcessContents: + { + static const unsigned short staticallyStoredProcessContents[] = + { + 112, 114, 111, 99, 101, 115, 115, 67, 111, 110, 116, 101, 110, 116, 115, 0 + }; + data = staticallyStoredProcessContents; + length = 15; + break; + } + + case Public: + { + static const unsigned short staticallyStoredPublic[] = + { + 112, 117, 98, 108, 105, 99, 0 + }; + data = staticallyStoredPublic; + length = 6; + break; + } + + case Redefine: + { + static const unsigned short staticallyStoredRedefine[] = + { + 114, 101, 100, 101, 102, 105, 110, 101, 0 + }; + data = staticallyStoredRedefine; + length = 8; + break; + } + + case Ref: + { + static const unsigned short staticallyStoredRef[] = + { + 114, 101, 102, 0 + }; + data = staticallyStoredRef; + length = 3; + break; + } + + case Refer: + { + static const unsigned short staticallyStoredRefer[] = + { + 114, 101, 102, 101, 114, 0 + }; + data = staticallyStoredRefer; + length = 5; + break; + } + + case Replace: + { + static const unsigned short staticallyStoredReplace[] = + { + 114, 101, 112, 108, 97, 99, 101, 0 + }; + data = staticallyStoredReplace; + length = 7; + break; + } + + case Restriction: + { + static const unsigned short staticallyStoredRestriction[] = + { + 114, 101, 115, 116, 114, 105, 99, 116, 105, 111, 110, 0 + }; + data = staticallyStoredRestriction; + length = 11; + break; + } + + case Schema: + { + static const unsigned short staticallyStoredSchema[] = + { + 115, 99, 104, 101, 109, 97, 0 + }; + data = staticallyStoredSchema; + length = 6; + break; + } + + case SchemaLocation: + { + static const unsigned short staticallyStoredSchemaLocation[] = + { + 115, 99, 104, 101, 109, 97, 76, 111, 99, 97, 116, 105, 111, 110, 0 + }; + data = staticallyStoredSchemaLocation; + length = 14; + break; + } + + case Selector: + { + static const unsigned short staticallyStoredSelector[] = + { + 115, 101, 108, 101, 99, 116, 111, 114, 0 + }; + data = staticallyStoredSelector; + length = 8; + break; + } + + case Sequence: + { + static const unsigned short staticallyStoredSequence[] = + { + 115, 101, 113, 117, 101, 110, 99, 101, 0 + }; + data = staticallyStoredSequence; + length = 8; + break; + } + + case SimpleContent: + { + static const unsigned short staticallyStoredSimpleContent[] = + { + 115, 105, 109, 112, 108, 101, 67, 111, 110, 116, 101, 110, 116, 0 + }; + data = staticallyStoredSimpleContent; + length = 13; + break; + } + + case SimpleType: + { + static const unsigned short staticallyStoredSimpleType[] = + { + 115, 105, 109, 112, 108, 101, 84, 121, 112, 101, 0 + }; + data = staticallyStoredSimpleType; + length = 10; + break; + } + + case Source: + { + static const unsigned short staticallyStoredSource[] = + { + 115, 111, 117, 114, 99, 101, 0 + }; + data = staticallyStoredSource; + length = 6; + break; + } + + case SubstitutionGroup: + { + static const unsigned short staticallyStoredSubstitutionGroup[] = + { + 115, 117, 98, 115, 116, 105, 116, 117, 116, 105, 111, 110, 71, 114, 111, 117, 112, 0 + }; + data = staticallyStoredSubstitutionGroup; + length = 17; + break; + } + + case System: + { + static const unsigned short staticallyStoredSystem[] = + { + 115, 121, 115, 116, 101, 109, 0 + }; + data = staticallyStoredSystem; + length = 6; + break; + } + + case TargetNamespace: + { + static const unsigned short staticallyStoredTargetNamespace[] = + { + 116, 97, 114, 103, 101, 116, 78, 97, 109, 101, 115, 112, 97, 99, 101, 0 + }; + data = staticallyStoredTargetNamespace; + length = 15; + break; + } + + case Test: + { + static const unsigned short staticallyStoredTest[] = + { + 116, 101, 115, 116, 0 + }; + data = staticallyStoredTest; + length = 4; + break; + } + + case TotalDigits: + { + static const unsigned short staticallyStoredTotalDigits[] = + { + 116, 111, 116, 97, 108, 68, 105, 103, 105, 116, 115, 0 + }; + data = staticallyStoredTotalDigits; + length = 11; + break; + } + + case Type: + { + static const unsigned short staticallyStoredType[] = + { + 116, 121, 112, 101, 0 + }; + data = staticallyStoredType; + length = 4; + break; + } + + case Union: + { + static const unsigned short staticallyStoredUnion[] = + { + 117, 110, 105, 111, 110, 0 + }; + data = staticallyStoredUnion; + length = 5; + break; + } + + case Unique: + { + static const unsigned short staticallyStoredUnique[] = + { + 117, 110, 105, 113, 117, 101, 0 + }; + data = staticallyStoredUnique; + length = 6; + break; + } + + case Use: + { + static const unsigned short staticallyStoredUse[] = + { + 117, 115, 101, 0 + }; + data = staticallyStoredUse; + length = 3; + break; + } + + case Value: + { + static const unsigned short staticallyStoredValue[] = + { + 118, 97, 108, 117, 101, 0 + }; + data = staticallyStoredValue; + length = 5; + break; + } + + case Version: + { + static const unsigned short staticallyStoredVersion[] = + { + 118, 101, 114, 115, 105, 111, 110, 0 + }; + data = staticallyStoredVersion; + length = 7; + break; + } + + case WhiteSpace: + { + static const unsigned short staticallyStoredWhiteSpace[] = + { + 119, 104, 105, 116, 101, 83, 112, 97, 99, 101, 0 + }; + data = staticallyStoredWhiteSpace; + length = 10; + break; + } + + case XML_NS_SCHEMA_URI: + { + static const unsigned short staticallyStoredXML_NS_SCHEMA_URI[] = + { + 104, 116, 116, 112, 58, 47, 47, 119, 119, 119, 46, 119, 51, 46, 111, 114, 103, 47, 50, 48, 48, 49, 47, 88, 77, 76, 83, 99, 104, 101, 109, 97, 0 + }; + data = staticallyStoredXML_NS_SCHEMA_URI; + length = 32; + break; + } + + case XPathDefaultNamespace: + { + static const unsigned short staticallyStoredXPathDefaultNamespace[] = + { + 120, 112, 97, 116, 104, 68, 101, 102, 97, 117, 108, 116, 78, 97, 109, 101, 115, 112, 97, 99, 101, 0 + }; + data = staticallyStoredXPathDefaultNamespace; + length = 21; + break; + } + + case XmlLanguage: + { + static const unsigned short staticallyStoredXmlLanguage[] = + { + 120, 109, 108, 58, 108, 97, 110, 103, 0 + }; + data = staticallyStoredXmlLanguage; + length = 8; + break; + } + + case Xpath: + { + static const unsigned short staticallyStoredXpath[] = + { + 120, 112, 97, 116, 104, 0 + }; + data = staticallyStoredXpath; + length = 5; + break; + } + + default: + /* It's either the default token, or an undefined enum + * value. We silence a compiler warning, and return the + * empty string. */ + ; + } + + union + { + const unsigned short *data; + const QChar *asQChar; + } converter; + converter.data = data; + + return QString::fromRawData(converter.asQChar, length); + } + +QT_END_NAMESPACE + diff --git a/src/xmlpatterns/schema/qxsdschematoken_p.h b/src/xmlpatterns/schema/qxsdschematoken_p.h new file mode 100644 index 0000000..8cb1e76 --- /dev/null +++ b/src/xmlpatterns/schema/qxsdschematoken_p.h @@ -0,0 +1,168 @@ +/**************************************************************************** +** +** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the $MODULE$ of the Qt Toolkit. +** +** $TROLLTECH_DUAL_LICENSE$ +** +****************************************************************************/ + +/* NOTE: This file is AUTO GENERATED by qautomaton2cpp.xsl. */ + +#ifndef QPatternist_XsdSchemaToken_h +#define QPatternist_XsdSchemaToken_h + +#include + +QT_BEGIN_NAMESPACE + +class XsdSchemaToken + { + public: + enum NodeName + + { + NoKeyword, +Abstract, +All, +Alternative, +Annotation, +Any, +AnyAttribute, +Appinfo, +AppliesToEmpty, +Assert, +Assertion, +Attribute, +AttributeFormDefault, +AttributeGroup, +Base, +Block, +BlockDefault, +Choice, +Collapse, +ComplexContent, +ComplexType, +Default, +DefaultAttributes, +DefaultAttributesApply, +DefaultOpenContent, +Documentation, +Element, +ElementFormDefault, +Enumeration, +Extension, +Field, +Final, +FinalDefault, +Fixed, +Form, +FractionDigits, +Group, +Id, +Import, +Include, +ItemType, +Key, +Keyref, +Length, +List, +MaxExclusive, +MaxInclusive, +MaxLength, +MaxOccurs, +MemberTypes, +MinExclusive, +MinInclusive, +MinLength, +MinOccurs, +Mixed, +Mode, +Name, +Namespace, +Nillable, +NotNamespace, +NotQName, +Notation, +OpenContent, +Override, +Pattern, +Preserve, +ProcessContents, +Public, +Redefine, +Ref, +Refer, +Replace, +Restriction, +Schema, +SchemaLocation, +Selector, +Sequence, +SimpleContent, +SimpleType, +Source, +SubstitutionGroup, +System, +TargetNamespace, +Test, +TotalDigits, +Type, +Union, +Unique, +Use, +Value, +Version, +WhiteSpace, +XML_NS_SCHEMA_URI, +XPathDefaultNamespace, +XmlLanguage, +Xpath + }; + + static inline NodeName toToken(const QString &value); +static inline NodeName toToken(const QStringRef &value); +static NodeName toToken(const QChar *data, int length); +static QString toString(NodeName token); + + + private: + static inline NodeName classifier2(const QChar *data); +static inline NodeName classifier3(const QChar *data); +static inline NodeName classifier4(const QChar *data); +static inline NodeName classifier5(const QChar *data); +static inline NodeName classifier6(const QChar *data); +static inline NodeName classifier7(const QChar *data); +static inline NodeName classifier8(const QChar *data); +static inline NodeName classifier9(const QChar *data); +static inline NodeName classifier10(const QChar *data); +static inline NodeName classifier11(const QChar *data); +static inline NodeName classifier12(const QChar *data); +static inline NodeName classifier13(const QChar *data); +static inline NodeName classifier14(const QChar *data); +static inline NodeName classifier15(const QChar *data); +static inline NodeName classifier17(const QChar *data); +static inline NodeName classifier18(const QChar *data); +static inline NodeName classifier20(const QChar *data); +static inline NodeName classifier21(const QChar *data); +static inline NodeName classifier22(const QChar *data); +static inline NodeName classifier32(const QChar *data); + + }; + + inline XsdSchemaToken::NodeName XsdSchemaToken::toToken(const QString &value) + { + return toToken(value.constData(), value.length()); + } + + inline XsdSchemaToken::NodeName XsdSchemaToken::toToken(const QStringRef &value) + { + return toToken(value.constData(), value.length()); + } + + +QT_END_NAMESPACE + +#endif diff --git a/src/xmlpatterns/schema/qxsdschematypesfactory.cpp b/src/xmlpatterns/schema/qxsdschematypesfactory.cpp new file mode 100644 index 0000000..6cac0ff --- /dev/null +++ b/src/xmlpatterns/schema/qxsdschematypesfactory.cpp @@ -0,0 +1,96 @@ +/**************************************************************************** +** +** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the $MODULE$ of the Qt Toolkit. +** +** $TROLLTECH_DUAL_LICENSE$ +** +****************************************************************************/ + +#include "qxsdschematypesfactory_p.h" + +#include "qbasictypesfactory_p.h" +#include "qbuiltintypes_p.h" +#include "qderivedinteger_p.h" +#include "qderivedstring_p.h" +#include "qcommonnamespaces_p.h" +#include "qxsdschematoken_p.h" +#include "qxsdsimpletype_p.h" + +QT_BEGIN_NAMESPACE + +using namespace QPatternist; + +XsdSchemaTypesFactory::XsdSchemaTypesFactory(const NamePool::Ptr &namePool) + : m_namePool(namePool) +{ + m_types.reserve(3); + + const XsdFacet::Ptr whiteSpaceFacet(new XsdFacet()); + whiteSpaceFacet->setType(XsdFacet::WhiteSpace); + whiteSpaceFacet->setFixed(true); + whiteSpaceFacet->setValue(DerivedString::fromLexical(m_namePool, XsdSchemaToken::toString(XsdSchemaToken::Collapse))); + + const XsdFacet::Ptr minLengthFacet(new XsdFacet()); + minLengthFacet->setType(XsdFacet::MinimumLength); + minLengthFacet->setValue(DerivedInteger::fromLexical(namePool, QLatin1String("1"))); + + XsdFacet::Hash facets; + facets.insert(whiteSpaceFacet->type(), whiteSpaceFacet); + facets.insert(minLengthFacet->type(), minLengthFacet); + + { + const QXmlName typeName = m_namePool->allocateQName(CommonNamespaces::WXS, QLatin1String("NMTOKENS")); + const XsdSimpleType::Ptr type(new XsdSimpleType()); + type->setName(typeName); + type->setWxsSuperType(BuiltinTypes::xsAnySimpleType); + type->setCategory(XsdSimpleType::SimpleTypeList); + type->setItemType(BuiltinTypes::xsNMTOKEN); + type->setDerivationMethod(XsdSimpleType::DerivationRestriction); + type->setFacets(facets); + m_types.insert(typeName, type); + } + { + const QXmlName typeName = m_namePool->allocateQName(CommonNamespaces::WXS, QLatin1String("IDREFS")); + const XsdSimpleType::Ptr type(new XsdSimpleType()); + type->setName(typeName); + type->setWxsSuperType(BuiltinTypes::xsAnySimpleType); + type->setCategory(XsdSimpleType::SimpleTypeList); + type->setItemType(BuiltinTypes::xsIDREF); + type->setDerivationMethod(XsdSimpleType::DerivationRestriction); + type->setFacets(facets); + m_types.insert(typeName, type); + } + { + const QXmlName typeName = m_namePool->allocateQName(CommonNamespaces::WXS, QLatin1String("ENTITIES")); + const XsdSimpleType::Ptr type(new XsdSimpleType()); + type->setName(typeName); + type->setWxsSuperType(BuiltinTypes::xsAnySimpleType); + type->setCategory(XsdSimpleType::SimpleTypeList); + type->setItemType(BuiltinTypes::xsENTITY); + type->setDerivationMethod(XsdSimpleType::DerivationRestriction); + type->setFacets(facets); + m_types.insert(typeName, type); + } +} + +SchemaType::Ptr XsdSchemaTypesFactory::createSchemaType(const QXmlName name) const +{ + if (m_types.contains(name)) { + return m_types.value(name); + } else { + if (!m_basicTypesFactory) + m_basicTypesFactory = BasicTypesFactory::self(m_namePool); + + return m_basicTypesFactory->createSchemaType(name); + } +} + +SchemaType::Hash XsdSchemaTypesFactory::types() const +{ + return m_types; +} + +QT_END_NAMESPACE diff --git a/src/xmlpatterns/schema/qxsdschematypesfactory_p.h b/src/xmlpatterns/schema/qxsdschematypesfactory_p.h new file mode 100644 index 0000000..4fcd5fb --- /dev/null +++ b/src/xmlpatterns/schema/qxsdschematypesfactory_p.h @@ -0,0 +1,79 @@ +/**************************************************************************** +** +** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the $MODULE$ of the Qt Toolkit. +** +** $TROLLTECH_DUAL_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_XsdSchemaTypesFactory_H +#define Patternist_XsdSchemaTypesFactory_H + +#include +#include "qschematypefactory_p.h" + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +namespace QPatternist +{ + + /** + * @short Factory for creating schema types for the types defined in XSD. + * + * @ingroup Patternist_types + * @author Tobias Koenig + */ + class XsdSchemaTypesFactory : public SchemaTypeFactory + { + public: + /** + * Creates a new schema type factory. + * + * @param namePool The name pool all type names belong to. + */ + XsdSchemaTypesFactory(const NamePool::Ptr &namePool); + + /** + * Creates a primitive type for @p name. If @p name is not supported, + * @c null is returned. + * + * @note This does not handle user defined types, only builtin types. + */ + virtual SchemaType::Ptr createSchemaType(const QXmlName) const; + + /** + * Returns a hash of all available types. + */ + virtual SchemaType::Hash types() const; + + private: + /** + * A dictonary of all predefined schema types. + */ + SchemaType::Hash m_types; + + NamePool::Ptr m_namePool; + mutable SchemaTypeFactory::Ptr m_basicTypesFactory; + }; +} + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif diff --git a/src/xmlpatterns/schema/qxsdsimpletype.cpp b/src/xmlpatterns/schema/qxsdsimpletype.cpp new file mode 100644 index 0000000..2e5b7f5 --- /dev/null +++ b/src/xmlpatterns/schema/qxsdsimpletype.cpp @@ -0,0 +1,118 @@ +/**************************************************************************** +** +** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the $MODULE$ of the Qt Toolkit. +** +** $TROLLTECH_DUAL_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. + +#include "qxsdsimpletype_p.h" + +QT_BEGIN_NAMESPACE + +using namespace QPatternist; + +QString XsdSimpleType::displayName(const NamePool::Ptr &np) const +{ + return np->displayName(name(np)); +} + +void XsdSimpleType::setWxsSuperType(const SchemaType::Ptr &type) +{ + m_superType = type; +} + +SchemaType::Ptr XsdSimpleType::wxsSuperType() const +{ + return m_superType; +} + +void XsdSimpleType::setContext(const NamedSchemaComponent::Ptr &component) +{ + m_context = component; +} + +NamedSchemaComponent::Ptr XsdSimpleType::context() const +{ + return m_context; +} + +void XsdSimpleType::setPrimitiveType(const AnySimpleType::Ptr &type) +{ + m_primitiveType = type; +} + +AnySimpleType::Ptr XsdSimpleType::primitiveType() const +{ + return m_primitiveType; +} + +void XsdSimpleType::setItemType(const AnySimpleType::Ptr &type) +{ + m_itemType = type; +} + +AnySimpleType::Ptr XsdSimpleType::itemType() const +{ + return m_itemType; +} + +void XsdSimpleType::setMemberTypes(const AnySimpleType::List &types) +{ + m_memberTypes = types; +} + +AnySimpleType::List XsdSimpleType::memberTypes() const +{ + return m_memberTypes; +} + +void XsdSimpleType::setFacets(const XsdFacet::Hash &facets) +{ + m_facets = facets; +} + +XsdFacet::Hash XsdSimpleType::facets() const +{ + return m_facets; +} + +void XsdSimpleType::setCategory(TypeCategory category) +{ + m_typeCategory = category; +} + +XsdSimpleType::TypeCategory XsdSimpleType::category() const +{ + return m_typeCategory; +} + +void XsdSimpleType::setDerivationMethod(DerivationMethod method) +{ + m_derivationMethod = method; +} + +XsdSimpleType::DerivationMethod XsdSimpleType::derivationMethod() const +{ + return m_derivationMethod; +} + +bool XsdSimpleType::isDefinedBySchema() const +{ + return true; +} + +QT_END_NAMESPACE diff --git a/src/xmlpatterns/schema/qxsdsimpletype_p.h b/src/xmlpatterns/schema/qxsdsimpletype_p.h new file mode 100644 index 0000000..9ba34b6 --- /dev/null +++ b/src/xmlpatterns/schema/qxsdsimpletype_p.h @@ -0,0 +1,189 @@ +/**************************************************************************** +** +** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the $MODULE$ of the Qt Toolkit. +** +** $TROLLTECH_DUAL_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_XsdSimpleType_H +#define Patternist_XsdSimpleType_H + +#include "qanysimpletype_p.h" +#include "qxsdfacet_p.h" +#include "qxsduserschematype_p.h" + +#include + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +namespace QPatternist +{ + /** + * @short Represents a XSD simpleType object. + * + * This class represents the simpleType object of a XML schema as described + * here. + * + * It contains information from either a top-level simple type declaration (as child of a schema object) + * or a local simple type declaration (as descendant of an element or complexType object). + * + * @see XML Schema API reference + * @ingroup Patternist_schema + * @author Tobias Koenig + */ + class XsdSimpleType : public XsdUserSchemaType + { + public: + typedef QExplicitlySharedDataPointer Ptr; + + /** + * Returns the display name of the simple type. + * + * @param namePool The name pool the type name is stored in. + */ + virtual QString displayName(const NamePool::Ptr &namePool) const; + + /** + * Sets the base @p type of the simple type. + * + * @see Base Type Definition + */ + void setWxsSuperType(const SchemaType::Ptr &type); + + /** + * Returns the base type of the simple type or an empty pointer if no base type is + * set. + */ + virtual SchemaType::Ptr wxsSuperType() const; + + /** + * Sets the context @p component of the simple type. + * + * @see Context Definition + */ + void setContext(const NamedSchemaComponent::Ptr &component); + + /** + * Returns the context component of the simple type. + */ + NamedSchemaComponent::Ptr context() const; + + /** + * Sets the primitive @p type of the simple type. + * + * The primitive type is only specified if the category is SimpleTypeAtomic. + * + * @see Primitive Type Definition + */ + void setPrimitiveType(const AnySimpleType::Ptr &type); + + /** + * Returns the primitive type of the simple type or an empty pointer if the category is + * not SimpleTypeAtomic. + */ + AnySimpleType::Ptr primitiveType() const; + + /** + * Sets the list item @p type of the simple type. + * + * The list item type is only specified if the category is SimpleTypeList. + * + * @see Item Type Definition + */ + void setItemType(const AnySimpleType::Ptr &type); + + /** + * Returns the list item type of the simple type or an empty pointer if the category is + * not SimpleTypeList. + */ + AnySimpleType::Ptr itemType() const; + + /** + * Sets the member @p types of the simple type. + * + * The member types are only specified if the category is SimpleTypeUnion. + * + * @see Member Types Definition + */ + void setMemberTypes(const AnySimpleType::List &types); + + /** + * Returns the list member types of the simple type or an empty list if the category is + * not SimpleTypeUnion. + */ + AnySimpleType::List memberTypes() const; + + /** + * Sets the @p facets of the simple type. + * + * @see Facets Definition + */ + void setFacets(const XsdFacet::Hash &facets); + + /** + * Returns the facets of the simple type. + */ + XsdFacet::Hash facets() const; + + /** + * Sets the @p category (variety) of the simple type. + * + * @see Variety Definition + */ + void setCategory(TypeCategory category); + + /** + * Returns the category (variety) of the simple type. + */ + virtual TypeCategory category() const; + + /** + * Sets the derivation @p method of the simple type. + * + * @see DerivationMethod + */ + void setDerivationMethod(DerivationMethod method); + + /** + * Returns the derivation method of the simple type. + */ + virtual DerivationMethod derivationMethod() const; + + /** + * Always returns @c true. + */ + virtual bool isDefinedBySchema() const; + + private: + SchemaType::Ptr m_superType; + NamedSchemaComponent::Ptr m_context; + AnySimpleType::Ptr m_primitiveType; + AnySimpleType::Ptr m_itemType; + AnySimpleType::List m_memberTypes; + XsdFacet::Hash m_facets; + TypeCategory m_typeCategory; + DerivationMethod m_derivationMethod; + }; +} + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif diff --git a/src/xmlpatterns/schema/qxsdstatemachine.cpp b/src/xmlpatterns/schema/qxsdstatemachine.cpp new file mode 100644 index 0000000..e40e55b --- /dev/null +++ b/src/xmlpatterns/schema/qxsdstatemachine.cpp @@ -0,0 +1,433 @@ +/**************************************************************************** +** +** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the $MODULE$ of the Qt Toolkit. +** +** $TROLLTECH_DUAL_LICENSE$ +** +****************************************************************************/ + +/* + * NOTE: This file is included by qxsdstatemachine_p.h + * if you need some includes, put them in qxsdstatemachine_p.h (outside of the namespace) + */ + +template +XsdStateMachine::XsdStateMachine() + : m_counter(50) +{ +} + +template +XsdStateMachine::XsdStateMachine(const NamePool::Ptr &namePool) + : m_namePool(namePool) + , m_counter(50) +{ +} + +template +typename XsdStateMachine::StateId XsdStateMachine::addState(StateType type) +{ +#ifndef QT_NO_DEBUG + // make sure we don't have two start states + if (type == StartState) { + QHashIterator it(m_states); + while (it.hasNext()) { + it.next(); + Q_ASSERT(it.value() != StartState && it.value() != StartEndState); + } + } +#endif // QT_NO_DEBUG + + // reserve new state id + const StateId id = ++m_counter; + m_states.insert(id, type); + + // if it is a start state, we make it to our current state + if (type == StartState || type == StartEndState) + m_currentState = id; + + return id; +} + +template +void XsdStateMachine::addTransition(StateId start, TransitionType transition, StateId end) +{ + QHash > &hash = m_transitions[start]; + QVector &states = hash[transition]; + if (!states.contains(end)) + states.append(end); +} + +template +void XsdStateMachine::addEpsilonTransition(StateId start, StateId end) +{ + QVector &states = m_epsilonTransitions[start]; + states.append(end); +} + +template +void XsdStateMachine::reset() +{ + // reset the machine to the start state + QHashIterator it(m_states); + while (it.hasNext()) { + it.next(); + if (it.value() == StartState || it.value() == StartEndState) { + m_currentState = it.key(); + return; + } + } + + Q_ASSERT(false); +} + +template +void XsdStateMachine::clear() +{ + m_states.clear(); + m_transitions.clear(); + m_epsilonTransitions.clear(); + m_currentState = -1; + m_counter = 50; +} + +template +bool XsdStateMachine::proceed(TransitionType transition) +{ + // check that we are not in an invalid state + if (!m_transitions.contains(m_currentState)) { + return false; + } + + // fetch the transition entry for the current state + const QHash > &entry = m_transitions[m_currentState]; + if (entry.contains(transition)) { // is there an transition for the given input? + m_currentState = entry.value(transition).first(); + m_lastTransition = transition; + return true; + } else { + return false; + } +} + +template +template +bool XsdStateMachine::proceed(InputType input) +{ + // check that we are not in an invalid state + if (!m_transitions.contains(m_currentState)) { + return false; + } + + // fetch the transition entry for the current state + const QHash > &entry = m_transitions[m_currentState]; + QHashIterator > it(entry); + while (it.hasNext()) { + it.next(); + if (inputEqualsTransition(input, it.key())) { + m_currentState = it.value().first(); + m_lastTransition = it.key(); + return true; + } + } + + return false; +} + +template +template +bool XsdStateMachine::inputEqualsTransition(InputType input, TransitionType transition) const +{ + return false; +} + +template +bool XsdStateMachine::inEndState() const +{ + // check if current state is an end state + return (m_states.value(m_currentState) == StartEndState || m_states.value(m_currentState) == EndState); +} + +template +TransitionType XsdStateMachine::lastTransition() const +{ + return m_lastTransition; +} + +template +typename XsdStateMachine::StateId XsdStateMachine::startState() const +{ + QHashIterator it(m_states); + while (it.hasNext()) { + it.next(); + if (it.value() == StartState || it.value() == StartEndState) + return it.key(); + } + + Q_ASSERT(false); // should never be reached + return -1; +} + +template +QString XsdStateMachine::transitionTypeToString(TransitionType type) const +{ + Q_UNUSED(type) + + return QString(); +} + +template +bool XsdStateMachine::outputGraph(QIODevice *device, const QString &graphName) const +{ + if (!device->isOpen()) { + qWarning("device must be open for writing"); + return false; + } + + QByteArray graph; + QTextStream s(&graph); + + QHashIterator > > it(m_transitions); + QHashIterator it3(m_states); + + s << "digraph " << graphName << " {\n"; + s << " mindist = 2.0\n"; + + // draw edges + while (it.hasNext()) { + it.next(); + + QHashIterator > it2(it.value()); + while (it2.hasNext()) { + it2.next(); + for (int i = 0; i < it2.value().count(); ++i) + s << " " << it.key() << " -> " << it2.value().at(i) << " [label=\"" << transitionTypeToString(it2.key()) << "\"]\n"; + } + } + + QHashIterator > it4(m_epsilonTransitions); + while (it4.hasNext()) { + it4.next(); + + const QVector states = it4.value(); + for (int i = 0; i < states.count(); ++i) + s << " " << it4.key() << " -> " << states.at(i) << " [label=\"ε\"]\n"; + } + + // draw node infos + while (it3.hasNext()) { + it3.next(); + + QString style; + if (it3.value() == StartState) { + style = QLatin1String("shape=circle, style=filled, color=blue"); + } else if (it3.value() == StartEndState) { + style = QLatin1String("shape=doublecircle, style=filled, color=blue"); + } else if (it3.value() == InternalState) { + style = QLatin1String("shape=circle, style=filled, color=red"); + } else if (it3.value() == EndState) { + style = QLatin1String("shape=doublecircle, style=filled, color=green"); + } + + s << " " << it3.key() << " [" << style << "]\n"; + } + + s << "}\n"; + + s.flush(); + + if (device->write(graph) == -1) + return false; + + return true; +} + + +template +typename XsdStateMachine::StateId XsdStateMachine::dfaStateForNfaState(QSet nfaState, + QList< QPair, StateId> > &stateTable, + XsdStateMachine &dfa) const +{ + // check whether we have the given state in our lookup table + // already, in that case simply return it + for (int i = 0; i < stateTable.count(); ++i) { + if (stateTable.at(i).first == nfaState) + return stateTable.at(i).second; + } + + // check if the NFA state set contains a Start or End + // state, in that case our new DFA state will be a + // Start or End state as well + StateType type = InternalState; + QSetIterator it(nfaState); + bool hasStartState = false; + bool hasEndState = false; + while (it.hasNext()) { + const StateId state = it.next(); + if (m_states.value(state) == EndState) { + hasEndState = true; + } else if (m_states.value(state) == StartState) { + hasStartState = true; + } + } + if (hasStartState) { + if (hasEndState) + type = StartEndState; + else + type = StartState; + } else if (hasEndState) { + type = EndState; + } + + // create the new DFA state + const StateId dfaState = dfa.addState(type); + + // add the new DFA state to the lookup table + stateTable.append(qMakePair, StateId>(nfaState, dfaState)); + + return dfaState; +} + + +template +QSet::StateId> XsdStateMachine::epsilonClosure(const QSet &input) const +{ + // every state can reach itself by epsilon transition, so include the input states + // in the result as well + QSet result = input; + + // add the input states to the list of to be processed states + QList workStates = input.toList(); + while (!workStates.isEmpty()) { // while there are states to be processed left... + + // dequeue one state from list + const StateId state = workStates.takeFirst(); + + // get the list of states that can be reached by the epsilon transition + // from the current 'state' + const QVector targetStates = m_epsilonTransitions.value(state); + for (int i = 0; i < targetStates.count(); ++i) { + // if we have this target state not in our result set yet... + if (!result.contains(targetStates.at(i))) { + // ... add it to the result set + result.insert(targetStates.at(i)); + + // add the target state to the list of to be processed states as well, + // as we want to have the epsilon transitions not only for the first + // level of following states + workStates.append(targetStates.at(i)); + } + } + } + + return result; +} + +template +QSet::StateId> XsdStateMachine::move(const QSet &states, TransitionType input) const +{ + QSet result; + + QSetIterator it(states); + while (it.hasNext()) { // iterate over all given states + const StateId state = it.next(); + + // get the transition table for the current state + const QHash > transitions = m_transitions.value(state); + + // get the target states for the given input + const QVector targetStates = transitions.value(input); + + // add all target states to the result + for (int i = 0; i < targetStates.size(); ++i) + result.insert(targetStates.at(i)); + } + + return result; +} + +template +XsdStateMachine XsdStateMachine::toDFA() const +{ + XsdStateMachine dfa(m_namePool); + dfa.m_counter = 100; + QList< QPair< QSet, StateId> > table; + QList< QSet > isMarked; + + // search the start state as the algorithm starts with it... + StateId startState = -1; + QHashIterator stateTypeIt(m_states); + while (stateTypeIt.hasNext()) { + stateTypeIt.next(); + if (stateTypeIt.value() == StartState) { + startState = stateTypeIt.key(); + break; + } + } + Q_ASSERT(startState != -1); + + // our list of state set that still have to be processed + QList< QSet > workStates; + + // add the start state to the list of to processed state sets + workStates.append(epsilonClosure(QSet() << startState)); + + while (!workStates.isEmpty()) { // as long as there are state sets to process left + + // enqueue set of states + const QSet states = workStates.takeFirst(); + + if (isMarked.contains(states)) // we processed this state set already + continue; + + // mark as processed + isMarked.append(states); + + // select a list of all inputs that are possible for + // the 'states' set + QList input; + + { + QSetIterator it(states); + while (it.hasNext()) { + input << m_transitions.value(it.next()).keys(); + } + } + + // get the state in DFA that corresponds to the 'states' set in the NFA + const StateId dfaBegin = dfaStateForNfaState(states, table, dfa); + + for (int i = 0; i < input.count(); ++i) { // for each possible input + // retrieve the states that can be reached from the 'states' set by the + // given input or by epsilon transition + const QSet followStates = epsilonClosure(move(states, input.at(i))); + + // get the state in DFA that corresponds to the 'followStates' set in the NFA + const StateId dfaEnd = dfaStateForNfaState(followStates, table, dfa); + + // adds a new transition to the DFA that corresponds to the transitions between + // 'states' and 'followStates' in the NFA + dfa.addTransition(dfaBegin, input.at(i), dfaEnd); + + // add the 'followStates' to the list of to be processed state sets + workStates.append(followStates); + } + } + + return dfa; +} + +template +QHash::StateId, typename XsdStateMachine::StateType> XsdStateMachine::states() const +{ + return m_states; +} + +template +QHash::StateId, QHash::StateId> > > XsdStateMachine::transitions() const +{ + return m_transitions; +} diff --git a/src/xmlpatterns/schema/qxsdstatemachine_p.h b/src/xmlpatterns/schema/qxsdstatemachine_p.h new file mode 100644 index 0000000..7988335 --- /dev/null +++ b/src/xmlpatterns/schema/qxsdstatemachine_p.h @@ -0,0 +1,209 @@ +/**************************************************************************** +** +** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the $MODULE$ of the Qt Toolkit. +** +** $TROLLTECH_DUAL_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_XsdStateMachine_H +#define Patternist_XsdStateMachine_H + +#include "qnamepool_p.h" + +#include +#include +#include + +class QIODevice; + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +namespace QPatternist +{ + /** + * @short A state machine used for evaluation. + * + * @ingroup Patternist_schema + * @author Tobias Koenig + */ + template + class XsdStateMachine + { + public: + typedef qint32 StateId; + + /** + * Describes the type of state. + */ + enum StateType + { + StartState, ///< The state the machine will start with. + StartEndState, ///< The state the machine will start with, can be end state as well. + InternalState, ///< Any state that is not start or end state. + EndState ///< Any state where the machine is allowed to stop. + }; + + /** + * Creates a new state machine object. + */ + XsdStateMachine(); + + /** + * Creates a new state machine object. + * + * The name pool to use for accessing object names. + */ + XsdStateMachine(const NamePool::Ptr &namePool); + + /** + * Adds a new state of the given @p type to the state machine. + * + * @return The id of the new state. + */ + StateId addState(StateType type); + + /** + * Adds a new @p transition to the state machine. + * + * @param start The start state. + * @param transition The transition to come from the start to the end state. + * @param end The end state. + */ + void addTransition(StateId start, TransitionType transition, StateId end); + + /** + * Adds a new epsilon @p transition to the state machine. + * + * @param start The start state. + * @param end The end state. + */ + void addEpsilonTransition(StateId start, StateId end); + + /** + * Resets the machine to the start state. + */ + void reset(); + + /** + * Removes all states and transitions from the state machine. + */ + void clear(); + + /** + * Continues execution of the machine with the given input @p transition. + * + * @return @c true if the transition was successfull, @c false otherwise. + */ + bool proceed(TransitionType transition); + + /** + * Continues execution of the machine with the given @p input. + * + * @note To use this method, inputEqualsTransition must be implemented + * to find the right transition to use. + * + * @return @c true if the transition was successfull, @c false otherwise. + */ + template + bool proceed(InputType input); + + /** + * Returns whether the given @p input matches the given @p transition. + */ + template + bool inputEqualsTransition(InputType input, TransitionType transition) const; + + /** + * Returns whether the machine is in an allowed end state. + */ + bool inEndState() const; + + /** + * Returns the last transition that was taken. + */ + TransitionType lastTransition() const; + + /** + * Returns the start state of the machine. + */ + StateId startState() const; + + /** + * This method should be redefined by template specialization for every + * concret TransitionType. + */ + QString transitionTypeToString(TransitionType type) const; + + /** + * Outputs the state machine in DOT format to the given + * output @p device. + */ + bool outputGraph(QIODevice *device, const QString &graphName) const; + + /** + * Returns a DFA that is equal to the NFA of the state machine. + */ + XsdStateMachine toDFA() const; + + /** + * Returns the information of all states of the state machine. + */ + QHash states() const; + + /** + * Returns the information of all transitions of the state machine. + */ + QHash > > transitions() const; + + private: + /** + * Returns the DFA state for the given @p nfaStat from the given @p stateTable. + * If there is no corresponding DFA state yet, a new one is created. + */ + StateId dfaStateForNfaState(QSet nfaState, QList< QPair< QSet, StateId> > &stateTable, XsdStateMachine &dfa) const; + + /** + * Returns the set of all states that can be reached from the set of @p input states + * by the epsilon transition. + */ + QSet epsilonClosure(const QSet &input) const; + + /** + * Returns the set of all states that can be reached from the set of given @p states + * by the given @p input. + */ + QSet move(const QSet &states, TransitionType input) const; + + NamePool::Ptr m_namePool; + QHash m_states; + QHash > > m_transitions; + QHash > m_epsilonTransitions; + StateId m_currentState; + qint32 m_counter; + TransitionType m_lastTransition; + }; + + #include "qxsdstatemachine.cpp" +} + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif diff --git a/src/xmlpatterns/schema/qxsdstatemachinebuilder.cpp b/src/xmlpatterns/schema/qxsdstatemachinebuilder.cpp new file mode 100644 index 0000000..866e010 --- /dev/null +++ b/src/xmlpatterns/schema/qxsdstatemachinebuilder.cpp @@ -0,0 +1,230 @@ +/**************************************************************************** +** +** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the $MODULE$ of the Qt Toolkit. +** +** $TROLLTECH_DUAL_LICENSE$ +** +****************************************************************************/ + +#include "qxsdstatemachinebuilder_p.h" + +#include "qxsdelement_p.h" +#include "qxsdmodelgroup_p.h" +#include "qxsdschemahelper_p.h" + +QT_BEGIN_NAMESPACE + +using namespace QPatternist; + +/* + * This methods takes a list of objects and returns a list of list + * of all combinations the objects can be ordered. + * + * e.g. input = [ 1, 2, 3 ] + * output = [ + * [ 1, 2, 3 ], + * [ 1, 3, 2 ], + * [ 2, 1, 3 ], + * [ 2, 3, 1 ], + * [ 3, 1, 2 ], + * [ 3, 2, 1 ] + * ] + * + * The method is used to create all possible combinations for the particles + * in an model group. + */ +template +QList< QList > allCombinations(const QList &input) +{ + if (input.count() == 1) + return (QList< QList >() << input); + + QList< QList > result; + for (int i = 0; i < input.count(); ++i) { + QList subList = input; + T value = subList.takeAt(i); + + QList< QList > subLists = allCombinations(subList); + for (int j = 0; j < subLists.count(); ++j) { + subLists[j].prepend(value); + } + result << subLists; + } + + return result; +} + +XsdStateMachineBuilder::XsdStateMachineBuilder(XsdStateMachine *machine, const NamePool::Ptr &namePool, Mode mode) + : m_stateMachine(machine), m_namePool(namePool), m_mode(mode) +{ +} + +XsdStateMachine::StateId XsdStateMachineBuilder::reset() +{ + Q_ASSERT(m_stateMachine); + + m_stateMachine->clear(); + + return m_stateMachine->addState(XsdStateMachine::EndState); +} + +XsdStateMachine::StateId XsdStateMachineBuilder::addStartState(XsdStateMachine::StateId state) +{ + const XsdStateMachine::StateId startState = m_stateMachine->addState(XsdStateMachine::StartState); + m_stateMachine->addEpsilonTransition(startState, state); + + return startState; +} + +/* + * Create the FSA according to Algorithm Tp(S) from http://www.ltg.ed.ac.uk/~ht/XML_Europe_2003.html + */ +XsdStateMachine::StateId XsdStateMachineBuilder::buildParticle(const XsdParticle::Ptr &particle, XsdStateMachine::StateId endState) +{ + XsdStateMachine::StateId currentStartState = endState; + XsdStateMachine::StateId currentEndState = endState; + + // 2 + if (particle->maximumOccursUnbounded()) { + const XsdStateMachine::StateId t = m_stateMachine->addState(XsdStateMachine::InternalState); + const XsdStateMachine::StateId n = buildTerm(particle->term(), t); + + m_stateMachine->addEpsilonTransition(t, n); + m_stateMachine->addEpsilonTransition(n, endState); + + currentEndState = t; + currentStartState = t; + } else { // 3 + int count = (particle->maximumOccurs() - particle->minimumOccurs()); + if (count > 100) + count = 100; + + for (int i = 0; i < count; ++i) { + currentStartState = buildTerm(particle->term(), currentEndState); + m_stateMachine->addEpsilonTransition(currentStartState, endState); + currentEndState = currentStartState; + } + } + + int minOccurs = particle->minimumOccurs(); + if (minOccurs > 100) + minOccurs = 100; + + for (int i = 0; i < minOccurs; ++i) { + currentStartState = buildTerm(particle->term(), currentEndState); + currentEndState = currentStartState; + } + + return currentStartState; +} + +/* + * Create the FSA according to Algorithm Tt(S) from http://www.ltg.ed.ac.uk/~ht/XML_Europe_2003.html + */ +XsdStateMachine::StateId XsdStateMachineBuilder::buildTerm(const XsdTerm::Ptr &term, XsdStateMachine::StateId endState) +{ + if (term->isWildcard()) { // 1 + const XsdStateMachine::StateId b = m_stateMachine->addState(XsdStateMachine::InternalState); + m_stateMachine->addTransition(b, term, endState); + return b; + } else if (term->isElement()) { // 2 + const XsdStateMachine::StateId b = m_stateMachine->addState(XsdStateMachine::InternalState); + m_stateMachine->addTransition(b, term, endState); + + const XsdElement::Ptr element(term); + if (m_mode == CheckingMode) { + const XsdElement::List substGroups = element->substitutionGroups(); + for (int i = 0; i < substGroups.count(); ++i) + m_stateMachine->addTransition(b, substGroups.at(i), endState); + } else if (m_mode == ValidatingMode) { + const XsdElement::List substGroups = element->substitutionGroups(); + for (int i = 0; i < substGroups.count(); ++i) { + if (XsdSchemaHelper::substitutionGroupOkTransitive(element, substGroups.at(i), m_namePool)) + m_stateMachine->addTransition(b, substGroups.at(i), endState); + } + } + + return b; + } else if (term->isModelGroup()) { + const XsdModelGroup::Ptr group(term); + + if (group->compositor() == XsdModelGroup::ChoiceCompositor) { // 3 + const XsdStateMachine::StateId b = m_stateMachine->addState(XsdStateMachine::InternalState); + + for (int i = 0; i < group->particles().count(); ++i) { + const XsdParticle::Ptr particle(group->particles().at(i)); + if (particle->maximumOccurs() != 0) { + const XsdStateMachine::StateId state = buildParticle(particle, endState); + m_stateMachine->addEpsilonTransition(b, state); + } + } + + return b; + } else if (group->compositor() == XsdModelGroup::SequenceCompositor) { // 4 + XsdStateMachine::StateId currentStartState = endState; + XsdStateMachine::StateId currentEndState = endState; + + for (int i = (group->particles().count() - 1); i >= 0; --i) { // iterate reverse + const XsdParticle::Ptr particle(group->particles().at(i)); + if (particle->maximumOccurs() != 0) { + currentStartState = buildParticle(particle, currentEndState); + currentEndState = currentStartState; + } + } + + return currentStartState; + } else if (group->compositor() == XsdModelGroup::AllCompositor) { + const XsdStateMachine::StateId newStartState = m_stateMachine->addState(XsdStateMachine::InternalState); + + const QList list = allCombinations(group->particles()); + + for (int i = 0; i < list.count(); ++i) { + XsdStateMachine::StateId currentStartState = endState; + XsdStateMachine::StateId currentEndState = endState; + + const XsdParticle::List particles = list.at(i); + for (int j = (particles.count() - 1); j >= 0; --j) { // iterate reverse + const XsdParticle::Ptr particle(particles.at(j)); + if (particle->maximumOccurs() != 0) { + currentStartState = buildParticle(particle, currentEndState); + currentEndState = currentStartState; + } + } + m_stateMachine->addEpsilonTransition(newStartState, currentStartState); + } + + if (list.isEmpty()) + return endState; + else + return newStartState; + } + } + + Q_ASSERT(false); + return 0; +} + +static void internalParticleLookupMap(const XsdParticle::Ptr &particle, QHash &hash) +{ + hash.insert(particle->term(), particle); + + if (particle->term()->isModelGroup()) { + const XsdModelGroup::Ptr group(particle->term()); + const XsdParticle::List particles = group->particles(); + for (int i = 0; i < particles.count(); ++i) + internalParticleLookupMap(particles.at(i), hash); + } +} + +QHash XsdStateMachineBuilder::particleLookupMap(const XsdParticle::Ptr &particle) +{ + QHash result; + internalParticleLookupMap(particle, result); + + return result; +} + +QT_END_NAMESPACE diff --git a/src/xmlpatterns/schema/qxsdstatemachinebuilder_p.h b/src/xmlpatterns/schema/qxsdstatemachinebuilder_p.h new file mode 100644 index 0000000..011153a --- /dev/null +++ b/src/xmlpatterns/schema/qxsdstatemachinebuilder_p.h @@ -0,0 +1,111 @@ +/**************************************************************************** +** +** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the $MODULE$ of the Qt Toolkit. +** +** $TROLLTECH_DUAL_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_XsdStateMachineBuilder_H +#define Patternist_XsdStateMachineBuilder_H + +#include "qxsdparticle_p.h" +#include "qxsdstatemachine_p.h" +#include "qxsdterm_p.h" + +#include +#include + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +namespace QPatternist +{ + /** + * @short A helper class to build up validation state machines. + * + * @ingroup Patternist_schema + * @author Tobias Koenig + */ + class XsdStateMachineBuilder : public QSharedData + { + public: + typedef QExplicitlySharedDataPointer Ptr; + + enum Mode + { + CheckingMode, + ValidatingMode + }; + + /** + * Creates a new state machine builder. + * + * @param machine The state machine it should work on. + * @param namePool The name pool used by all schema components. + * @param mode The mode the machine shall be build for. + */ + XsdStateMachineBuilder(XsdStateMachine *machine, const NamePool::Ptr &namePool, Mode mode = CheckingMode); + + /** + * Resets the state machine. + * + * @returns The initial end state. + */ + XsdStateMachine::StateId reset(); + + /** + * Prepends a start state to the given @p state. + * That is needed to allow the conversion of the state machine from a FSA to a DFA. + */ + XsdStateMachine::StateId addStartState(XsdStateMachine::StateId state); + + /** + * Creates the state machine for the given @p particle that should have the + * given @p endState. + * + * @returns The new start state. + */ + XsdStateMachine::StateId buildParticle(const XsdParticle::Ptr &particle, XsdStateMachine::StateId endState); + + /** + * Creates the state machine for the given @p term that should have the + * given @p endState. + * + * @returns The new start state. + */ + XsdStateMachine::StateId buildTerm(const XsdTerm::Ptr &term, XsdStateMachine::StateId endState); + + /** + * Returns a hash that maps each term that appears inside @p particle, to the particle it belongs. + * + * @note These information are used by XsdParticleChecker to check particle inheritance. + */ + static QHash particleLookupMap(const XsdParticle::Ptr &particle); + + private: + XsdStateMachine *m_stateMachine; + NamePool::Ptr m_namePool; + Mode m_mode; + }; +} + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif diff --git a/src/xmlpatterns/schema/qxsdterm.cpp b/src/xmlpatterns/schema/qxsdterm.cpp new file mode 100644 index 0000000..1dbe34b --- /dev/null +++ b/src/xmlpatterns/schema/qxsdterm.cpp @@ -0,0 +1,38 @@ +/**************************************************************************** +** +** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the $MODULE$ of the Qt Toolkit. +** +** $TROLLTECH_DUAL_LICENSE$ +** +****************************************************************************/ + +#include "qxsdterm_p.h" + +QT_BEGIN_NAMESPACE + +using namespace QPatternist; + +bool XsdTerm::isElement() const +{ + return false; +} + +bool XsdTerm::isModelGroup() const +{ + return false; +} + +bool XsdTerm::isWildcard() const +{ + return false; +} + +bool XsdTerm::isReference() const +{ + return false; +} + +QT_END_NAMESPACE diff --git a/src/xmlpatterns/schema/qxsdterm_p.h b/src/xmlpatterns/schema/qxsdterm_p.h new file mode 100644 index 0000000..f45d791 --- /dev/null +++ b/src/xmlpatterns/schema/qxsdterm_p.h @@ -0,0 +1,84 @@ +/**************************************************************************** +** +** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the $MODULE$ of the Qt Toolkit. +** +** $TROLLTECH_DUAL_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_XsdTerm_H +#define Patternist_XsdTerm_H + +#include "qnamedschemacomponent_p.h" +#include "qxsdannotated_p.h" + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +namespace QPatternist +{ + /** + * @short A base class for all particles of a model group. + * + * This class is the base class for all particles of a model group + * as the element, group or any tag, it is not supposed to + * be instantiated directly. + * + * @see XML Schema API reference + * @ingroup Patternist_schema + * @author Tobias Koenig + */ + class XsdTerm : public NamedSchemaComponent, public XsdAnnotated + { + public: + typedef QExplicitlySharedDataPointer Ptr; + + /** + * Returns @c true if the term is an element, @c false otherwise. + */ + virtual bool isElement() const; + + /** + * Returns @c true if the term is a model group (group tag), @c false otherwise. + */ + virtual bool isModelGroup() const; + + /** + * Returns @c true if the term is a wildcard (any tag), @c false otherwise. + */ + virtual bool isWildcard() const; + + /** + * Returns @c true if the term is a reference, @c false otherwise. + * + * @note The reference term is only used internally as helper during type resolving. + */ + virtual bool isReference() const; + + protected: + /** + * This constructor only exists to ensure this class is subclassed. + */ + inline XsdTerm() {}; + }; +} + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif diff --git a/src/xmlpatterns/schema/qxsdtypechecker.cpp b/src/xmlpatterns/schema/qxsdtypechecker.cpp new file mode 100644 index 0000000..ab971a9 --- /dev/null +++ b/src/xmlpatterns/schema/qxsdtypechecker.cpp @@ -0,0 +1,1308 @@ +/**************************************************************************** +** +** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the $MODULE$ of the Qt Toolkit. +** +** $TROLLTECH_DUAL_LICENSE$ +** +****************************************************************************/ + +#include "qxsdtypechecker_p.h" + +#include "qabstractdatetime_p.h" +#include "qbase64binary_p.h" +#include "qboolean_p.h" +#include "qdecimal_p.h" +#include "qderivedinteger_p.h" +#include "qduration_p.h" +#include "qgenericstaticcontext_p.h" +#include "qhexbinary_p.h" +#include "qnamespaceresolver_p.h" +#include "qpatternplatform_p.h" +#include "qqnamevalue_p.h" +#include "qvaluefactory_p.h" +#include "qxmlnamepool.h" +#include "qxsdschemahelper_p.h" +#include "qxsdschemamerger_p.h" +#include "qxsdstatemachine_p.h" + +#include "qxsdschemadebugger_p.h" + +QT_BEGIN_NAMESPACE + +using namespace QPatternist; + +XsdSchemaSourceLocationReflection::XsdSchemaSourceLocationReflection(const QSourceLocation &location) + : m_sourceLocation(location) +{ +} + +const SourceLocationReflection* XsdSchemaSourceLocationReflection::actualReflection() const +{ + return this; +} + +QSourceLocation XsdSchemaSourceLocationReflection::sourceLocation() const +{ + return m_sourceLocation; +} + + +static AnySimpleType::Ptr comparableType(const AnySimpleType::Ptr &type) +{ + if (!type->isDefinedBySchema()) { + return type; + } else { + const XsdSimpleType::Ptr simpleType(type); + if (type->category() == SchemaType::SimpleTypeAtomic) { + return simpleType->primitiveType(); + } else if (type->category() == SchemaType::SimpleTypeList) { + return simpleType->itemType(); + } else if (type->category() == SchemaType::SimpleTypeUnion) { + return simpleType->memberTypes().first(); + } + } + + Q_ASSERT(false); + return AnySimpleType::Ptr(); +} + +static int totalDigitsForSignedLongLong(long long value) +{ + QString number = QString::number(value); + if (number.startsWith(QLatin1Char('-'))) + number = number.mid(1); + + return number.length(); +} + +static int totalDigitsForUnsignedLongLong(unsigned long long value) +{ + const QString number = QString::number(value); + return number.length(); +} + +static int totalDigitsForDecimal(const QString &lexicalValue) +{ + const QLatin1Char zeroChar('0'); + const int length = lexicalValue.length() - 1; + + // strip leading zeros + int pos = 0; + while (lexicalValue.at(pos) == zeroChar && (pos != length)) + pos++; + + QString value = lexicalValue.mid(pos); + + // if contains '.' strip trailing zeros + if (value.contains(QLatin1Char('.'))) { + pos = value.length() - 1; + while (value.at(pos) == zeroChar) { + pos--; + } + + value = value.left(pos + 1); + } + + // check number of digits of remaining string + int totalDigits = 0; + for (int i = 0; i < value.count(); ++i) + if (value.at(i).isDigit()) + ++totalDigits; + + if (totalDigits == 0) + totalDigits = 1; + + return totalDigits; +} + +static int fractionDigitsForDecimal(const QString &lexicalValue) +{ + // we use the lexical value here, as the conversion to double might strip + // away decimal positions + + QString trimmedValue(lexicalValue.trimmed()); + const int pos = trimmedValue.indexOf(QLatin1Char('.')); + if (pos == -1) // no '.' -> 0 fraction digits + return 0; + else + return (trimmedValue.length() - pos - 1); +} + +XsdTypeChecker::XsdTypeChecker(const XsdSchemaContext::Ptr &context, const QVector &namespaceBindings, const QSourceLocation &location) + : m_context(context) + , m_namePool(m_context->namePool()) + , m_namespaceBindings(namespaceBindings) + , m_reflection(new XsdSchemaSourceLocationReflection(location)) +{ +} + +XsdTypeChecker::~XsdTypeChecker() +{ +} + +QString XsdTypeChecker::normalizedValue(const QString &value, const XsdFacet::Hash &facets) +{ + if (!facets.contains(XsdFacet::WhiteSpace)) + return value; + + const XsdFacet::Ptr whiteSpaceFacet = facets.value(XsdFacet::WhiteSpace); + + const DerivedString::Ptr facetValue = whiteSpaceFacet->value(); + const QString stringValue = facetValue->stringValue(); + if (stringValue == XsdSchemaToken::toString(XsdSchemaToken::Preserve)) + return value; + else if (stringValue == XsdSchemaToken::toString(XsdSchemaToken::Replace)) { + QString newValue(value); + newValue.replace(QLatin1Char('\t'), QLatin1Char(' ')); + newValue.replace(QLatin1Char('\n'), QLatin1Char(' ')); + newValue.replace(QLatin1Char('\r'), QLatin1Char(' ')); + + return newValue; + } else if (stringValue == XsdSchemaToken::toString(XsdSchemaToken::Collapse)) { + return value.simplified(); + } + + return value; +} + +XsdFacet::Hash XsdTypeChecker::mergedFacetsForType(const SchemaType::Ptr &type, const XsdSchemaContext::Ptr &context) +{ + if (!type) + return XsdFacet::Hash(); + + const XsdFacet::Hash baseFacets = mergedFacetsForType(type->wxsSuperType(), context); + const XsdFacet::Hash facets = context->facetsForType(type); + + XsdFacet::Hash result = baseFacets; + XsdFacet::HashIterator it(facets); + while (it.hasNext()) { + it.next(); + + result.insert(it.key(), it.value()); + } + + return result; +} + +bool XsdTypeChecker::isValidString(const QString &normalizedString, const AnySimpleType::Ptr &type, QString &errorMsg, AnySimpleType::Ptr *boundType) const +{ + if (type->name(m_namePool) == BuiltinTypes::xsAnySimpleType->name(m_namePool)) { + if (boundType) + *boundType = type; + + return true; + } + + if (!type->isDefinedBySchema()) { + // special QName check + if (BuiltinTypes::xsQName->wxsTypeMatches(type)) { + if (!XPathHelper::isQName(normalizedString)) { + errorMsg = QtXmlPatterns::tr("%1 is not valid according to %2").arg(formatData(normalizedString)).arg(formatType(m_namePool, type)); + return false; + } + } + + const AtomicValue::Ptr value = fromLexical(normalizedString, type, m_context, m_reflection); + if (value->hasError()) { + errorMsg = QtXmlPatterns::tr("%1 is not valid according to %2").arg(formatData(normalizedString)).arg(formatType(m_namePool, type)); + return false; + } + + if (!checkConstrainingFacets(value, normalizedString, type, errorMsg)) { + return false; + } + + if (boundType) + *boundType = type; + + } else { + const XsdSimpleType::Ptr simpleType(type); + + if (simpleType->category() == XsdSimpleType::SimpleTypeAtomic) { + AnySimpleType::Ptr targetType = simpleType->primitiveType(); + if (!simpleType->wxsSuperType()->isDefinedBySchema()) + targetType = simpleType->wxsSuperType(); + + const AtomicValue::Ptr value = fromLexical(normalizedString, targetType, m_context, m_reflection); + if (value->hasError()) { + errorMsg = QtXmlPatterns::tr("%1 is not valid according to %2").arg(formatData(normalizedString)).arg(formatType(m_namePool, targetType)); + return false; + } + + if (!checkConstrainingFacets(value, normalizedString, type, errorMsg)) { + return false; + } + + if (boundType) + *boundType = type; + + } else if (simpleType->category() == XsdSimpleType::SimpleTypeList) { + QStringList entries = normalizedString.split(QLatin1Char(' '), QString::SkipEmptyParts); + for (int i = 0; i < entries.count(); ++i) { + entries[i] = normalizedValue(entries.at(i), mergedFacetsForType(simpleType->itemType(), m_context)); + } + + if (!checkConstrainingFacetsList(entries, normalizedString, simpleType->itemType(), mergedFacetsForType(simpleType, m_context), errorMsg)) { + return false; + } + + for (int i = 0; i < entries.count(); ++i) { + if (!isValidString(entries.at(i), simpleType->itemType(), errorMsg)) { + return false; + } + } + + if (boundType) + *boundType = simpleType->itemType(); + + } else if (simpleType->category() == XsdSimpleType::SimpleTypeUnion) { + if (!checkConstrainingFacetsUnion(normalizedString, normalizedString, simpleType, mergedFacetsForType(simpleType, m_context), errorMsg)) { + return false; + } + + const AnySimpleType::List memberTypes = simpleType->memberTypes(); + + bool foundValidType = false; + for (int i = 0; i < memberTypes.count(); ++i) { + const XsdFacet::Hash mergedFacets = mergedFacetsForType(memberTypes.at(i), m_context); + if (isValidString(normalizedValue(normalizedString, mergedFacets), memberTypes.at(i), errorMsg)) { + foundValidType = true; + + if (boundType) + *boundType = memberTypes.at(i); + + break; + } + } + + if (!foundValidType) { + return false; + } + } + } + + return true; +} + +bool XsdTypeChecker::valuesAreEqual(const QString &value, const QString &otherValue, const AnySimpleType::Ptr &type) const +{ + const AnySimpleType::Ptr targetType = comparableType(type); + + // if the type is xs:anySimpleType we just do string comparison... + if (targetType->name(m_namePool) == BuiltinTypes::xsAnySimpleType->name(m_namePool)) + return (value == otherValue); + + if (BuiltinTypes::xsQName->wxsTypeMatches(type)) { + const QXmlName valueName = convertToQName(value); + const QXmlName otherValueName = convertToQName(otherValue); + + if (valueName == otherValueName) + return true; + } + + if (type->category() == SchemaType::SimpleTypeAtomic) { + // ... otherwise we use the casting platform for value comparison + const DerivedString::Ptr valueStr = DerivedString::fromLexical(m_namePool, value); + const DerivedString::Ptr otherValueStr = DerivedString::fromLexical(m_namePool, otherValue); + + return XsdSchemaHelper::constructAndCompare(valueStr, AtomicComparator::OperatorEqual, otherValueStr, targetType, m_context, m_reflection); + } else if (type->category() == SchemaType::SimpleTypeList) { + const QStringList values = value.split(QLatin1Char(' '), QString::SkipEmptyParts); + const QStringList otherValues = otherValue.split(QLatin1Char(' '), QString::SkipEmptyParts); + if (values.count() != otherValues.count()) + return false; + + for (int i = 0; i < values.count(); ++i) { + if (!valuesAreEqual(values.at(i), otherValues.at(i), XsdSimpleType::Ptr(type)->itemType())) + return false; + } + + return true; + } else if (type->category() == SchemaType::SimpleTypeUnion) { + const AnySimpleType::List memberTypes = XsdSimpleType::Ptr(type)->memberTypes(); + for (int i = 0; i < memberTypes.count(); ++i) { + if (valuesAreEqual(value, otherValue, memberTypes.at(i))) { + return true; + } + } + + return false; + } + + return false; +} + +bool XsdTypeChecker::checkConstrainingFacets(const AtomicValue::Ptr &value, const QString &lexicalValue, const AnySimpleType::Ptr &type, QString &errorMsg) const +{ + const XsdFacet::Hash facets = mergedFacetsForType(type, m_context); + + if (BuiltinTypes::xsString->wxsTypeMatches(type) || + BuiltinTypes::xsUntypedAtomic->wxsTypeMatches(type)) { + return checkConstrainingFacetsString(value->stringValue(), facets, BuiltinTypes::xsString, errorMsg); + } else if (BuiltinTypes::xsAnyURI->wxsTypeMatches(type)) { + return checkConstrainingFacetsString(value->stringValue(), facets, BuiltinTypes::xsAnyURI, errorMsg); + } else if (BuiltinTypes::xsNOTATION->wxsTypeMatches(type)) { + return checkConstrainingFacetsNotation(value->as()->qName(), facets, errorMsg); + } else if (BuiltinTypes::xsUnsignedByte->wxsTypeMatches(type) || + BuiltinTypes::xsUnsignedInt->wxsTypeMatches(type) || + BuiltinTypes::xsUnsignedLong->wxsTypeMatches(type) || + BuiltinTypes::xsUnsignedShort->wxsTypeMatches(type)) { + return checkConstrainingFacetsUnsignedInteger(value->as()->toUnsignedInteger(), lexicalValue, facets, errorMsg); + } else if (BuiltinTypes::xsInteger->wxsTypeMatches(type)) { + return checkConstrainingFacetsSignedInteger(value->as()->toInteger(), lexicalValue, facets, errorMsg); + } else if (BuiltinTypes::xsFloat->wxsTypeMatches(type) || + BuiltinTypes::xsDouble->wxsTypeMatches(type)) { + return checkConstrainingFacetsDouble(value->as()->toDouble(), lexicalValue, facets, errorMsg); + } else if (BuiltinTypes::xsDecimal->wxsTypeMatches(type)) { + return checkConstrainingFacetsDecimal(value, lexicalValue, facets, errorMsg); + } else if (BuiltinTypes::xsDateTime->wxsTypeMatches(type)) { + return checkConstrainingFacetsDateTime(value->as()->toDateTime(), lexicalValue, facets, BuiltinTypes::xsDateTime, errorMsg); + } else if (BuiltinTypes::xsDate->wxsTypeMatches(type)) { + return checkConstrainingFacetsDateTime(value->as()->toDateTime(), lexicalValue, facets, BuiltinTypes::xsDate, errorMsg); + } else if (BuiltinTypes::xsGYear->wxsTypeMatches(type)) { + return checkConstrainingFacetsDateTime(value->as()->toDateTime(), lexicalValue, facets, BuiltinTypes::xsGYear, errorMsg); + } else if (BuiltinTypes::xsGYearMonth->wxsTypeMatches(type)) { + return checkConstrainingFacetsDateTime(value->as()->toDateTime(), lexicalValue, facets, BuiltinTypes::xsGYearMonth, errorMsg); + } else if (BuiltinTypes::xsGMonth->wxsTypeMatches(type)) { + return checkConstrainingFacetsDateTime(value->as()->toDateTime(), lexicalValue, facets, BuiltinTypes::xsGMonth, errorMsg); + } else if (BuiltinTypes::xsGMonthDay->wxsTypeMatches(type)) { + return checkConstrainingFacetsDateTime(value->as()->toDateTime(), lexicalValue, facets, BuiltinTypes::xsGMonthDay, errorMsg); + } else if (BuiltinTypes::xsGDay->wxsTypeMatches(type)) { + return checkConstrainingFacetsDateTime(value->as()->toDateTime(), lexicalValue, facets, BuiltinTypes::xsGDay, errorMsg); + } else if (BuiltinTypes::xsTime->wxsTypeMatches(type)) { + return checkConstrainingFacetsDateTime(value->as()->toDateTime(), lexicalValue, facets, BuiltinTypes::xsTime, errorMsg); + } else if (BuiltinTypes::xsDuration->wxsTypeMatches(type)) { + return checkConstrainingFacetsDuration(value, lexicalValue, facets, errorMsg); + } else if (BuiltinTypes::xsBoolean->wxsTypeMatches(type)) { + return checkConstrainingFacetsBoolean(value->as()->value(), lexicalValue, facets, errorMsg); + } else if (BuiltinTypes::xsHexBinary->wxsTypeMatches(type)) { + return checkConstrainingFacetsBinary(value->as()->asByteArray(), facets, BuiltinTypes::xsHexBinary, errorMsg); + } else if (BuiltinTypes::xsBase64Binary->wxsTypeMatches(type)) { + return checkConstrainingFacetsBinary(value->as()->asByteArray(), facets, BuiltinTypes::xsBase64Binary, errorMsg); + } else if (BuiltinTypes::xsQName->wxsTypeMatches(type)) { + return checkConstrainingFacetsQName(value->as()->qName(), lexicalValue, facets, errorMsg); + } + + return true; +} + +bool XsdTypeChecker::checkConstrainingFacetsString(const QString &value, const XsdFacet::Hash &facets, const AnySimpleType::Ptr &type, QString &errorMsg) const +{ + if (facets.contains(XsdFacet::Length)) { + const XsdFacet::Ptr facet = facets.value(XsdFacet::Length); + const DerivedInteger::Ptr length = facet->value(); + if (length->toInteger() != value.length()) { + errorMsg = QtXmlPatterns::tr("string content does not match the length facet"); + return false; + } + } + if (facets.contains(XsdFacet::MinimumLength)) { + const XsdFacet::Ptr facet = facets.value(XsdFacet::MinimumLength); + const DerivedInteger::Ptr length = facet->value(); + if (length->toInteger() > value.length()) { + errorMsg = QtXmlPatterns::tr("string content does not match the minLength facet"); + return false; + } + } + if (facets.contains(XsdFacet::MaximumLength)) { + const XsdFacet::Ptr facet = facets.value(XsdFacet::MaximumLength); + const DerivedInteger::Ptr length = facet->value(); + if (length->toInteger() < value.length()) { + errorMsg = QtXmlPatterns::tr("string content does not match the maxLength facet"); + return false; + } + } + if (facets.contains(XsdFacet::Pattern)) { + const XsdFacet::Ptr facet = facets.value(XsdFacet::Pattern); + const AtomicValue::List multiValue = facet->multiValue(); + bool found = false; + for (int j = 0; j < multiValue.count(); ++j) { + const QString pattern = multiValue.at(j)->as >()->stringValue(); + const QRegExp exp = PatternPlatform::parsePattern(pattern, m_context, m_reflection); + if (exp.exactMatch(value)) { + found = true; + break; + } + } + + if (!found) { + errorMsg = QtXmlPatterns::tr("string content does not match pattern facet"); + return false; + } + } + if (facets.contains(XsdFacet::Enumeration)) { + const XsdFacet::Ptr facet = facets.value(XsdFacet::Enumeration); + const DerivedString::Ptr valueStr = DerivedString::fromLexical(m_namePool, value); + + const AtomicValue::List multiValue = facet->multiValue(); + bool found = false; + for (int j = 0; j < multiValue.count(); ++j) { + if (XsdSchemaHelper::constructAndCompare(valueStr, AtomicComparator::OperatorEqual, multiValue.at(j), type, m_context, m_reflection)) { + found = true; + break; + } + } + + if (!found) { + errorMsg = QtXmlPatterns::tr("string content is not listed in the enumeration facet"); + return false; + } + } + if (facets.contains(XsdFacet::Assertion)) { + //TODO: implement + } + + return true; +} + +bool XsdTypeChecker::checkConstrainingFacetsSignedInteger(long long value, const QString &lexicalValue, const XsdFacet::Hash &facets, QString &errorMsg) const +{ + if (facets.contains(XsdFacet::MaximumInclusive)) { + const XsdFacet::Ptr facet = facets.value(XsdFacet::MaximumInclusive); + const Numeric::Ptr facetValue = ValueFactory::fromLexical(facet->value()->as >()->stringValue(), BuiltinTypes::xsLong, m_context, m_reflection); + if (facetValue->toInteger() < value) { + errorMsg = QtXmlPatterns::tr("signed integer content does not match the maxInclusive facet"); + return false; + } + } + if (facets.contains(XsdFacet::MaximumExclusive)) { + const XsdFacet::Ptr facet = facets.value(XsdFacet::MaximumExclusive); + const Numeric::Ptr facetValue = ValueFactory::fromLexical(facet->value()->as >()->stringValue(), BuiltinTypes::xsLong, m_context, m_reflection); + if (facetValue->toInteger() <= value) { + errorMsg = QtXmlPatterns::tr("signed integer content does not match the maxExclusive facet"); + return false; + } + } + if (facets.contains(XsdFacet::MinimumInclusive)) { + const XsdFacet::Ptr facet = facets.value(XsdFacet::MinimumInclusive); + const Numeric::Ptr facetValue = ValueFactory::fromLexical(facet->value()->as >()->stringValue(), BuiltinTypes::xsLong, m_context, m_reflection); + if (facetValue->toInteger() > value) { + errorMsg = QtXmlPatterns::tr("signed integer content does not match the minInclusive facet"); + return false; + } + } + if (facets.contains(XsdFacet::MinimumExclusive)) { + const XsdFacet::Ptr facet = facets.value(XsdFacet::MinimumExclusive); + const Numeric::Ptr facetValue = ValueFactory::fromLexical(facet->value()->as >()->stringValue(), BuiltinTypes::xsLong, m_context, m_reflection); + if (facetValue->toInteger() >= value) { + errorMsg = QtXmlPatterns::tr("signed integer content does not match the minExclusive facet"); + return false; + } + } + if (facets.contains(XsdFacet::Enumeration)) { + const XsdFacet::Ptr facet = facets.value(XsdFacet::Enumeration); + const DerivedString::Ptr valueStr = DerivedString::fromLexical(m_namePool, QString::number(value)); + + const AtomicValue::List multiValue = facet->multiValue(); + bool found = false; + for (int j = 0; j < multiValue.count(); ++j) { + if (XsdSchemaHelper::constructAndCompare(valueStr, AtomicComparator::OperatorEqual, multiValue.at(j), BuiltinTypes::xsLong, m_context, m_reflection)) { + found = true; + break; + } + } + + if (!found) { + errorMsg = QtXmlPatterns::tr("signed integer content is not listed in the enumeration facet"); + return false; + } + } + if (facets.contains(XsdFacet::Pattern)) { + const XsdFacet::Ptr facet = facets.value(XsdFacet::Pattern); + const AtomicValue::List multiValue = facet->multiValue(); + bool found = false; + for (int j = 0; j < multiValue.count(); ++j) { + const QString pattern = multiValue.at(j)->as >()->stringValue(); + const QRegExp exp = PatternPlatform::parsePattern(pattern, m_context, m_reflection); + if (exp.exactMatch(lexicalValue)) { + found = true; + break; + } + } + + if (!found) { + errorMsg = QtXmlPatterns::tr("signed integer content does not match pattern facet"); + return false; + } + } + if (facets.contains(XsdFacet::TotalDigits)) { + const XsdFacet::Ptr facet = facets.value(XsdFacet::TotalDigits); + const DerivedInteger::Ptr facetValue = facet->value(); + + if (totalDigitsForSignedLongLong(value) > facetValue->toInteger()) { + errorMsg = QtXmlPatterns::tr("signed integer content does not match in the totalDigits facet"); + return false; + } + } + if (facets.contains(XsdFacet::Assertion)) { + //TODO: implement + } + + return true; +} + +bool XsdTypeChecker::checkConstrainingFacetsUnsignedInteger(unsigned long long value, const QString &lexicalValue, const XsdFacet::Hash &facets, QString &errorMsg) const +{ + if (facets.contains(XsdFacet::MaximumInclusive)) { + const XsdFacet::Ptr facet = facets.value(XsdFacet::MaximumInclusive); + const Numeric::Ptr facetValue = ValueFactory::fromLexical(facet->value()->as >()->stringValue(), BuiltinTypes::xsUnsignedLong, m_context, m_reflection); + if (facetValue->toUnsignedInteger() < value) { + errorMsg = QtXmlPatterns::tr("unsigned integer content does not match the maxInclusive facet"); + return false; + } + } + if (facets.contains(XsdFacet::MaximumExclusive)) { + const XsdFacet::Ptr facet = facets.value(XsdFacet::MaximumExclusive); + const Numeric::Ptr facetValue = ValueFactory::fromLexical(facet->value()->as >()->stringValue(), BuiltinTypes::xsUnsignedLong, m_context, m_reflection); + if (facetValue->toUnsignedInteger() <= value) { + errorMsg = QtXmlPatterns::tr("unsigned integer content does not match the maxExclusive facet"); + return false; + } + } + if (facets.contains(XsdFacet::MinimumInclusive)) { + const XsdFacet::Ptr facet = facets.value(XsdFacet::MinimumInclusive); + const Numeric::Ptr facetValue = ValueFactory::fromLexical(facet->value()->as >()->stringValue(), BuiltinTypes::xsUnsignedLong, m_context, m_reflection); + if (facetValue->toUnsignedInteger() > value) { + errorMsg = QtXmlPatterns::tr("unsigned integer content does not match the minInclusive facet"); + return false; + } + } + if (facets.contains(XsdFacet::MinimumExclusive)) { + const XsdFacet::Ptr facet = facets.value(XsdFacet::MinimumExclusive); + const Numeric::Ptr facetValue = ValueFactory::fromLexical(facet->value()->as >()->stringValue(), BuiltinTypes::xsUnsignedLong, m_context, m_reflection); + if (facetValue->toUnsignedInteger() >= value) { + errorMsg = QtXmlPatterns::tr("unsigned integer content does not match the minExclusive facet"); + return false; + } + } + if (facets.contains(XsdFacet::Enumeration)) { + const XsdFacet::Ptr facet = facets.value(XsdFacet::Enumeration); + const DerivedString::Ptr valueStr = DerivedString::fromLexical(m_namePool, QString::number(value)); + + const AtomicValue::List multiValue = facet->multiValue(); + bool found = false; + for (int j = 0; j < multiValue.count(); ++j) { + if (XsdSchemaHelper::constructAndCompare(valueStr, AtomicComparator::OperatorEqual, multiValue.at(j), BuiltinTypes::xsUnsignedLong, m_context, m_reflection)) { + found = true; + break; + } + } + + if (!found) { + errorMsg = QtXmlPatterns::tr("unsigned integer content is not listed in the enumeration facet"); + return false; + } + } + if (facets.contains(XsdFacet::Pattern)) { + const XsdFacet::Ptr facet = facets.value(XsdFacet::Pattern); + const AtomicValue::List multiValue = facet->multiValue(); + bool found = false; + for (int j = 0; j < multiValue.count(); ++j) { + const QString pattern = multiValue.at(j)->as >()->stringValue(); + const QRegExp exp = PatternPlatform::parsePattern(pattern, m_context, m_reflection); + if (exp.exactMatch(lexicalValue)) { + found = true; + break; + } + } + + if (!found) { + errorMsg = QtXmlPatterns::tr("unsigned integer content does not match pattern facet"); + return false; + } + } + if (facets.contains(XsdFacet::TotalDigits)) { + const XsdFacet::Ptr facet = facets.value(XsdFacet::TotalDigits); + const DerivedInteger::Ptr facetValue = facet->value(); + + if (totalDigitsForUnsignedLongLong(value) > facetValue->toInteger()) { + errorMsg = QtXmlPatterns::tr("unsigned integer content does not match in the totalDigits facet"); + return false; + } + } + if (facets.contains(XsdFacet::Assertion)) { + //TODO: implement + } + + return true; +} + +bool XsdTypeChecker::checkConstrainingFacetsDouble(double value, const QString &lexicalValue, const XsdFacet::Hash &facets, QString &errorMsg) const +{ + if (facets.contains(XsdFacet::MaximumInclusive)) { + const XsdFacet::Ptr facet = facets.value(XsdFacet::MaximumInclusive); + const Numeric::Ptr facetValue = ValueFactory::fromLexical(facet->value()->as >()->stringValue(), BuiltinTypes::xsDouble, m_context, m_reflection); + if (facetValue->toDouble() < value) { + errorMsg = QtXmlPatterns::tr("double content does not match the maxInclusive facet"); + return false; + } + } + if (facets.contains(XsdFacet::MaximumExclusive)) { + const XsdFacet::Ptr facet = facets.value(XsdFacet::MaximumExclusive); + const Numeric::Ptr facetValue = ValueFactory::fromLexical(facet->value()->as >()->stringValue(), BuiltinTypes::xsDouble, m_context, m_reflection); + if (facetValue->toDouble() <= value) { + errorMsg = QtXmlPatterns::tr("double content does not match the maxExclusive facet"); + return false; + } + } + if (facets.contains(XsdFacet::MinimumInclusive)) { + const XsdFacet::Ptr facet = facets.value(XsdFacet::MinimumInclusive); + const Numeric::Ptr facetValue = ValueFactory::fromLexical(facet->value()->as >()->stringValue(), BuiltinTypes::xsDouble, m_context, m_reflection); + if (facetValue->toDouble() > value) { + errorMsg = QtXmlPatterns::tr("double content does not match the minInclusive facet"); + return false; + } + } + if (facets.contains(XsdFacet::MinimumExclusive)) { + const XsdFacet::Ptr facet = facets.value(XsdFacet::MinimumExclusive); + const Numeric::Ptr facetValue = ValueFactory::fromLexical(facet->value()->as >()->stringValue(), BuiltinTypes::xsDouble, m_context, m_reflection); + if (facetValue->toDouble() >= value) { + errorMsg = QtXmlPatterns::tr("double content does not match the minExclusive facet"); + return false; + } + } + if (facets.contains(XsdFacet::Enumeration)) { + const XsdFacet::Ptr facet = facets.value(XsdFacet::Enumeration); + const DerivedString::Ptr valueStr = DerivedString::fromLexical(m_namePool, QString::number(value)); + + const AtomicValue::List multiValue = facet->multiValue(); + bool found = false; + for (int j = 0; j < multiValue.count(); ++j) { + if (XsdSchemaHelper::constructAndCompare(valueStr, AtomicComparator::OperatorEqual, multiValue.at(j), BuiltinTypes::xsDouble, m_context, m_reflection)) { + found = true; + break; + } + } + + if (!found) { + errorMsg = QtXmlPatterns::tr("double content is not listed in the enumeration facet"); + return false; + } + } + if (facets.contains(XsdFacet::Pattern)) { + const XsdFacet::Ptr facet = facets.value(XsdFacet::Pattern); + const AtomicValue::List multiValue = facet->multiValue(); + bool found = false; + for (int j = 0; j < multiValue.count(); ++j) { + const QString pattern = multiValue.at(j)->as >()->stringValue(); + const QRegExp exp = PatternPlatform::parsePattern(pattern, m_context, m_reflection); + if (exp.exactMatch(lexicalValue)) { + found = true; + break; + } + } + + if (!found) { + errorMsg = QtXmlPatterns::tr("double content does not match pattern facet"); + return false; + } + } + if (facets.contains(XsdFacet::Assertion)) { + //TODO: implement + } + + return true; +} + +bool XsdTypeChecker::checkConstrainingFacetsDecimal(const AtomicValue::Ptr &value, const QString &lexicalValue, const XsdFacet::Hash &facets, QString &errorMsg) const +{ + if (facets.contains(XsdFacet::FractionDigits)) { + const XsdFacet::Ptr facet = facets.value(XsdFacet::FractionDigits); + const DerivedInteger::Ptr facetValue = facet->value(); + + if (fractionDigitsForDecimal(lexicalValue) > facetValue->toInteger()) { + errorMsg = QtXmlPatterns::tr("decimal content does not match in the fractionDigits facet"); + return false; + } + } + if (facets.contains(XsdFacet::TotalDigits)) { + const XsdFacet::Ptr facet = facets.value(XsdFacet::TotalDigits); + const DerivedInteger::Ptr facetValue = facet->value(); + + if (totalDigitsForDecimal(lexicalValue) > facetValue->toInteger()) { + errorMsg = QtXmlPatterns::tr("decimal content does not match in the totalDigits facet"); + return false; + } + } + + return checkConstrainingFacetsDouble(value->as()->toDouble(), lexicalValue, facets, errorMsg); +} + +bool XsdTypeChecker::checkConstrainingFacetsDateTime(const QDateTime &value, const QString &lexicalValue, const XsdFacet::Hash &facets, const AnySimpleType::Ptr &type, QString &errorMsg) const +{ + if (facets.contains(XsdFacet::MaximumInclusive)) { + const XsdFacet::Ptr facet = facets.value(XsdFacet::MaximumInclusive); + const AbstractDateTime::Ptr facetValue = ValueFactory::fromLexical(facet->value()->as >()->stringValue(), type, m_context, m_reflection); + if (facetValue->toDateTime() < value) { + errorMsg = QtXmlPatterns::tr("date time content does not match the maxInclusive facet"); + return false; + } + } + if (facets.contains(XsdFacet::MaximumExclusive)) { + const XsdFacet::Ptr facet = facets.value(XsdFacet::MaximumExclusive); + const AbstractDateTime::Ptr facetValue = ValueFactory::fromLexical(facet->value()->as >()->stringValue(), type, m_context, m_reflection); + if (facetValue->toDateTime() <= value) { + errorMsg = QtXmlPatterns::tr("date time content does not match the maxExclusive facet"); + return false; + } + } + if (facets.contains(XsdFacet::MinimumInclusive)) { + const XsdFacet::Ptr facet = facets.value(XsdFacet::MinimumInclusive); + const AbstractDateTime::Ptr facetValue = ValueFactory::fromLexical(facet->value()->as >()->stringValue(), type, m_context, m_reflection); + if (facetValue->toDateTime() > value) { + errorMsg = QtXmlPatterns::tr("date time content does not match the minInclusive facet"); + return false; + } + } + if (facets.contains(XsdFacet::MinimumExclusive)) { + const XsdFacet::Ptr facet = facets.value(XsdFacet::MinimumExclusive); + const AbstractDateTime::Ptr facetValue = ValueFactory::fromLexical(facet->value()->as >()->stringValue(), type, m_context, m_reflection); + if (facetValue->toDateTime() >= value) { + errorMsg = QtXmlPatterns::tr("date time content does not match the minExclusive facet"); + return false; + } + } + if (facets.contains(XsdFacet::Enumeration)) { + const XsdFacet::Ptr facet = facets.value(XsdFacet::Enumeration); + + const AtomicValue::List multiValue = facet->multiValue(); + bool found = false; + for (int j = 0; j < multiValue.count(); ++j) { + const AbstractDateTime::Ptr facetValue = ValueFactory::fromLexical(multiValue.at(j)->as >()->stringValue(), type, m_context, m_reflection); + if (facetValue->toDateTime() == value) { + found = true; + break; + } + } + + if (!found) { + errorMsg = QtXmlPatterns::tr("date time content is not listed in the enumeration facet"); + return false; + } + } + if (facets.contains(XsdFacet::Pattern)) { + const XsdFacet::Ptr facet = facets.value(XsdFacet::Pattern); + const AtomicValue::List multiValue = facet->multiValue(); + bool found = false; + for (int j = 0; j < multiValue.count(); ++j) { + const QString pattern = multiValue.at(j)->as >()->stringValue(); + const QRegExp exp = PatternPlatform::parsePattern(pattern, m_context, m_reflection); + if (exp.exactMatch(lexicalValue)) { + found = true; + break; + } + } + + if (!found) { + errorMsg = QtXmlPatterns::tr("date time content does not match pattern facet"); + return false; + } + } + + return true; +} + +bool XsdTypeChecker::checkConstrainingFacetsDuration(const AtomicValue::Ptr&, const QString &lexicalValue, const XsdFacet::Hash &facets, QString &errorMsg) const +{ + if (facets.contains(XsdFacet::MaximumInclusive)) { + const XsdFacet::Ptr facet = facets.value(XsdFacet::MaximumInclusive); + const DerivedString::Ptr value = DerivedString::fromLexical(m_namePool, lexicalValue); + + if (XsdSchemaHelper::constructAndCompare(facets.value(XsdFacet::MaximumInclusive)->value(), AtomicComparator::OperatorLessThan, value, BuiltinTypes::xsDuration, m_context, m_reflection)) { + errorMsg = QtXmlPatterns::tr("duration content does not match the maxInclusive facet"); + return false; + } + } + if (facets.contains(XsdFacet::MaximumExclusive)) { + const XsdFacet::Ptr facet = facets.value(XsdFacet::MaximumExclusive); + const DerivedString::Ptr value = DerivedString::fromLexical(m_namePool, lexicalValue); + + if (XsdSchemaHelper::constructAndCompare(facets.value(XsdFacet::MaximumExclusive)->value(), AtomicComparator::OperatorLessOrEqual, value, BuiltinTypes::xsDuration, m_context, m_reflection)) { + errorMsg = QtXmlPatterns::tr("duration content does not match the maxExclusive facet"); + return false; + } + } + if (facets.contains(XsdFacet::MinimumInclusive)) { + const XsdFacet::Ptr facet = facets.value(XsdFacet::MinimumInclusive); + const DerivedString::Ptr value = DerivedString::fromLexical(m_namePool, lexicalValue); + + if (XsdSchemaHelper::constructAndCompare(facets.value(XsdFacet::MinimumInclusive)->value(), AtomicComparator::OperatorGreaterThan, value, BuiltinTypes::xsDuration, m_context, m_reflection)) { + errorMsg = QtXmlPatterns::tr("duration content does not match the minInclusive facet"); + return false; + } + } + if (facets.contains(XsdFacet::MinimumExclusive)) { + const XsdFacet::Ptr facet = facets.value(XsdFacet::MinimumExclusive); + const DerivedString::Ptr value = DerivedString::fromLexical(m_namePool, lexicalValue); + + if (XsdSchemaHelper::constructAndCompare(facets.value(XsdFacet::MinimumExclusive)->value(), AtomicComparator::OperatorGreaterOrEqual, value, BuiltinTypes::xsDuration, m_context, m_reflection)) { + errorMsg = QtXmlPatterns::tr("duration content does not match the minExclusive facet"); + return false; + } + } + if (facets.contains(XsdFacet::Enumeration)) { + const XsdFacet::Ptr facet = facets.value(XsdFacet::Enumeration); + const DerivedString::Ptr value = DerivedString::fromLexical(m_namePool, lexicalValue); + + const AtomicValue::List multiValue = facet->multiValue(); + bool found = false; + for (int j = 0; j < multiValue.count(); ++j) { + if (XsdSchemaHelper::constructAndCompare(multiValue.at(j), AtomicComparator::OperatorEqual, value, BuiltinTypes::xsDuration, m_context, m_reflection)) { + found = true; + break; + } + } + + if (!found) { + errorMsg = QtXmlPatterns::tr("duration content is not listed in the enumeration facet"); + return false; + } + } + if (facets.contains(XsdFacet::Pattern)) { + const XsdFacet::Ptr facet = facets.value(XsdFacet::Pattern); + const AtomicValue::List multiValue = facet->multiValue(); + bool found = false; + for (int j = 0; j < multiValue.count(); ++j) { + const QString pattern = multiValue.at(j)->as >()->stringValue(); + const QRegExp exp = PatternPlatform::parsePattern(pattern, m_context, m_reflection); + if (exp.exactMatch(lexicalValue)) { + found = true; + break; + } + } + + if (!found) { + errorMsg = QtXmlPatterns::tr("duration content does not match pattern facet"); + return false; + } + } + if (facets.contains(XsdFacet::Assertion)) { + //TODO: implement + } + + return true; +} + +bool XsdTypeChecker::checkConstrainingFacetsBoolean(bool, const QString &lexicalValue, const XsdFacet::Hash &facets, QString &errorMsg) const +{ + if (facets.contains(XsdFacet::Pattern)) { + const XsdFacet::Ptr facet = facets.value(XsdFacet::Pattern); + const AtomicValue::List multiValue = facet->multiValue(); + bool found = false; + for (int j = 0; j < multiValue.count(); ++j) { + const QString pattern = multiValue.at(j)->as >()->stringValue(); + const QRegExp exp = PatternPlatform::parsePattern(pattern, m_context, m_reflection); + if (exp.exactMatch(lexicalValue)) { + found = true; + break; + } + } + + if (!found) { + errorMsg = QtXmlPatterns::tr("boolean content does not match pattern facet"); + return false; + } + } + if (facets.contains(XsdFacet::Assertion)) { + //TODO: implement + } + + return true; +} + +bool XsdTypeChecker::checkConstrainingFacetsBinary(const QByteArray &value, const XsdFacet::Hash &facets, const AnySimpleType::Ptr &type, QString &errorMsg) const +{ + if (facets.contains(XsdFacet::Length)) { + const XsdFacet::Ptr facet = facets.value(XsdFacet::Length); + const DerivedInteger::Ptr length = facet->value(); + if (length->toInteger() != value.length()) { + errorMsg = QtXmlPatterns::tr("binary content does not match the length facet"); + return false; + } + } + if (facets.contains(XsdFacet::MinimumLength)) { + const XsdFacet::Ptr facet = facets.value(XsdFacet::MinimumLength); + const DerivedInteger::Ptr length = facet->value(); + if (length->toInteger() > value.length()) { + errorMsg = QtXmlPatterns::tr("binary content does not match the minLength facet"); + return false; + } + } + if (facets.contains(XsdFacet::MaximumLength)) { + const XsdFacet::Ptr facet = facets.value(XsdFacet::MaximumLength); + const DerivedInteger::Ptr length = facet->value(); + if (length->toInteger() < value.length()) { + errorMsg = QtXmlPatterns::tr("binary content does not match the maxLength facet"); + return false; + } + } + if (facets.contains(XsdFacet::Enumeration)) { + const XsdFacet::Ptr facet = facets.value(XsdFacet::Enumeration); + const AtomicValue::List multiValue = facet->multiValue(); + bool found = false; + for (int j = 0; j < multiValue.count(); ++j) { + const Base64Binary::Ptr binary = ValueFactory::fromLexical(multiValue.at(j)->as >()->stringValue(), type, m_context, m_reflection); + const QByteArray facetValue = binary->as()->asByteArray(); + if (value == facetValue) { + found = true; + break; + } + } + + if (!found) { + errorMsg = QtXmlPatterns::tr("binary content is not listed in the enumeration facet"); + return false; + } + } + if (facets.contains(XsdFacet::Pattern)) { + //TODO: implement + } + if (facets.contains(XsdFacet::Assertion)) { + //TODO: implement + } + + return true; +} + +bool XsdTypeChecker::checkConstrainingFacetsQName(const QXmlName &value, const QString &lexicalValue, const XsdFacet::Hash &facets, QString &errorMsg) const +{ + if (facets.contains(XsdFacet::Length)) { + // always true + } + if (facets.contains(XsdFacet::MinimumLength)) { + // always true + } + if (facets.contains(XsdFacet::MaximumLength)) { + // always true + } + if (facets.contains(XsdFacet::Enumeration)) { + if (!XPathHelper::isQName(lexicalValue)) { + errorMsg = QtXmlPatterns::tr("invalid QName content: %1").arg(formatData(lexicalValue)); + return false; + } + + const XsdFacet::Ptr facet = facets.value(XsdFacet::Enumeration); + const AtomicValue::List multiValue = facet->multiValue(); + bool found = false; + for (int j = 0; j < multiValue.count(); ++j) { + const QXmlName facetValue = multiValue.at(j)->as()->qName(); + + if (value == facetValue) { + found = true; + break; + } + } + + if (!found) { + errorMsg = QtXmlPatterns::tr("QName content is not listed in the enumeration facet"); + return false; + } + } + if (facets.contains(XsdFacet::Pattern)) { + const XsdFacet::Ptr facet = facets.value(XsdFacet::Pattern); + const AtomicValue::List multiValue = facet->multiValue(); + bool found = false; + for (int j = 0; j < multiValue.count(); ++j) { + const QString pattern = multiValue.at(j)->as >()->stringValue(); + const QRegExp exp = PatternPlatform::parsePattern(pattern, m_context, m_reflection); + if (exp.exactMatch(lexicalValue)) { + found = true; + break; + } + } + + if (!found) { + errorMsg = QtXmlPatterns::tr("QName content does not match pattern facet"); + return false; + } + } + if (facets.contains(XsdFacet::Assertion)) { + //TODO: implement + } + + return true; +} + +bool XsdTypeChecker::checkConstrainingFacetsNotation(const QXmlName &value, const XsdFacet::Hash &facets, QString &errorMsg) const +{ + if (facets.contains(XsdFacet::Length)) { + // deprecated by spec + } + if (facets.contains(XsdFacet::MinimumLength)) { + // deprecated by spec + } + if (facets.contains(XsdFacet::MaximumLength)) { + // deprecated by spec + } + if (facets.contains(XsdFacet::Enumeration)) { + const XsdFacet::Ptr facet = facets.value(XsdFacet::Enumeration); + const AtomicValue::List multiValue = facet->multiValue(); + bool found = false; + for (int j = 0; j < multiValue.count(); ++j) { + const QXmlName facetValue = multiValue.at(j)->as()->qName(); + + if (value == facetValue) { + found = true; + break; + } + } + + if (!found) { + errorMsg = QtXmlPatterns::tr("notation content is not listed in the enumeration facet"); + return false; + } + } + if (facets.contains(XsdFacet::Pattern)) { + //TODO: implement + } + if (facets.contains(XsdFacet::Assertion)) { + //TODO: implement + } + + return true; +} + +bool XsdTypeChecker::checkConstrainingFacetsList(const QStringList &values, const QString &lexicalValue, const AnySimpleType::Ptr &itemType, const XsdFacet::Hash &facets, QString &errorMsg) const +{ + if (facets.contains(XsdFacet::Length)) { + const DerivedInteger::Ptr value = facets.value(XsdFacet::Length)->value(); + if (value->toInteger() != values.count()) { + errorMsg = QtXmlPatterns::tr("list content does not match length facet"); + return false; + } + } + if (facets.contains(XsdFacet::MinimumLength)) { + const DerivedInteger::Ptr value = facets.value(XsdFacet::MinimumLength)->value(); + if (value->toInteger() > values.count()) { + errorMsg = QtXmlPatterns::tr("list content does not match minLength facet"); + return false; + } + } + if (facets.contains(XsdFacet::MaximumLength)) { + const DerivedInteger::Ptr value = facets.value(XsdFacet::MaximumLength)->value(); + if (value->toInteger() < values.count()) { + errorMsg = QtXmlPatterns::tr("list content does not match maxLength facet"); + return false; + } + } + if (facets.contains(XsdFacet::Enumeration)) { + + bool found = false; + + // we have to handle lists with QName derived items differently + if (BuiltinTypes::xsQName->wxsTypeMatches(itemType) || BuiltinTypes::xsNOTATION->wxsTypeMatches(itemType)) { + // first convert the string values from the instance document to a list of QXmlName + QList instanceValues; + for (int i = 0; i < values.count(); ++i) { + instanceValues.append(convertToQName(values.at(i))); + } + + // fetch the values from the facet and create a list of QXmlNames for each of them + const XsdFacet::Ptr facet = facets.value(XsdFacet::Enumeration); + + const AtomicValue::List multiValue = facet->multiValue(); + for (int i = 0; i < multiValue.count(); ++i) { + const QStringList facetValueList = multiValue.at(i)->as >()->stringValue().split(QLatin1Char(' '), QString::SkipEmptyParts); + + // create the list of atomic string values + QList facetValues; + for (int j = 0; j < facetValueList.count(); ++j) { + facetValues.append(convertToQName(facetValueList.at(j))); + } + + // check if both lists have the same length + if (instanceValues.count() != facetValues.count()) + continue; + + // check if both lists are equal, that means the contain equal items in the same order + bool matchesAll = true; + for (int j = 0; j < instanceValues.count(); ++j) { + if (instanceValues.at(j) != facetValues.at(j)) { + matchesAll = false; + break; + } + } + + if (matchesAll) { + found = true; + break; + } + } + } else { + // first convert the string values from the instance document to atomic values of type string + AtomicValue::List instanceValues; + for (int i = 0; i < values.count(); ++i) { + instanceValues.append(DerivedString::fromLexical(m_namePool, values.at(i))); + } + + // fetch the values from the facet and create a list of atomic string values for each of them + const XsdFacet::Ptr facet = facets.value(XsdFacet::Enumeration); + + const AnySimpleType::Ptr targetType = comparableType(itemType); + + const AtomicValue::List multiValue = facet->multiValue(); + for (int i = 0; i < multiValue.count(); ++i) { + const QStringList facetValueList = multiValue.at(i)->as >()->stringValue().split(QLatin1Char(' '), QString::SkipEmptyParts); + + // create the list of atomic string values + AtomicValue::List facetValues; + for (int j = 0; j < facetValueList.count(); ++j) { + facetValues.append(DerivedString::fromLexical(m_namePool, facetValueList.at(j))); + } + + // check if both lists have the same length + if (instanceValues.count() != facetValues.count()) + continue; + + // check if both lists are equal, that means the contain equal items in the same order + bool matchesAll = true; + for (int j = 0; j < instanceValues.count(); ++j) { + if (!XsdSchemaHelper::constructAndCompare(instanceValues.at(j), AtomicComparator::OperatorEqual, facetValues.at(j), targetType, m_context, m_reflection)) { + matchesAll = false; + break; + } + } + + if (matchesAll) { + found = true; + break; + } + } + } + + if (!found) { + errorMsg = QtXmlPatterns::tr("list content is not listed in the enumeration facet"); + return false; + } + } + if (facets.contains(XsdFacet::Pattern)) { + const XsdFacet::Ptr facet = facets.value(XsdFacet::Pattern); + const AtomicValue::List multiValue = facet->multiValue(); + bool found = false; + for (int j = 0; j < multiValue.count(); ++j) { + const QString pattern = multiValue.at(j)->as >()->stringValue(); + const QRegExp exp = PatternPlatform::parsePattern(pattern, m_context, m_reflection); + if (exp.exactMatch(lexicalValue)) { + found = true; + break; + } + } + + if (!found) { + errorMsg = QtXmlPatterns::tr("list content does not match pattern facet"); + return false; + } + } + if (facets.contains(XsdFacet::Assertion)) { + //TODO: implement + } + + return true; +} + +bool XsdTypeChecker::checkConstrainingFacetsUnion(const QString &value, const QString &lexicalValue, const XsdSimpleType::Ptr &simpleType, const XsdFacet::Hash &facets, QString &errorMsg) const +{ + if (facets.contains(XsdFacet::Enumeration)) { + const AnySimpleType::List memberTypes = simpleType->memberTypes(); + + const XsdFacet::Ptr facet = facets.value(XsdFacet::Enumeration); + + // convert the instance value into an atomic string value + const DerivedString::Ptr valueString = DerivedString::fromLexical(m_namePool, value); + + // collect the facet values into a list of atomic string values + const AtomicValue::List facetValues = facet->multiValue(); + + // compare the instance value against the facetValues for each member type and + // search for a match + + bool found = false; + for (int i = 0; i < memberTypes.count(); ++i) { + const AnySimpleType::Ptr targetType = comparableType(memberTypes.at(i)); + for (int j = 0; j < facetValues.count(); ++j) { + if (XsdSchemaHelper::constructAndCompare(valueString, AtomicComparator::OperatorEqual, facetValues.at(j), targetType, m_context, m_reflection)) { + found = true; + break; + } + } + } + + if (!found) { + errorMsg = QtXmlPatterns::tr("union content is not listed in the enumeration facet"); + return false; + } + } + if (facets.contains(XsdFacet::Pattern)) { + const XsdFacet::Ptr facet = facets.value(XsdFacet::Pattern); + const AtomicValue::List multiValue = facet->multiValue(); + bool found = false; + for (int j = 0; j < multiValue.count(); ++j) { + const QString pattern = multiValue.at(j)->as >()->stringValue(); + const QRegExp exp = PatternPlatform::parsePattern(pattern, m_context, m_reflection); + if (exp.exactMatch(lexicalValue)) { + found = true; + break; + } + } + + if (!found) { + errorMsg = QtXmlPatterns::tr("union content does not match pattern facet"); + return false; + } + } + if (facets.contains(XsdFacet::Assertion)) { + //TODO: implement + } + + return true; +} + +AtomicValue::Ptr XsdTypeChecker::fromLexical(const QString &value, const SchemaType::Ptr &type, const ReportContext::Ptr &context, const SourceLocationReflection *const reflection) const +{ + if (type->name(m_namePool) == BuiltinTypes::xsNOTATION->name(m_namePool) || type->name(m_namePool) == BuiltinTypes::xsQName->name(m_namePool)) { + if (value.simplified().isEmpty()) + return ValidationError::createError(QtXmlPatterns::tr("data of type %1 are not allowed to be empty").arg(formatType(m_namePool, BuiltinTypes::xsNOTATION))); + + const QXmlName valueName = convertToQName(value); + return QNameValue::fromValue(m_namePool, valueName); + } else { + return ValueFactory::fromLexical(value, type, context, reflection); + } +} + +QXmlName XsdTypeChecker::convertToQName(const QString &name) const +{ + const int pos = name.indexOf(QLatin1Char(':')); + + QXmlName::PrefixCode prefixCode = 0; + QXmlName::NamespaceCode namespaceCode; + QXmlName::LocalNameCode localNameCode; + if (pos != -1) { + prefixCode = m_context->namePool()->allocatePrefix(name.left(pos)); + namespaceCode = StandardNamespaces::empty; + for (int i = 0; i < m_namespaceBindings.count(); ++i) { + if (m_namespaceBindings.at(i).prefix() == prefixCode) { + namespaceCode = m_namespaceBindings.at(i).namespaceURI(); + break; + } + } + localNameCode = m_context->namePool()->allocateLocalName(name.mid(pos + 1)); + } else { + prefixCode = StandardPrefixes::empty; + namespaceCode = StandardNamespaces::empty; + for (int i = 0; i < m_namespaceBindings.count(); ++i) { + if (m_namespaceBindings.at(i).prefix() == prefixCode) { + namespaceCode = m_namespaceBindings.at(i).namespaceURI(); + break; + } + } + localNameCode = m_context->namePool()->allocateLocalName(name); + } + + return QXmlName(namespaceCode, localNameCode, prefixCode); +} + +QT_END_NAMESPACE diff --git a/src/xmlpatterns/schema/qxsdtypechecker_p.h b/src/xmlpatterns/schema/qxsdtypechecker_p.h new file mode 100644 index 0000000..2af20db --- /dev/null +++ b/src/xmlpatterns/schema/qxsdtypechecker_p.h @@ -0,0 +1,159 @@ +/**************************************************************************** +** +** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the $MODULE$ of the Qt Toolkit. +** +** $TROLLTECH_DUAL_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_XsdTypeChecker_H +#define Patternist_XsdTypeChecker_H + +#include + +#include "qschematype_p.h" +#include "qsourcelocationreflection_p.h" +#include "qxsdschemacontext_p.h" + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +class QXmlQuery; + +namespace QPatternist +{ + /** + * @short An implementation of SourceLocationReflection that takes a QSourceLocation. + * + * This is a convenience class which provides a QSourceLocation with a SourceLocationReflection + * interface. + */ + class XsdSchemaSourceLocationReflection : public SourceLocationReflection + { + public: + XsdSchemaSourceLocationReflection(const QSourceLocation &location); + + virtual const SourceLocationReflection *actualReflection() const; + virtual QSourceLocation sourceLocation() const; + + private: + const QSourceLocation m_sourceLocation; + }; + + /** + * @short The class that provides methods for checking a string against a type. + * + * The class provides functionality for type-aware string handling. + */ + class XsdTypeChecker + { + public: + /** + * Creates a new type checker. + * + * @param context The schema context that is used for error reporting. + * @param namespaceBindings The namespace bindings that shall be used to check against xs:QName based types. + * @param location The source location that is used for error reporting. + */ + XsdTypeChecker(const XsdSchemaContext::Ptr &context, const QVector &namespaceBindings, const QSourceLocation &location); + + /** + * Destroys the type checker. + */ + ~XsdTypeChecker(); + + /** + * Returns all facets for the given @p type. + * + * The list of facets is created by following the type hierarchy from xs:anyType down to the given type + * and merging the facets in each step. + */ + static XsdFacet::Hash mergedFacetsForType(const SchemaType::Ptr &type, const XsdSchemaContext::Ptr &context); + + /** + * Returns the normalized value for the given @p value. + * + * The normalized value is the original value with all the white space facets + * applied on it. + * + * @param value The original value. + * @param facets The hash of all facets of the values type. + */ + static QString normalizedValue(const QString &value, const XsdFacet::Hash &facets); + + /** + * Checks whether the @p normalizedString is valid according the given @p type. + * + * @param normalizedString The string in normalized form (whitespace facets applied). + * @param type The type the string shall be tested against. + * @param errorMsg Contains the error message if the normalizedString does not match the type. + * @param boundType The type the data was bound to during validation. + * + * @note The @p boundType only differs from @p type if the type is derived from an based union value. + */ + bool isValidString(const QString &normalizedString, const AnySimpleType::Ptr &type, QString &errorMsg, AnySimpleType::Ptr *boundType = 0) const; + + /** + * Returns whether the given @p value and @p otherValue are of @p type and are equal. + */ + bool valuesAreEqual(const QString &value, const QString &otherValue, const AnySimpleType::Ptr &type) const; + + private: + Q_DISABLE_COPY(XsdTypeChecker) + + /** + * Checks the given value against the facets of @p type. + */ + bool checkConstrainingFacets(const AtomicValue::Ptr &value, const QString &lexicalValue, const AnySimpleType::Ptr &type, QString &errorMsg) const; + bool checkConstrainingFacetsString(const QString &value, const XsdFacet::Hash &facets, const AnySimpleType::Ptr &type, QString &errorMsg) const; + bool checkConstrainingFacetsSignedInteger(long long value, const QString &lexicalValue, const XsdFacet::Hash &facets, QString &errorMsg) const; + bool checkConstrainingFacetsUnsignedInteger(unsigned long long value, const QString &lexicalValue, const XsdFacet::Hash &facets, QString &errorMsg) const; + bool checkConstrainingFacetsDouble(double value, const QString &lexicalValue, const XsdFacet::Hash &facets, QString &errorMsg) const; + bool checkConstrainingFacetsDecimal(const AtomicValue::Ptr &value, const QString &lexicalValue, const XsdFacet::Hash &facets, QString &errorMsg) const; + bool checkConstrainingFacetsDateTime(const QDateTime &value, const QString &lexicalValue, const XsdFacet::Hash &facets, const AnySimpleType::Ptr &type, QString &errorMsg) const; + bool checkConstrainingFacetsDuration(const AtomicValue::Ptr &value, const QString &lexicalValue, const XsdFacet::Hash &facets, QString &errorMsg) const; + bool checkConstrainingFacetsBoolean(bool value, const QString &lexicalValue, const XsdFacet::Hash &facets, QString &errorMsg) const; + bool checkConstrainingFacetsBinary(const QByteArray &value, const XsdFacet::Hash &facets, const AnySimpleType::Ptr &type, QString &errorMsg) const; + bool checkConstrainingFacetsQName(const QXmlName&, const QString &lexicalValue, const XsdFacet::Hash &facets, QString &errorMsg) const; + bool checkConstrainingFacetsNotation(const QXmlName &value, const XsdFacet::Hash &facets, QString &errorMsg) const; + bool checkConstrainingFacetsList(const QStringList &values, const QString &lexicalValue, const AnySimpleType::Ptr &itemType, const XsdFacet::Hash &facets, QString &errorMsg) const; + bool checkConstrainingFacetsUnion(const QString &value, const QString &lexicalValue, const XsdSimpleType::Ptr &simpleType, const XsdFacet::Hash &facets, QString &errorMsg) const; + + /** + * Creates an atomic value of @p type from the given string @p value. + */ + AtomicValue::Ptr fromLexical(const QString &value, const SchemaType::Ptr &type, const ReportContext::Ptr &context, const SourceLocationReflection *const reflection) const; + + /** + * Converts a qualified name into a QXmlName according to the namespace + * mappings of the current node. + */ + QXmlName convertToQName(const QString &name) const; + + XsdSchemaContext::Ptr m_context; + XsdSchema::Ptr m_schema; + const NamePool::Ptr m_namePool; + QVector m_namespaceBindings; + SourceLocationReflection* m_reflection; + }; +} + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif diff --git a/src/xmlpatterns/schema/qxsduserschematype.cpp b/src/xmlpatterns/schema/qxsduserschematype.cpp new file mode 100644 index 0000000..b8bf7e7 --- /dev/null +++ b/src/xmlpatterns/schema/qxsduserschematype.cpp @@ -0,0 +1,45 @@ +/**************************************************************************** +** +** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the $MODULE$ of the Qt Toolkit. +** +** $TROLLTECH_DUAL_LICENSE$ +** +****************************************************************************/ + +/* + * NOTE: This file is included by qxsduserschematype_p.h + * if you need some includes, put them in qxsduserschematype_p.h (outside of the namespace) + */ + +template +void XsdUserSchemaType::setName(const QXmlName &name) +{ + m_name = name; +} + +template +QXmlName XsdUserSchemaType::name(const NamePool::Ptr&) const +{ + return m_name; +} + +template +QString XsdUserSchemaType::displayName(const NamePool::Ptr &np) const +{ + return np->displayName(m_name); +} + +template +void XsdUserSchemaType::setDerivationConstraints(const SchemaType::DerivationConstraints &constraints) +{ + m_derivationConstraints = constraints; +} + +template +SchemaType::DerivationConstraints XsdUserSchemaType::derivationConstraints() const +{ + return m_derivationConstraints; +} diff --git a/src/xmlpatterns/schema/qxsduserschematype_p.h b/src/xmlpatterns/schema/qxsduserschematype_p.h new file mode 100644 index 0000000..ab70f91 --- /dev/null +++ b/src/xmlpatterns/schema/qxsduserschematype_p.h @@ -0,0 +1,94 @@ +/**************************************************************************** +** +** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the $MODULE$ of the Qt Toolkit. +** +** $TROLLTECH_DUAL_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_XsdUserSchemaType_H +#define Patternist_XsdUserSchemaType_H + +#include "qnamedschemacomponent_p.h" +#include "qschematype_p.h" +#include "qxsdannotated_p.h" + +template class QHash; +template class QList; + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +namespace QPatternist +{ + /** + * @short A base class for all user defined simple and complex types. + * + * This class was introduced to combine the SchemaType class and the + * NamedSchemaComponent class without explicit inheritance. + * + * @ingroup Patternist_schema + * @author Tobias Koenig + */ + template + class XsdUserSchemaType : public TSuperClass, public NamedSchemaComponent, public XsdAnnotated + { + public: + typedef QExplicitlySharedDataPointer Ptr; + + /** + * Sets the @p name of the type. + */ + void setName(const QXmlName &name); + + /** + * Returns the name of the type. + * + * @param namePool The pool the name belongs to. + */ + virtual QXmlName name(const NamePool::Ptr &namePool) const; + + /** + * Returns the display name of the type. + * + * @param namePool The pool the name belongs to. + */ + virtual QString displayName(const NamePool::Ptr &namePool) const; + + /** + * Sets the derivation @p constraints of the type. + */ + void setDerivationConstraints(const SchemaType::DerivationConstraints &constraints); + + /** + * Returns the derivation constraints of the type. + */ + SchemaType::DerivationConstraints derivationConstraints() const; + + private: + QXmlName m_name; + SchemaType::DerivationConstraints m_derivationConstraints; + }; + + #include "qxsduserschematype.cpp" +} + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif diff --git a/src/xmlpatterns/schema/qxsdvalidatedxmlnodemodel.cpp b/src/xmlpatterns/schema/qxsdvalidatedxmlnodemodel.cpp new file mode 100644 index 0000000..8e1645a --- /dev/null +++ b/src/xmlpatterns/schema/qxsdvalidatedxmlnodemodel.cpp @@ -0,0 +1,185 @@ +/**************************************************************************** +** +** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the $MODULE$ of the Qt Toolkit. +** +** $TROLLTECH_DUAL_LICENSE$ +** +****************************************************************************/ + +#include "qxsdvalidatedxmlnodemodel_p.h" + +#include +#include +#include + +QT_BEGIN_NAMESPACE + +using namespace QPatternist; + +XsdValidatedXmlNodeModel::XsdValidatedXmlNodeModel(const QAbstractXmlNodeModel *model) + : m_internalModel(const_cast(model)) +{ +} + +XsdValidatedXmlNodeModel::~XsdValidatedXmlNodeModel() +{ +} + +QUrl XsdValidatedXmlNodeModel::baseUri(const QXmlNodeModelIndex &index) const +{ + return m_internalModel->baseUri(index); +} + +QUrl XsdValidatedXmlNodeModel::documentUri(const QXmlNodeModelIndex &index) const +{ + return m_internalModel->documentUri(index); +} + +QXmlNodeModelIndex::NodeKind XsdValidatedXmlNodeModel::kind(const QXmlNodeModelIndex &index) const +{ + return m_internalModel->kind(index); +} + +QXmlNodeModelIndex::DocumentOrder XsdValidatedXmlNodeModel::compareOrder(const QXmlNodeModelIndex &index, const QXmlNodeModelIndex &otherIndex) const +{ + return m_internalModel->compareOrder(index, otherIndex); +} + +QXmlNodeModelIndex XsdValidatedXmlNodeModel::root(const QXmlNodeModelIndex &index) const +{ + return m_internalModel->root(index); +} + +QXmlName XsdValidatedXmlNodeModel::name(const QXmlNodeModelIndex &index) const +{ + return m_internalModel->name(index); +} + +QString XsdValidatedXmlNodeModel::stringValue(const QXmlNodeModelIndex &index) const +{ + return m_internalModel->stringValue(index); +} + +QVariant XsdValidatedXmlNodeModel::typedValue(const QXmlNodeModelIndex &index) const +{ + return m_internalModel->typedValue(index); +} + +QExplicitlySharedDataPointer > XsdValidatedXmlNodeModel::iterate(const QXmlNodeModelIndex &index, QXmlNodeModelIndex::Axis axis) const +{ + return m_internalModel->iterate(index, axis); +} + +QPatternist::ItemIteratorPtr XsdValidatedXmlNodeModel::sequencedTypedValue(const QXmlNodeModelIndex &index) const +{ + return m_internalModel->sequencedTypedValue(index); +} + +QPatternist::ItemTypePtr XsdValidatedXmlNodeModel::type(const QXmlNodeModelIndex &index) const +{ + return m_internalModel->type(index); +} + +QXmlName::NamespaceCode XsdValidatedXmlNodeModel::namespaceForPrefix(const QXmlNodeModelIndex &index, const QXmlName::PrefixCode prefix) const +{ + return m_internalModel->namespaceForPrefix(index, prefix); +} + +bool XsdValidatedXmlNodeModel::isDeepEqual(const QXmlNodeModelIndex &index, const QXmlNodeModelIndex &otherIndex) const +{ + return m_internalModel->isDeepEqual(index, otherIndex); +} + +void XsdValidatedXmlNodeModel::sendNamespaces(const QXmlNodeModelIndex &index, QAbstractXmlReceiver *const receiver) const +{ + m_internalModel->sendNamespaces(index, receiver); +} + +QVector XsdValidatedXmlNodeModel::namespaceBindings(const QXmlNodeModelIndex &index) const +{ + return m_internalModel->namespaceBindings(index); +} + +QXmlNodeModelIndex XsdValidatedXmlNodeModel::elementById(const QXmlName &name) const +{ + return m_internalModel->elementById(name); +} + +QVector XsdValidatedXmlNodeModel::nodesByIdref(const QXmlName &name) const +{ + return m_internalModel->nodesByIdref(name); +} + +void XsdValidatedXmlNodeModel::copyNodeTo(const QXmlNodeModelIndex &index, QAbstractXmlReceiver *const receiver, const NodeCopySettings &settings) const +{ + return m_internalModel->copyNodeTo(index, receiver, settings); +} + +QXmlNodeModelIndex XsdValidatedXmlNodeModel::nextFromSimpleAxis(SimpleAxis axis, const QXmlNodeModelIndex &origin) const +{ + return m_internalModel->nextFromSimpleAxis(axis, origin); +} + +QVector XsdValidatedXmlNodeModel::attributes(const QXmlNodeModelIndex &index) const +{ + return m_internalModel->attributes(index); +} + +void XsdValidatedXmlNodeModel::setAssignedElement(const QXmlNodeModelIndex &index, const XsdElement::Ptr &element) +{ + m_assignedElements.insert(index, element); +} + +XsdElement::Ptr XsdValidatedXmlNodeModel::assignedElement(const QXmlNodeModelIndex &index) const +{ + if (m_assignedElements.contains(index)) + return m_assignedElements.value(index); + else + return XsdElement::Ptr(); +} + +void XsdValidatedXmlNodeModel::setAssignedAttribute(const QXmlNodeModelIndex &index, const XsdAttribute::Ptr &attribute) +{ + m_assignedAttributes.insert(index, attribute); +} + +XsdAttribute::Ptr XsdValidatedXmlNodeModel::assignedAttribute(const QXmlNodeModelIndex &index) const +{ + if (m_assignedAttributes.contains(index)) + return m_assignedAttributes.value(index); + else + return XsdAttribute::Ptr(); +} + +void XsdValidatedXmlNodeModel::setAssignedType(const QXmlNodeModelIndex &index, const SchemaType::Ptr &type) +{ + m_assignedTypes.insert(index, type); +} + +SchemaType::Ptr XsdValidatedXmlNodeModel::assignedType(const QXmlNodeModelIndex &index) const +{ + if (m_assignedTypes.contains(index)) + return m_assignedTypes.value(index); + else + return SchemaType::Ptr(); +} + +void XsdValidatedXmlNodeModel::addIdIdRefBinding(const QString &id, const NamedSchemaComponent::Ptr &binding) +{ + m_idIdRefBindings[id].insert(binding); +} + +QStringList XsdValidatedXmlNodeModel::idIdRefBindingIds() const +{ + return m_idIdRefBindings.keys(); +} + +QSet XsdValidatedXmlNodeModel::idIdRefBindings(const QString &id) const +{ + return m_idIdRefBindings.value(id); +} + +QT_END_NAMESPACE diff --git a/src/xmlpatterns/schema/qxsdvalidatedxmlnodemodel_p.h b/src/xmlpatterns/schema/qxsdvalidatedxmlnodemodel_p.h new file mode 100644 index 0000000..579f41a --- /dev/null +++ b/src/xmlpatterns/schema/qxsdvalidatedxmlnodemodel_p.h @@ -0,0 +1,149 @@ +/**************************************************************************** +** +** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the $MODULE$ of the Qt Toolkit. +** +** $TROLLTECH_DUAL_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_XsdValidatedXmlNodeModel_H +#define Patternist_XsdValidatedXmlNodeModel_H + +#include "qabstractxmlnodemodel.h" + +#include "qabstractxmlforwarditerator_p.h" +#include "qitem_p.h" +#include "qschematype_p.h" +#include "qxsdelement_p.h" + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +namespace QPatternist +{ + /** + * @short A delegate class that wraps around a QAbstractXmlNodeModel and provides + * additional validation specific information. + * + * This class represents the input XML document enriched with additional type + * information that has been assigned during validation. + * + * @ingroup Patternist_schema + * @author Tobias Koenig + */ + class XsdValidatedXmlNodeModel : public QAbstractXmlNodeModel + { + public: + typedef QExplicitlySharedDataPointer Ptr; + typedef QList List; + + /** + * Creates a new validated xml node model. + */ + XsdValidatedXmlNodeModel(const QAbstractXmlNodeModel *model); + + /** + * Destroys the validated xml node model. + */ + virtual ~XsdValidatedXmlNodeModel(); + + virtual QUrl baseUri(const QXmlNodeModelIndex &ni) const; + virtual QUrl documentUri(const QXmlNodeModelIndex &ni) const; + virtual QXmlNodeModelIndex::NodeKind kind(const QXmlNodeModelIndex &ni) const; + virtual QXmlNodeModelIndex::DocumentOrder compareOrder(const QXmlNodeModelIndex &ni1, const QXmlNodeModelIndex &ni2) const; + virtual QXmlNodeModelIndex root(const QXmlNodeModelIndex &n) const; + virtual QXmlName name(const QXmlNodeModelIndex &ni) const; + virtual QString stringValue(const QXmlNodeModelIndex &n) const; + virtual QVariant typedValue(const QXmlNodeModelIndex &n) const; + virtual QExplicitlySharedDataPointer > iterate(const QXmlNodeModelIndex &ni, QXmlNodeModelIndex::Axis axis) const; + virtual QPatternist::ItemIteratorPtr sequencedTypedValue(const QXmlNodeModelIndex &ni) const; + virtual QPatternist::ItemTypePtr type(const QXmlNodeModelIndex &ni) const; + virtual QXmlName::NamespaceCode namespaceForPrefix(const QXmlNodeModelIndex &ni, const QXmlName::PrefixCode prefix) const; + virtual bool isDeepEqual(const QXmlNodeModelIndex &ni1, const QXmlNodeModelIndex &ni2) const; + virtual void sendNamespaces(const QXmlNodeModelIndex &n, QAbstractXmlReceiver *const receiver) const; + virtual QVector namespaceBindings(const QXmlNodeModelIndex &n) const; + virtual QXmlNodeModelIndex elementById(const QXmlName &NCName) const; + virtual QVector nodesByIdref(const QXmlName &NCName) const; + virtual void copyNodeTo(const QXmlNodeModelIndex &node, QAbstractXmlReceiver *const receiver, const NodeCopySettings &) const; + + /** + * Sets the @p element that is assigned to the xml node at @p index. + */ + void setAssignedElement(const QXmlNodeModelIndex &index, const XsdElement::Ptr &element); + + /** + * Returns the element that is assigned to the xml node at @p index. + */ + XsdElement::Ptr assignedElement(const QXmlNodeModelIndex &index) const; + + /** + * Sets the @p attribute that is assigned to the xml node at @p index. + */ + void setAssignedAttribute(const QXmlNodeModelIndex &index, const XsdAttribute::Ptr &attribute); + + /** + * Returns the attribute that is assigned to the xml node at @p index. + */ + XsdAttribute::Ptr assignedAttribute(const QXmlNodeModelIndex &index) const; + + /** + * Sets the @p type that is assigned to the xml node at @p index. + * + * @note The type can be a different than the type of the element or + * attribute that is assigned to the index, since the instance + * document can overwrite it by xsi:type. + */ + void setAssignedType(const QXmlNodeModelIndex &index, const SchemaType::Ptr &type); + + /** + * Returns the type that is assigned to the xml node at @p index. + */ + SchemaType::Ptr assignedType(const QXmlNodeModelIndex &index) const; + + /** + * Adds the attribute or element @p binding with the given @p id. + */ + void addIdIdRefBinding(const QString &id, const NamedSchemaComponent::Ptr &binding); + + /** + * Returns a list of all binding ids. + */ + QStringList idIdRefBindingIds() const; + + /** + * Returns the set of bindings with the given @p id. + */ + QSet idIdRefBindings(const QString &id) const; + + protected: + virtual QXmlNodeModelIndex nextFromSimpleAxis(SimpleAxis axis, const QXmlNodeModelIndex &origin) const; + virtual QVector attributes(const QXmlNodeModelIndex &element) const; + + private: + QAbstractXmlNodeModel::Ptr m_internalModel; + QHash m_assignedElements; + QHash m_assignedAttributes; + QHash m_assignedTypes; + QHash > m_idIdRefBindings; + }; +} + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif diff --git a/src/xmlpatterns/schema/qxsdvalidatinginstancereader.cpp b/src/xmlpatterns/schema/qxsdvalidatinginstancereader.cpp new file mode 100644 index 0000000..12fc477 --- /dev/null +++ b/src/xmlpatterns/schema/qxsdvalidatinginstancereader.cpp @@ -0,0 +1,1245 @@ +/**************************************************************************** +** +** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the $MODULE$ of the Qt Toolkit. +** +** $TROLLTECH_DUAL_LICENSE$ +** +****************************************************************************/ + +#include "qxsdvalidatinginstancereader_p.h" + +#include "qabstractdatetime_p.h" +#include "qacceltreeresourceloader_p.h" +#include "qbase64binary_p.h" +#include "qboolean_p.h" +#include "qderivedinteger_p.h" +#include "qduration_p.h" +#include "qgenericstaticcontext_p.h" +#include "qhexbinary_p.h" +#include "qnamespaceresolver_p.h" +#include "qpatternplatform_p.h" +#include "qqnamevalue_p.h" +#include "qsourcelocationreflection_p.h" +#include "qvaluefactory_p.h" +#include "qxmlnamepool.h" +#include "qxmlquery_p.h" +#include "qxmlschema_p.h" +#include "qxsdschemahelper_p.h" +#include "qxsdschemamerger_p.h" +#include "qxsdstatemachine_p.h" +#include "qxsdstatemachinebuilder_p.h" +#include "qxsdtypechecker_p.h" + +#include "qxsdschemadebugger_p.h" + +#include +#include +#include + +QT_BEGIN_NAMESPACE + +using namespace QPatternist; + +namespace QPatternist +{ + template <> + template <> + bool XsdStateMachine::inputEqualsTransition(QXmlName name, XsdTerm::Ptr term) const + { + if (term->isElement()) { + return (XsdElement::Ptr(term)->name(m_namePool) == name); + } else if (term->isWildcard()) { + // wildcards using XsdWildcard::absentNamespace, so we have to fix that here + if (name.namespaceURI() == StandardNamespaces::empty) { + name.setNamespaceURI(m_namePool->allocateNamespace(XsdWildcard::absentNamespace())); + } + + return XsdSchemaHelper::wildcardAllowsExpandedName(name, XsdWildcard::Ptr(term), m_namePool); + } + + return false; + } +} + +XsdValidatingInstanceReader::XsdValidatingInstanceReader(const XsdValidatedXmlNodeModel *model, const QUrl &documentUri, const XsdSchemaContext::Ptr &context) + : XsdInstanceReader(model, context) + , m_model(const_cast(model)) + , m_namePool(m_context->namePool()) + , m_xsiNilName(m_namePool->allocateQName(QLatin1String("http://www.w3.org/2001/XMLSchema-instance"), QLatin1String("nil"))) + , m_xsiTypeName(m_namePool->allocateQName(QLatin1String("http://www.w3.org/2001/XMLSchema-instance"), QLatin1String("type"))) + , m_xsiSchemaLocationName(m_namePool->allocateQName(QLatin1String("http://www.w3.org/2001/XMLSchema-instance"), QLatin1String("schemaLocation"))) + , m_xsiNoNamespaceSchemaLocationName(m_namePool->allocateQName(QLatin1String("http://www.w3.org/2001/XMLSchema-instance"), QLatin1String("noNamespaceSchemaLocation"))) + , m_documentUri(documentUri) +{ + m_idRefsType = m_context->schemaTypeFactory()->createSchemaType(m_namePool->allocateQName(CommonNamespaces::WXS, QLatin1String("IDREFS"))); +} + +void XsdValidatingInstanceReader::addSchema(const XsdSchema::Ptr &schema, const QUrl &locationUrl) +{ + if (!m_mergedSchemas.contains(locationUrl)) { + m_mergedSchemas.insert(locationUrl, QStringList() << schema->targetNamespace()); + } else { + QStringList &targetNamespaces = m_mergedSchemas[locationUrl]; + if (targetNamespaces.contains(schema->targetNamespace())) + return; + + targetNamespaces.append(schema->targetNamespace()); + } + + const XsdSchemaMerger merger(m_schema, schema); + m_schema = merger.mergedSchema(); +/* + XsdSchemaDebugger dbg(m_namePool); + dbg.dumpSchema(m_schema); +*/ +} + +bool XsdValidatingInstanceReader::read() +{ + while (!atEnd()) { + readNext(); + + if (isEndElement()) + return true; + + if (isStartElement()) { + const QXmlName elementName = name(); + const QXmlItem currentItem = item(); + bool hasStateMachine = false; + XsdElement::Ptr processedElement; + + if (!validate(hasStateMachine, processedElement)) + return false; + + read(); + + if (processedElement) { // for wildcard with 'skip' we have no element + m_model->setAssignedElement(currentItem.toNodeModelIndex(), processedElement); + + // check identity constraints after all child nodes have been + // validated, so that we know there assigned types + validateIdentityConstraint(processedElement, currentItem); + } + + if (!m_stateMachines.isEmpty() && hasStateMachine) { + if (!m_stateMachines.top().inEndState()) { + error(QtXmlPatterns::tr("element %1 is missing child element").arg(formatKeyword(m_namePool->displayName(elementName)))); + return false; + } + m_stateMachines.pop(); + } + } + } + + // final validations + + // check IDREF occurrences + const QStringList ids = m_model->idIdRefBindingIds(); + QSetIterator it(m_idRefs); + while (it.hasNext()) { + const QString id = it.next(); + if (!ids.contains(id)) { + error(QtXmlPatterns::tr("there is one IDREF value with no corresponding ID: %1").arg(formatKeyword(id))); + return false; + } + } + + return true; +} + +void XsdValidatingInstanceReader::error(const QString &msg) const +{ + const_cast(m_context.data())->error(msg, XsdSchemaContext::XSDError, sourceLocation()); +} + +bool XsdValidatingInstanceReader::loadSchema(const QString &targetNamespace, const QUrl &location) +{ + const AutoPtr reply(AccelTreeResourceLoader::load(location, m_context->networkAccessManager(), + m_context, AccelTreeResourceLoader::ContinueOnError)); + if (!reply) + return true; + + // we have to create a separated schema context here, that however shares the type factory + XsdSchemaContext::Ptr context(new XsdSchemaContext(m_namePool)); + context->m_schemaTypeFactory = m_context->m_schemaTypeFactory; + + QXmlSchemaPrivate schema(context); + schema.load(reply.data(), location, targetNamespace); + if (!schema.isValid()) { + error(QtXmlPatterns::tr("loaded schema file is invalid")); + return false; + } + + addSchema(schema.m_schemaParserContext->schema(), location); + + return true; +} + +bool XsdValidatingInstanceReader::validate(bool &hasStateMachine, XsdElement::Ptr &processedElement) +{ + // first check if a custom schema is defined + if (hasAttribute(m_xsiSchemaLocationName)) { + const QString schemaLocation = attribute(m_xsiSchemaLocationName); + const QStringList parts = schemaLocation.split(QLatin1Char(' '), QString::SkipEmptyParts); + if ((parts.count()%2) == 1) { + error(QtXmlPatterns::tr("%1 contains invalid data").arg(formatKeyword(m_namePool, m_xsiSchemaLocationName))); + return false; + } + + for (int i = 0; i < parts.count(); i += 2) { + const QString identifier = QString::fromLatin1("%1 %2").arg(parts.at(i)).arg(parts.at(i + 1)); + if (m_processedSchemaLocations.contains(identifier)) + continue; + else + m_processedSchemaLocations.insert(identifier); + + // check constraint 4) from http://www.w3.org/TR/xmlschema-1/#schema-loc (only valid for XML Schema 1.0?) + if (m_processedNamespaces.contains(parts.at(i))) { + error(QtXmlPatterns::tr("xsi:schemaLocation namespace %1 has already appeared earlier in the instance document").arg(formatKeyword(parts.at(i)))); + return false; + } + + QUrl url(parts.at(i + 1)); + if (url.isRelative()) { + Q_ASSERT(m_documentUri.isValid()); + + url = m_documentUri.resolved(url); + } + + loadSchema(parts.at(i), url); + } + } + + if (hasAttribute(m_xsiNoNamespaceSchemaLocationName)) { + const QString schemaLocation = attribute(m_xsiNoNamespaceSchemaLocationName); + + if (!m_processedSchemaLocations.contains(schemaLocation)) { + m_processedSchemaLocations.insert(schemaLocation); + + if (m_processedNamespaces.contains(QString())) { + error(QtXmlPatterns::tr("xsi:noNamespaceSchemaLocation cannot appear after the first no-namespace element or attribute")); + return false; + } + + QUrl url(schemaLocation); + if (url.isRelative()) { + Q_ASSERT(m_documentUri.isValid()); + + url = m_documentUri.resolved(url); + } + + loadSchema(QString(), url); + } + } + + m_processedNamespaces.insert(m_namePool->stringForNamespace(name().namespaceURI())); + + if (!m_schema) { + error(QtXmlPatterns::tr("no schema defined for validation")); + return false; + } + + // check if we are 'inside' a type definition + if (m_stateMachines.isEmpty()) { + // find out the type of the top-level element + XsdElement::Ptr element = elementByName(name()); + if (!element) { + if (!hasAttribute(m_xsiTypeName)) { + error(QtXmlPatterns::tr("no definition for element %1 available").arg(formatKeyword(m_namePool, name()))); + return false; + } + + // This instance document has an element with no definition in the schema + // but an explicitly given type, that is fine according to the spec. + // We will create an element definition manually here and continue the + // normal validation process + element = XsdElement::Ptr(new XsdElement()); + element->setName(name()); + element->setIsAbstract(false); + element->setIsNillable(hasAttribute(m_xsiNilName)); + + const QString type = qNameAttribute(m_xsiTypeName); + const QXmlName typeName = convertToQName(type); + + const SchemaType::Ptr elementType = typeByName(typeName); + if (!elementType) { + error(QtXmlPatterns::tr("specified type %1 is not known to the schema").arg(formatType(m_namePool, typeName))); + return false; + } + element->setType(elementType); + } + + // rememeber the element we process + processedElement = element; + + if (!validateElement(element, hasStateMachine)) { + return false; + } + + } else { + if (!m_stateMachines.top().proceed(name())) { + error(QtXmlPatterns::tr("element %1 is not defined in this scope").arg(formatKeyword(m_namePool, name()))); + return false; + } + + const XsdTerm::Ptr term = m_stateMachines.top().lastTransition(); + if (term->isElement()) { + const XsdElement::Ptr element(term); + + // rememeber the element we process + processedElement = element; + + if (!validateElement(element, hasStateMachine)) + return false; + + } else { + const XsdWildcard::Ptr wildcard(term); + if (wildcard->processContents() != XsdWildcard::Skip) { + XsdElement::Ptr elementDeclaration = elementByName(name()); + if (!elementDeclaration) { + if (hasAttribute(m_xsiTypeName)) { + // This instance document has an element with no definition in the schema + // but an explicitly given type, that is fine according to the spec. + // We will create an element definition manually here and continue the + // normal validation process + elementDeclaration = XsdElement::Ptr(new XsdElement()); + elementDeclaration->setName(name()); + elementDeclaration->setIsAbstract(false); + elementDeclaration->setIsNillable(hasAttribute(m_xsiNilName)); + + const QString type = qNameAttribute(m_xsiTypeName); + const QXmlName typeName = convertToQName(type); + + const SchemaType::Ptr elementType = typeByName(typeName); + if (!elementType) { + error(QtXmlPatterns::tr("specified type %1 is not known to the schema").arg(formatType(m_namePool, typeName))); + return false; + } + elementDeclaration->setType(elementType); + } + } + + if (!elementDeclaration) { + if (wildcard->processContents() == XsdWildcard::Strict) { + error(QtXmlPatterns::tr("declaration for element %1 does not exist").arg(formatKeyword(m_namePool->displayName(name())))); + return false; + } else { + // in this case we put a state machine for the xs:anyType on the statemachine stack, + // so we accept every content of this element + + createAndPushStateMachine(anyType()->contentType()->particle()); + hasStateMachine = true; + } + } else { + if (!validateElement(elementDeclaration, hasStateMachine)) { + if (wildcard->processContents() == XsdWildcard::Strict) { + error(QtXmlPatterns::tr("element %1 contains invalid content").arg(formatKeyword(m_namePool->displayName(name())))); + return false; + } + } + + // rememeber the type of that element node + m_model->setAssignedType(item().toNodeModelIndex(), elementDeclaration->type()); + } + } else { // wildcard process contents type is Skip + // in this case we put a state machine for the xs:anyType on the statemachine stack, + // so we accept every content of this element + + const XsdWildcard::Ptr wildcard(new XsdWildcard()); + wildcard->namespaceConstraint()->setVariety(XsdWildcard::NamespaceConstraint::Any); + wildcard->setProcessContents(XsdWildcard::Skip); + + const XsdParticle::Ptr outerParticle(new XsdParticle()); + outerParticle->setMinimumOccurs(1); + outerParticle->setMaximumOccurs(1); + + const XsdParticle::Ptr innerParticle(new XsdParticle()); + innerParticle->setMinimumOccurs(0); + innerParticle->setMaximumOccursUnbounded(true); + innerParticle->setTerm(wildcard); + + const XsdModelGroup::Ptr outerModelGroup(new XsdModelGroup()); + outerModelGroup->setCompositor(XsdModelGroup::SequenceCompositor); + outerModelGroup->setParticles(XsdParticle::List() << innerParticle); + outerParticle->setTerm(outerModelGroup); + + createAndPushStateMachine(outerParticle); + hasStateMachine = true; + } + } + } + + return true; +} + +void XsdValidatingInstanceReader::createAndPushStateMachine(const XsdParticle::Ptr &particle) +{ + XsdStateMachine stateMachine(m_namePool); + + XsdStateMachineBuilder builder(&stateMachine, m_namePool, XsdStateMachineBuilder::ValidatingMode); + const XsdStateMachine::StateId endState = builder.reset(); + const XsdStateMachine::StateId startState = builder.buildParticle(particle, endState); + builder.addStartState(startState); + +/* + QString fileName = QString("/tmp/foo_%1.dot").arg(m_namePool->displayName(complexType->name(m_namePool))); + QString pngFileName = QString("/tmp/foo_%1.png").arg(m_namePool->displayName(complexType->name(m_namePool))); + QFile file(fileName); + file.open(QIODevice::WriteOnly); + stateMachine.outputGraph(&file, "Hello"); + file.close(); + ::system(QString("dot -Tpng %1 -o%2").arg(fileName).arg(pngFileName).toLatin1().data()); +*/ + + stateMachine = stateMachine.toDFA(); + + m_stateMachines.push(stateMachine); +} + +bool XsdValidatingInstanceReader::validateElement(const XsdElement::Ptr &declaration, bool &hasStateMachine) +{ + // http://www.w3.org/TR/xmlschema11-1/#d0e10998 + + bool isNilled = false; + + // 1 tested already, 'declaration' corresponds D + + // 2 + if (declaration->isAbstract()) { + error(QtXmlPatterns::tr("element %1 is declared as abstract").arg(formatKeyword(declaration->displayName(m_namePool)))); + return false; + } + + // 3 + if (!declaration->isNillable()) { + if (hasAttribute(m_xsiNilName)) { + error(QtXmlPatterns::tr("element %1 is not nillable").arg(formatKeyword(declaration->displayName(m_namePool)))); + return false; // 3.1 + } + } else { + if (hasAttribute(m_xsiNilName)) { + const QString value = attribute(m_xsiNilName); + const Boolean::Ptr nil = Boolean::fromLexical(value); + if (nil->hasError()) { + error(QtXmlPatterns::tr("attribute %1 contains invalid data: %1").arg(formatKeyword(QLatin1String("nil"))).arg(formatData(value))); + return false; + } + + // 3.2.3 + if (nil->as()->value() == true) { + // 3.2.3.1 + if (hasChildElement() || hasChildText()) { + error(QtXmlPatterns::tr("element contains content although it is nillable")); + return false; + } + + // 3.2.3.2 + if (declaration->valueConstraint() && declaration->valueConstraint()->variety() == XsdElement::ValueConstraint::Fixed) { + error(QtXmlPatterns::tr("fixed value constrained not allowed if element is nillable")); + return false; + } + } + + isNilled = nil->as()->value(); + } + } + + SchemaType::Ptr finalElementType = declaration->type(); + + // 4 + if (hasAttribute(m_xsiTypeName)) { + const QString type = qNameAttribute(m_xsiTypeName); + const QXmlName typeName = convertToQName(type); + + const SchemaType::Ptr elementType = typeByName(typeName); + // 4.1 + if (!elementType) { + error(QtXmlPatterns::tr("specified type %1 is not known to the schema").arg(formatType(m_namePool, typeName))); + return false; + } + + // 4.2 + SchemaType::DerivationConstraints constraints = 0; + if (declaration->disallowedSubstitutions() & NamedSchemaComponent::ExtensionConstraint) + constraints |= SchemaType::ExtensionConstraint; + if (declaration->disallowedSubstitutions() & NamedSchemaComponent::RestrictionConstraint) + constraints |= SchemaType::RestrictionConstraint; + + if (!XsdSchemaHelper::isValidlySubstitutable(elementType, declaration->type(), constraints)) { + if (declaration->type()->name(m_namePool) != BuiltinTypes::xsAnyType->name(m_namePool)) { // xs:anyType is a valid substitutable type here + error(QtXmlPatterns::tr("specified type %1 is not validly substitutable with element type %2").arg(formatType(m_namePool, elementType)).arg(formatType(m_namePool, declaration->type()))); + return false; + } + } + + finalElementType = elementType; + } + + if (!validateElementType(declaration, finalElementType, isNilled, hasStateMachine)) + return false; + + return true; +} + +bool XsdValidatingInstanceReader::validateElementType(const XsdElement::Ptr &declaration, const SchemaType::Ptr &type, bool isNilled, bool &hasStateMachine) +{ + // @see http://www.w3.org/TR/xmlschema11-1/#d0e11749 + + // 1 checked already + + // 2 + if (type->isComplexType() && type->isDefinedBySchema()) { + if (XsdComplexType::Ptr(type)->isAbstract()) { + error(QtXmlPatterns::tr("complex type %1 is not allowed to be abstract").arg(formatType(m_namePool, type))); + return false; + } + } + + // 3 + if (type->isSimpleType()) + return validateElementSimpleType(declaration, type, isNilled); // 3.1 + else + return validateElementComplexType(declaration, type, isNilled, hasStateMachine); // 3.2 +} + +bool XsdValidatingInstanceReader::validateElementSimpleType(const XsdElement::Ptr &declaration, const SchemaType::Ptr &type, bool isNilled) +{ + // @see http://www.w3.org/TR/xmlschema11-1/#d0e11749 + + // 3.1.1 + const QSet allowedAttributes(QSet() << m_xsiNilName << m_xsiTypeName << m_xsiSchemaLocationName << m_xsiNoNamespaceSchemaLocationName); + QSet elementAttributes = attributeNames(); + elementAttributes.subtract(allowedAttributes); + if (!elementAttributes.isEmpty()) { + error(QtXmlPatterns::tr("element %1 contains not allowed attributes").arg(formatKeyword(declaration->displayName(m_namePool)))); + return false; + } + + // 3.1.2 + if (hasChildElement()) { + error(QtXmlPatterns::tr("element %1 contains not allowed child element").arg(formatKeyword(declaration->displayName(m_namePool)))); + return false; + } + + // 3.1.3 + if (!isNilled) { + const XsdFacet::Hash facets = XsdTypeChecker::mergedFacetsForType(type, m_context); + + QString actualValue; + if (hasChildText()) { + actualValue = XsdTypeChecker::normalizedValue(text(), facets); + } else { + if (declaration->valueConstraint()) + actualValue = XsdTypeChecker::normalizedValue(declaration->valueConstraint()->value(), facets); + } + + QString errorMsg; + AnySimpleType::Ptr boundType; + + const XsdTypeChecker checker(m_context, namespaceBindings(item().toNodeModelIndex()), sourceLocation()); + if (!checker.isValidString(actualValue, type, errorMsg, &boundType)) { + error(QtXmlPatterns::tr("content of element %1 does not match its type definition: %2").arg(formatKeyword(declaration->displayName(m_namePool))).arg(errorMsg)); + return false; + } + + // additional check + if (declaration->valueConstraint() && declaration->valueConstraint()->variety() == XsdElement::ValueConstraint::Fixed) { + const QString actualConstraintValue = XsdTypeChecker::normalizedValue(declaration->valueConstraint()->value(), facets); + if (!text().isEmpty() && !checker.valuesAreEqual(actualValue, actualConstraintValue, type)) { + error(QtXmlPatterns::tr("content of element %1 does not match defined value constraint").arg(formatKeyword(declaration->displayName(m_namePool)))); + return false; + } + } + } + + // 4 checked in validateElement already + + // rememeber the type of that element node + m_model->setAssignedType(item().toNodeModelIndex(), type); + + const XsdFacet::Hash facets = XsdTypeChecker::mergedFacetsForType(type, m_context); + const QString actualValue = XsdTypeChecker::normalizedValue(text(), facets); + + if (BuiltinTypes::xsID->wxsTypeMatches(type)) { + addIdIdRefBinding(actualValue, declaration); + } + + if (m_idRefsType->wxsTypeMatches(type)) { + const QStringList idRefs = actualValue.split(QLatin1Char(' '), QString::SkipEmptyParts); + for (int i = 0; i < idRefs.count(); ++i) { + m_idRefs.insert(idRefs.at(i)); + } + } else if (BuiltinTypes::xsIDREF->wxsTypeMatches(type)) { + m_idRefs.insert(actualValue); + } + + return true; +} + +static bool hasIDAttributeUse(const XsdAttributeUse::List &uses) +{ + const int count = uses.count(); + for (int i = 0; i < count; ++i) { + if (BuiltinTypes::xsID->wxsTypeMatches(uses.at(i)->attribute()->type())) + return true; + } + + return false; +} + +bool XsdValidatingInstanceReader::validateElementComplexType(const XsdElement::Ptr &declaration, const SchemaType::Ptr &type, bool isNilled, bool &hasStateMachine) +{ + // @see http://www.w3.org/TR/xmlschema11-1/#cvc-complex-type + + // 1 + if (!isNilled) { + XsdComplexType::Ptr complexType; + + if (type->isDefinedBySchema()) { + complexType = XsdComplexType::Ptr(type); + } else { + if (type->name(m_namePool) == BuiltinTypes::xsAnyType->name(m_namePool)) + complexType = anyType(); + } + + if (complexType) { + // 1.1 + if (complexType->contentType()->variety() == XsdComplexType::ContentType::Empty) { + if (hasChildText() || hasChildElement()) { + error(QtXmlPatterns::tr("element %1 contains not allowed child content").arg(formatKeyword(declaration->displayName(m_namePool)))); + return false; + } + } + + // 1.2 + if (complexType->contentType()->variety() == XsdComplexType::ContentType::Simple) { + if (hasChildElement()) { + error(QtXmlPatterns::tr("element %1 contains not allowed child element").arg(formatKeyword(declaration->displayName(m_namePool)))); + return false; + } + + const XsdFacet::Hash facets = XsdTypeChecker::mergedFacetsForType(complexType->contentType()->simpleType(), m_context); + QString actualValue; + if (hasChildText()) { + actualValue = XsdTypeChecker::normalizedValue(text(), facets); + } else { + if (declaration->valueConstraint()) + actualValue = XsdTypeChecker::normalizedValue(declaration->valueConstraint()->value(), facets); + } + + QString errorMsg; + AnySimpleType::Ptr boundType; + const XsdTypeChecker checker(m_context, namespaceBindings(item().toNodeModelIndex()), sourceLocation()); + if (!checker.isValidString(actualValue, complexType->contentType()->simpleType(), errorMsg, &boundType)) { + error(QtXmlPatterns::tr("content of element %1 does not match its type definition: %2").arg(formatKeyword(declaration->displayName(m_namePool))).arg(errorMsg)); + return false; + } + + // additional check + if (declaration->valueConstraint() && declaration->valueConstraint()->variety() == XsdElement::ValueConstraint::Fixed) { + if (!checker.valuesAreEqual(actualValue, declaration->valueConstraint()->value(), boundType)) { + error(QtXmlPatterns::tr("content of element %1 does not match defined value constraint").arg(formatKeyword(declaration->displayName(m_namePool)))); + return false; + } + } + } + + // 1.3 + if (complexType->contentType()->variety() == XsdComplexType::ContentType::ElementOnly) { + if (!text().simplified().isEmpty()) { + error(QtXmlPatterns::tr("element %1 contains not allowed text content").arg(formatKeyword(declaration->displayName(m_namePool)))); + return false; + } + } + + // 1.4 + if (complexType->contentType()->variety() == XsdComplexType::ContentType::ElementOnly || + complexType->contentType()->variety() == XsdComplexType::ContentType::Mixed) { + + if (complexType->contentType()->particle()) { + createAndPushStateMachine(complexType->contentType()->particle()); + hasStateMachine = true; + } + + // additional check + if (complexType->contentType()->variety() == XsdComplexType::ContentType::Mixed) { + if (declaration->valueConstraint() && declaration->valueConstraint()->variety() == XsdElement::ValueConstraint::Fixed) { + if (hasChildElement()) { + error(QtXmlPatterns::tr("element %1 can not contain other elements, as it has a fixed content").arg(formatKeyword(declaration->displayName(m_namePool)))); + return false; + } + + const XsdFacet::Hash facets = XsdTypeChecker::mergedFacetsForType(complexType->contentType()->simpleType(), m_context); + QString actualValue; + if (hasChildText()) { + actualValue = XsdTypeChecker::normalizedValue(text(), facets); + } else { + if (declaration->valueConstraint()) + actualValue = XsdTypeChecker::normalizedValue(declaration->valueConstraint()->value(), facets); + } + + if (actualValue != declaration->valueConstraint()->value()) { + error(QtXmlPatterns::tr("content of element %1 does not match defined value constraint").arg(formatKeyword(declaration->displayName(m_namePool)))); + return false; + } + } + } + } + } + } + + if (type->isDefinedBySchema()) { + const XsdComplexType::Ptr complexType(type); + + // create a lookup hash for faster access + QHash attributeUseHash; + { + const XsdAttributeUse::List attributeUses = complexType->attributeUses(); + for (int i = 0; i < attributeUses.count(); ++i) + attributeUseHash.insert(attributeUses.at(i)->attribute()->name(m_namePool), attributeUses.at(i)); + } + + const QSet attributes(attributeNames()); + + // 3 + QHashIterator usesIt(attributeUseHash); + while (usesIt.hasNext()) { + usesIt.next(); + + if (usesIt.value()->isRequired()) { + if (!attributes.contains(usesIt.key())) { + error(QtXmlPatterns::tr("element %1 is missing required attribute %2").arg(formatKeyword(declaration->displayName(m_namePool))) + .arg(formatKeyword(m_namePool->displayName(usesIt.key())))); + return false; + } + } + } + + bool hasIDAttribute = hasIDAttributeUse(complexType->attributeUses()); + + // 2 + QSetIterator it(attributes); + while (it.hasNext()) { + const QXmlName attributeName = it.next(); + + // skip builtin attributes + if (attributeName == m_xsiNilName || + attributeName == m_xsiTypeName || + attributeName == m_xsiSchemaLocationName || + attributeName == m_xsiNoNamespaceSchemaLocationName) + continue; + + // 2.1 + if (attributeUseHash.contains(attributeName) && (attributeUseHash.value(attributeName)->useType() != XsdAttributeUse::ProhibitedUse)) { + if (!validateAttribute(attributeUseHash.value(attributeName), attribute(attributeName))) + return false; + } else { // 2.2 + if (complexType->attributeWildcard()) { + const XsdWildcard::Ptr wildcard(complexType->attributeWildcard()); + if (!validateAttributeWildcard(attributeName, wildcard)) { + error(QtXmlPatterns::tr("attribute %1 does not match the attribute wildcard").arg(formatKeyword(m_namePool->displayName(attributeName)))); + return false; + } + + if (wildcard->processContents() != XsdWildcard::Skip) { + const XsdAttribute::Ptr attributeDeclaration = attributeByName(attributeName); + + if (!attributeDeclaration) { + if (wildcard->processContents() == XsdWildcard::Strict) { + error(QtXmlPatterns::tr("declaration for attribute %1 does not exist").arg(formatKeyword(m_namePool->displayName(attributeName)))); + return false; + } + } else { + if (BuiltinTypes::xsID->wxsTypeMatches(attributeDeclaration->type())) { + if (hasIDAttribute) { + error(QtXmlPatterns::tr("element %1 contains two attributes of type %2") + .arg(formatKeyword(declaration->displayName(m_namePool))) + .arg(formatKeyword("ID"))); + return false; + } + + hasIDAttribute = true; + } + + if (!validateAttribute(attributeDeclaration, attribute(attributeName))) { + if (wildcard->processContents() == XsdWildcard::Strict) { + error(QtXmlPatterns::tr("attribute %1 contains invalid content").arg(formatKeyword(m_namePool->displayName(attributeName)))); + return false; + } + } + } + } + } else { + error(QtXmlPatterns::tr("element %1 contains unknown attribute %2").arg(formatKeyword(declaration->displayName(m_namePool))) + .arg(formatKeyword(m_namePool->displayName(attributeName)))); + return false; + } + } + } + } + + // 4 + // so what?... + + // 5 + // hmm... + + // 6 + // TODO: check assertions + + // 7 + // TODO: check type table restrictions + + // rememeber the type of that element node + m_model->setAssignedType(item().toNodeModelIndex(), type); + + return true; +} + +bool XsdValidatingInstanceReader::validateAttribute(const XsdAttributeUse::Ptr &declaration, const QString &value) +{ + const AnySimpleType::Ptr attributeType = declaration->attribute()->type(); + const XsdFacet::Hash facets = XsdTypeChecker::mergedFacetsForType(attributeType, m_context); + + const QString actualValue = XsdTypeChecker::normalizedValue(value, facets); + + QString errorMsg; + AnySimpleType::Ptr boundType; + + const QXmlNodeModelIndex index = attributeItem(declaration->attribute()->name(m_namePool)).toNodeModelIndex(); + + const XsdTypeChecker checker(m_context, namespaceBindings(index), sourceLocation()); + if (!checker.isValidString(actualValue, attributeType, errorMsg, &boundType)) { + error(QtXmlPatterns::tr("content of attribute %1 does not match its type definition: %2").arg(formatKeyword(declaration->attribute()->displayName(m_namePool))).arg(errorMsg)); + return false; + } + + // @see http://www.w3.org/TR/xmlschema11-1/#cvc-au + if (declaration->valueConstraint() && declaration->valueConstraint()->variety() == XsdAttributeUse::ValueConstraint::Fixed) { + const QString actualConstraintValue = XsdTypeChecker::normalizedValue(declaration->valueConstraint()->value(), facets); + if (!checker.valuesAreEqual(actualValue, actualConstraintValue, attributeType)) { + error(QtXmlPatterns::tr("content of attribute %1 does not match defined value constraint").arg(formatKeyword(declaration->attribute()->displayName(m_namePool)))); + return false; + } + } + + if (BuiltinTypes::xsID->wxsTypeMatches(declaration->attribute()->type())) { + addIdIdRefBinding(actualValue, declaration->attribute()); + } + + if (m_idRefsType->wxsTypeMatches(declaration->attribute()->type())) { + const QStringList idRefs = actualValue.split(QLatin1Char(' '), QString::SkipEmptyParts); + for (int i = 0; i < idRefs.count(); ++i) + m_idRefs.insert(idRefs.at(i)); + } else if (BuiltinTypes::xsIDREF->wxsTypeMatches(declaration->attribute()->type())) { + m_idRefs.insert(actualValue); + } + + m_model->setAssignedType(index, declaration->attribute()->type()); + m_model->setAssignedAttribute(index, declaration->attribute()); + + return true; +} + +//TODO: merge that with the method above +bool XsdValidatingInstanceReader::validateAttribute(const XsdAttribute::Ptr &declaration, const QString &value) +{ + const AnySimpleType::Ptr attributeType = declaration->type(); + const XsdFacet::Hash facets = XsdTypeChecker::mergedFacetsForType(attributeType, m_context); + + const QString actualValue = XsdTypeChecker::normalizedValue(value, facets); + + QString errorMsg; + AnySimpleType::Ptr boundType; + + const QXmlNodeModelIndex index = attributeItem(declaration->name(m_namePool)).toNodeModelIndex(); + + const XsdTypeChecker checker(m_context, namespaceBindings(index), sourceLocation()); + if (!checker.isValidString(actualValue, attributeType, errorMsg, &boundType)) { + error(QtXmlPatterns::tr("content of attribute %1 does not match its type definition: %2").arg(formatKeyword(declaration->displayName(m_namePool))).arg(errorMsg)); + return false; + } + + // @see http://www.w3.org/TR/xmlschema11-1/#cvc-au + if (declaration->valueConstraint() && declaration->valueConstraint()->variety() == XsdAttribute::ValueConstraint::Fixed) { + const QString actualConstraintValue = XsdTypeChecker::normalizedValue(declaration->valueConstraint()->value(), facets); + if (!checker.valuesAreEqual(actualValue, actualConstraintValue, attributeType)) { + error(QtXmlPatterns::tr("content of attribute %1 does not match defined value constraint").arg(formatKeyword(declaration->displayName(m_namePool)))); + return false; + } + } + + if (BuiltinTypes::xsID->wxsTypeMatches(declaration->type())) { + addIdIdRefBinding(actualValue, declaration); + } + + if (m_idRefsType->wxsTypeMatches(declaration->type())) { + const QStringList idRefs = actualValue.split(QLatin1Char(' '), QString::SkipEmptyParts); + for (int i = 0; i < idRefs.count(); ++i) + m_idRefs.insert(idRefs.at(i)); + } else if (BuiltinTypes::xsIDREF->wxsTypeMatches(declaration->type())) { + m_idRefs.insert(actualValue); + } + + m_model->setAssignedType(index, declaration->type()); + m_model->setAssignedAttribute(index, declaration); + + return true; +} + +bool XsdValidatingInstanceReader::validateAttributeWildcard(const QXmlName &attributeName, const XsdWildcard::Ptr &wildcard) +{ + // @see http://www.w3.org/TR/xmlschema11-1/#cvc-wildcard + + // wildcards using XsdWildcard::absentNamespace, so we have to fix that here + QXmlName name(attributeName); + if (name.namespaceURI() == StandardNamespaces::empty) { + name.setNamespaceURI(m_namePool->allocateNamespace(XsdWildcard::absentNamespace())); + } + + return XsdSchemaHelper::wildcardAllowsExpandedName(name, wildcard, m_namePool); +} + +bool XsdValidatingInstanceReader::validateIdentityConstraint(const XsdElement::Ptr &element, const QXmlItem ¤tItem) +{ + const XsdIdentityConstraint::List constraints = element->identityConstraints(); + + for (int i = 0; i < constraints.count(); ++i) { + const XsdIdentityConstraint::Ptr constraint = constraints.at(i); + + TargetNode::Set targetNodeSet, qualifiedNodeSet; + selectNodeSets(element, currentItem, constraint, targetNodeSet, qualifiedNodeSet); + + if (constraint->category() == XsdIdentityConstraint::Unique) { + if (!validateUniqueIdentityConstraint(element, constraint, qualifiedNodeSet)) + return false; + } else if (constraint->category() == XsdIdentityConstraint::Key) { + if (!validateKeyIdentityConstraint(element, constraint, targetNodeSet, qualifiedNodeSet)) + return false; + } + } + + // we do the keyref check in a separated run to make sure that all keys are available + for (int i = 0; i < constraints.count(); ++i) { + const XsdIdentityConstraint::Ptr constraint = constraints.at(i); + if (constraint->category() == XsdIdentityConstraint::KeyReference) { + TargetNode::Set targetNodeSet, qualifiedNodeSet; + selectNodeSets(element, currentItem, constraint, targetNodeSet, qualifiedNodeSet); + + if (!validateKeyRefIdentityConstraint(element, constraint, qualifiedNodeSet)) + return false; + } + } + + return true; +} + +bool XsdValidatingInstanceReader::validateUniqueIdentityConstraint(const XsdElement::Ptr&, const XsdIdentityConstraint::Ptr &constraint, const TargetNode::Set &qualifiedNodeSet) +{ + // @see http://www.w3.org/TR/xmlschema11-1/#d0e32243 + + // 4.1 + const XsdSchemaSourceLocationReflection reflection(sourceLocation()); + + QSetIterator it(qualifiedNodeSet); + while (it.hasNext()) { + const TargetNode node = it.next(); + QSetIterator innerIt(qualifiedNodeSet); + while (innerIt.hasNext()) { + const TargetNode innerNode = innerIt.next(); + + if (node == innerNode) // do not compare with ourself + continue; + + if (node.fieldsAreEqual(innerNode, m_namePool, m_context, &reflection)) { + error(QtXmlPatterns::tr("non-unique value found for constraint %1").arg(formatKeyword(constraint->displayName(m_namePool)))); + return false; + } + } + } + + m_idcKeys.insert(constraint->name(m_namePool), qualifiedNodeSet); + + return true; +} + +bool XsdValidatingInstanceReader::validateKeyIdentityConstraint(const XsdElement::Ptr &element, const XsdIdentityConstraint::Ptr &constraint, const TargetNode::Set &targetNodeSet, const TargetNode::Set &qualifiedNodeSet) +{ + // @see http://www.w3.org/TR/xmlschema11-1/#d0e32243 + + // 4.2 + const XsdSchemaSourceLocationReflection reflection(sourceLocation()); + + // 4.2.1 + if (targetNodeSet.count() != qualifiedNodeSet.count()) { + error(QtXmlPatterns::tr("key constraint %1 contains absent fields").arg(formatKeyword(constraint->displayName(m_namePool)))); + return false; + } + + // 4.2.2 + if (!validateUniqueIdentityConstraint(element, constraint, qualifiedNodeSet)) + return false; + + // 4.2.3 + QSetIterator it(qualifiedNodeSet); + while (it.hasNext()) { + const TargetNode node = it.next(); + const QVector fieldItems = node.fieldItems(); + for (int i = 0; i < fieldItems.count(); ++i) { + const QXmlNodeModelIndex index = fieldItems.at(i).toNodeModelIndex(); + if (m_model->kind(index) == QXmlNodeModelIndex::Element) { + const XsdElement::Ptr declaration = m_model->assignedElement(index); + if (declaration && declaration->isNillable()) { + error(QtXmlPatterns::tr("key constraint %1 contains references nillable element %2") + .arg(formatKeyword(constraint->displayName(m_namePool))) + .arg(formatKeyword(declaration->displayName(m_namePool)))); + return false; + } + } + } + } + + m_idcKeys.insert(constraint->name(m_namePool), qualifiedNodeSet); + + return true; +} + +bool XsdValidatingInstanceReader::validateKeyRefIdentityConstraint(const XsdElement::Ptr&, const XsdIdentityConstraint::Ptr &constraint, const TargetNode::Set &qualifiedNodeSet) +{ + // @see http://www.w3.org/TR/xmlschema11-1/#d0e32243 + + // 4.3 + const XsdSchemaSourceLocationReflection reflection(sourceLocation()); + + const TargetNode::Set keySet = m_idcKeys.value(constraint->referencedKey()->name(m_namePool)); + + QSetIterator it(qualifiedNodeSet); + while (it.hasNext()) { + const TargetNode node = it.next(); + + bool foundMatching = false; + + QSetIterator keyIt(keySet); + while (keyIt.hasNext()) { + const TargetNode keyNode = keyIt.next(); + + if (node.fieldsAreEqual(keyNode, m_namePool, m_context, &reflection)) { + foundMatching = true; + break; + } + } + + if (!foundMatching) { + error(QtXmlPatterns::tr("no referenced value found for key reference %1").arg(formatKeyword(constraint->displayName(m_namePool)))); + return false; + } + } + + return true; +} + +QXmlQuery XsdValidatingInstanceReader::createXQuery(const QList &namespaceBindings, const QXmlItem &contextNode, const QString &queryString) const +{ + // create a public name pool from our name pool + QXmlNamePool namePool(m_namePool.data()); + + // the QXmlQuery shall work with the same name pool as we do + QXmlQuery query(namePool); + + // add additional namespace bindings + QXmlQueryPrivate *queryPrivate = query.d; + + for (int i = 0; i < namespaceBindings.count(); ++i) { + if (!namespaceBindings.at(i).prefix() == StandardPrefixes::empty) + queryPrivate->addAdditionalNamespaceBinding(namespaceBindings.at(i)); + } + + // set the context node for that query and the query string + query.setFocus(contextNode); + query.setQuery(queryString, m_documentUri); + + return query; +} + +bool XsdValidatingInstanceReader::selectNodeSets(const XsdElement::Ptr&, const QXmlItem ¤tItem, const XsdIdentityConstraint::Ptr &constraint, TargetNode::Set &targetNodeSet, TargetNode::Set &qualifiedNodeSet) +{ + // at first select all target nodes + const XsdXPathExpression::Ptr selector = constraint->selector(); + const XsdXPathExpression::List fields = constraint->fields(); + + QXmlQuery query = createXQuery(selector->namespaceBindings(), currentItem, selector->expression()); + + QXmlResultItems resultItems; + query.evaluateTo(&resultItems); + + // now we iterate over all target nodes and select the fields for each node + QXmlItem item(resultItems.next()); + while (!item.isNull()) { + + TargetNode targetNode(item); + + for (int i = 0; i < fields.count(); ++i) { + const XsdXPathExpression::Ptr field = fields.at(i); + QXmlQuery fieldQuery = createXQuery(field->namespaceBindings(), item, field->expression()); + + QXmlResultItems fieldResultItems; + fieldQuery.evaluateTo(&fieldResultItems); + + // copy result into vetor for better testing... + QVector fieldVector; + QXmlItem fieldItem(fieldResultItems.next()); + while (!fieldItem.isNull()) { + fieldVector.append(fieldItem); + fieldItem = fieldResultItems.next(); + } + + if (fieldVector.count() > 1) { + error(QtXmlPatterns::tr("more than one value found for field %1").arg(formatData(field->expression()))); + return false; + } + + if (fieldVector.count() == 1) { + fieldItem = fieldVector.first(); + + const QXmlNodeModelIndex index = fieldItem.toNodeModelIndex(); + const SchemaType::Ptr type = m_model->assignedType(index); + + bool typeOk = true; + if (type->isComplexType()) { + if (type->isDefinedBySchema()) { + if (XsdComplexType::Ptr(type)->contentType()->variety() != XsdComplexType::ContentType::Simple) + typeOk = false; + } else { + typeOk = false; + } + } + if (!typeOk) { + error(QtXmlPatterns::tr("field %1 has no simple type").arg(formatData(field->expression()))); + return false; + } + + SchemaType::Ptr targetType = type; + QString value = m_model->stringValue(fieldItem.toNodeModelIndex()); + + if (type->isDefinedBySchema()) { + if (type->isSimpleType()) + targetType = XsdSimpleType::Ptr(type)->primitiveType(); + else + targetType = XsdComplexType::Ptr(type)->contentType()->simpleType(); + } else { + if (BuiltinTypes::xsAnySimpleType->name(m_namePool) == type->name(m_namePool)) { + targetType = BuiltinTypes::xsString; + value = QLatin1String("___anySimpleType_value"); + } + } + + // if it is xs:QName derived type, we normalize the name content + // and do a string comparison + if (BuiltinTypes::xsQName->wxsTypeMatches(type)) { + targetType = BuiltinTypes::xsString; + + const QXmlName qName = convertToQName(value.trimmed()); + value = QString::fromLatin1("%1:%2").arg(m_namePool->stringForNamespace(qName.namespaceURI())).arg(m_namePool->stringForLocalName(qName.localName())); + } + + targetNode.addField(fieldItem, value, targetType); + } else { + // we add an empty entry here, that makes comparison easier later on + targetNode.addField(QXmlItem(), QString(), SchemaType::Ptr()); + } + } + + targetNodeSet.insert(targetNode); + + item = resultItems.next(); + } + + // copy all items from target node set to qualified node set, that have no empty fields + QSetIterator it(targetNodeSet); + while (it.hasNext()) { + const TargetNode node = it.next(); + if (node.emptyFieldsCount() == 0) + qualifiedNodeSet.insert(node); + } + + return true; +} + +XsdElement::Ptr XsdValidatingInstanceReader::elementByName(const QXmlName &name) const +{ + return m_schema->element(name); +} + +XsdAttribute::Ptr XsdValidatingInstanceReader::attributeByName(const QXmlName &name) const +{ + return m_schema->attribute(name); +} + +SchemaType::Ptr XsdValidatingInstanceReader::typeByName(const QXmlName &name) const +{ + const SchemaType::Ptr type = m_schema->type(name); + if (type) + return type; + + return m_context->schemaTypeFactory()->createSchemaType(name); +} + +void XsdValidatingInstanceReader::addIdIdRefBinding(const QString &id, const NamedSchemaComponent::Ptr &binding) +{ + if (!m_model->idIdRefBindings(id).isEmpty()) { + error(QtXmlPatterns::tr("ID value '%1' is not unique").arg(formatKeyword(id))); + return; + } + + m_model->addIdIdRefBinding(id, binding); +} + +QString XsdValidatingInstanceReader::qNameAttribute(const QXmlName &attributeName) +{ + const QString value = attribute(attributeName).simplified(); + if (!XPathHelper::isQName(value)) { + error(QtXmlPatterns::tr("'%1' attribute contains invalid QName content: %2").arg(m_namePool->displayName(attributeName)).arg(formatData(value))); + return QString(); + } else { + return value; + } +} + +XsdComplexType::Ptr XsdValidatingInstanceReader::anyType() +{ + if (m_anyType) + return m_anyType; + + const XsdWildcard::Ptr wildcard(new XsdWildcard()); + wildcard->namespaceConstraint()->setVariety(XsdWildcard::NamespaceConstraint::Any); + wildcard->setProcessContents(XsdWildcard::Lax); + + const XsdParticle::Ptr outerParticle(new XsdParticle()); + outerParticle->setMinimumOccurs(1); + outerParticle->setMaximumOccurs(1); + + const XsdParticle::Ptr innerParticle(new XsdParticle()); + innerParticle->setMinimumOccurs(0); + innerParticle->setMaximumOccursUnbounded(true); + innerParticle->setTerm(wildcard); + + const XsdModelGroup::Ptr outerModelGroup(new XsdModelGroup()); + outerModelGroup->setCompositor(XsdModelGroup::SequenceCompositor); + outerModelGroup->setParticles(XsdParticle::List() << innerParticle); + outerParticle->setTerm(outerModelGroup); + + m_anyType = XsdComplexType::Ptr(new XsdComplexType()); + m_anyType->setName(BuiltinTypes::xsAnyType->name(m_namePool)); + m_anyType->setDerivationMethod(XsdComplexType::DerivationRestriction); + m_anyType->contentType()->setVariety(XsdComplexType::ContentType::Mixed); + m_anyType->contentType()->setParticle(outerParticle); + m_anyType->setAttributeWildcard(wildcard); + m_anyType->setIsAbstract(false); + + return m_anyType; +} + +QT_END_NAMESPACE diff --git a/src/xmlpatterns/schema/qxsdvalidatinginstancereader_p.h b/src/xmlpatterns/schema/qxsdvalidatinginstancereader_p.h new file mode 100644 index 0000000..799ab44 --- /dev/null +++ b/src/xmlpatterns/schema/qxsdvalidatinginstancereader_p.h @@ -0,0 +1,266 @@ +/**************************************************************************** +** +** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the $MODULE$ of the Qt Toolkit. +** +** $TROLLTECH_DUAL_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_XsdValidatingInstanceReader_H +#define Patternist_XsdValidatingInstanceReader_H + +#include "qxsdidchelper_p.h" +#include "qxsdinstancereader_p.h" +#include "qxsdstatemachine_p.h" +#include "qxsdvalidatedxmlnodemodel_p.h" + +#include + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +class QXmlQuery; + +namespace QPatternist +{ + /** + * @short The validating schema instance reader. + * + * This class reads in a xml instance document from a QAbstractXmlNodeModel and + * validates it against a given xml schema. + * + * @ingroup Patternist_schema + * @author Tobias Koenig + */ + class XsdValidatingInstanceReader : public XsdInstanceReader + { + public: + typedef QExplicitlySharedDataPointer Ptr; + + /** + * Creates a new validating instance reader that reads the data from + * the given @p model. + * + * @param model The model the data shall be read from. + * @param documentUri The uri of the document the model is from. + * @param context The context that is used to report errors etc. + */ + XsdValidatingInstanceReader(const XsdValidatedXmlNodeModel *model, const QUrl &documentUri, const XsdSchemaContext::Ptr &context); + + /** + * Adds a new @p schema to the pool of schemas that shall be used + * for validation. + * The schema is located at the given @p url. + */ + void addSchema(const XsdSchema::Ptr &schema, const QUrl &url); + + /** + * Reads and validates the instance document. + */ + bool read(); + + private: + /** + * Loads a schema with the given @p targetNamespace from the given @p location + * and adds it to the pool of schemas that are used for validation. + * + * This method is used to load schemas defined in the xsi:schemaLocation or + * xsi:noNamespaceSchemaLocation attributes in the instance document. + */ + bool loadSchema(const QString &targetNamespace, const QUrl &location); + + /** + * Reports an error via the report context. + */ + void error(const QString &msg) const; + + /** + * Validates the current element tag of the instance document. + * + * @param hasStateMachine Used to remember whether this element represents the start tag + * of a complex type and therefor pushes a new state machine on the stack. + * @param element Used to remember which element has been validated in this step. + */ + bool validate(bool &hasStateMachine, XsdElement::Ptr &element); + + /** + * Validates the current tag of the instance document against the given element @p declaration. + * + * @param declaration The element declaration to validate against. + * @param hasStateMachine Used to remember whether this element represents the start tag + * of a complex type and therefor pushes a new state machine on the stack. + */ + bool validateElement(const XsdElement::Ptr &declaration, bool &hasStateMachine); + + /** + * Validates the current tag of the instance document against the given @p type of the element @p declaration. + * + * @param declaration The element declaration to validate against. + * @param type The type to validate against. + * @param isNilled Defines whether the element is nilled by the instance document. + * @param hasStateMachine Used to remember whether this element represents the start tag + * of a complex type and therefor pushes a new state machine on the stack. + * + * @note The @p type can differ from the element @p declaration type if the instance document has defined + * it via xsi:type attribute. + */ + bool validateElementType(const XsdElement::Ptr &declaration, const SchemaType::Ptr &type, bool isNilled, bool &hasStateMachine); + + /** + * Validates the current tag of the instance document against the given simple @p type of the element @p declaration. + * + * @param declaration The element declaration to validate against. + * @param type The type to validate against. + * @param isNilled Defines whether the element is nilled by the instance document. + * + * @note The @p type can differ from the element @p declaration type if the instance document has defined + * it via xsi:type attribute. + */ + bool validateElementSimpleType(const XsdElement::Ptr &declaration, const SchemaType::Ptr &type, bool isNilled); + + /** + * Validates the current tag of the instance document against the given complex @p type of the element @p declaration. + * + * @param declaration The element declaration to validate against. + * @param type The type to validate against. + * @param isNilled Defines whether the element is nilled by the instance document. + * @param hasStateMachine Used to remember whether this element represents the start tag + * of a complex type and therefor pushes a new state machine on the stack. + * + * @note The @p type can differ from the element @p declaration type if the instance document has defined + * it via xsi:type attribute. + */ + bool validateElementComplexType(const XsdElement::Ptr &declaration, const SchemaType::Ptr &type, bool isNilled, bool &hasStateMachine); + + /** + * Validates the given @p value against the attribute use @p declaration. + */ + bool validateAttribute(const XsdAttributeUse::Ptr &declaration, const QString &value); + + /** + * Validates the given @p value against the attribute @p declaration. + */ + bool validateAttribute(const XsdAttribute::Ptr &declaration, const QString &value); + + /** + * Validates the given @p attributeName against the @p wildcard. + */ + bool validateAttributeWildcard(const QXmlName &attributeName, const XsdWildcard::Ptr &wildcard); + + /** + * Validates the identity constraints of an @p element. + */ + bool validateIdentityConstraint(const XsdElement::Ptr &element, const QXmlItem ¤tItem); + + /** + * Validates the unique identity @p constraint of the @p element. + */ + bool validateUniqueIdentityConstraint(const XsdElement::Ptr &element, const XsdIdentityConstraint::Ptr &constraint, const TargetNode::Set &qualifiedNodeSet); + + /** + * Validates the key identity @p constraint of the @p element. + */ + bool validateKeyIdentityConstraint(const XsdElement::Ptr &element, const XsdIdentityConstraint::Ptr &constraint, const TargetNode::Set &targetNodeSet, const TargetNode::Set &qualifiedNodeSet); + + /** + * Validates the keyref identity @p constraint of the @p element. + */ + bool validateKeyRefIdentityConstraint(const XsdElement::Ptr &element, const XsdIdentityConstraint::Ptr &constraint, const TargetNode::Set &qualifiedNodeSet); + + /** + * Selects two sets of nodes that match the given identity @p constraint. + * + * @param element The element the identity constraint belongs to. + * @param currentItem The current element that will be used as focus for the XQuery. + * @param constraint The constraint (selector and fields) that describe the two sets. + * @param targetNodeSet The target node set as defined by the schema specification. + * @param qualifiedNodeSet The qualified node set as defined by the schema specification. + */ + bool selectNodeSets(const XsdElement::Ptr &element, const QXmlItem ¤tItem, const XsdIdentityConstraint::Ptr &constraint, TargetNode::Set &targetNodeSet, TargetNode::Set &qualifiedNodeSet); + + /** + * Creates an QXmlQuery object with the defined @p namespaceBindings that has the @p contextNode as focus + * and will execute @p query. + */ + QXmlQuery createXQuery(const QList &namespaceBindings, const QXmlItem &contextNode, const QString &query) const; + + /** + * Returns the element declaration with the given @p name from the pool of all schemas. + */ + XsdElement::Ptr elementByName(const QXmlName &name) const; + + /** + * Returns the attribute declaration with the given @p name from the pool of all schemas. + */ + XsdAttribute::Ptr attributeByName(const QXmlName &name) const; + + /** + * Returns the type declaration with the given @p name from the pool of all schemas. + */ + SchemaType::Ptr typeByName(const QXmlName &name) const; + + /** + * Adds the ID/IDREF binding to the validated model and checks for duplicates. + */ + void addIdIdRefBinding(const QString &id, const NamedSchemaComponent::Ptr &binding); + + /** + * Helper method that reads an attribute of type xs:QName and does + * syntax checking. + */ + QString qNameAttribute(const QXmlName &attributeName); + + /** + * Returns the xs:anyType that is used to build up the state machine. + * We need that as the BuiltinTypes::xsAnyType is not a XsdComplexType. + */ + XsdComplexType::Ptr anyType(); + + /** + * Helper method that creates a state machine for the given @p particle + * and pushes it on the state machine stack. + */ + void createAndPushStateMachine(const XsdParticle::Ptr &particle); + + typedef QHash MergedSchemas; + typedef QHashIterator MergedSchemasIterator; + + XsdValidatedXmlNodeModel::Ptr m_model; + MergedSchemas m_mergedSchemas; + XsdSchema::Ptr m_schema; + const NamePool::Ptr m_namePool; + const QXmlName m_xsiNilName; + const QXmlName m_xsiTypeName; + const QXmlName m_xsiSchemaLocationName; + const QXmlName m_xsiNoNamespaceSchemaLocationName; + + QStack > m_stateMachines; + QUrl m_documentUri; + XsdComplexType::Ptr m_anyType; + QSet m_processedNamespaces; + QSet m_processedSchemaLocations; + QSet m_idRefs; + QHash m_idcKeys; + SchemaType::Ptr m_idRefsType; + }; +} + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif diff --git a/src/xmlpatterns/schema/qxsdwildcard.cpp b/src/xmlpatterns/schema/qxsdwildcard.cpp new file mode 100644 index 0000000..6efb996 --- /dev/null +++ b/src/xmlpatterns/schema/qxsdwildcard.cpp @@ -0,0 +1,85 @@ +/**************************************************************************** +** +** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the $MODULE$ of the Qt Toolkit. +** +** $TROLLTECH_DUAL_LICENSE$ +** +****************************************************************************/ + +#include "qxsdwildcard_p.h" + +QT_BEGIN_NAMESPACE + +using namespace QPatternist; + +QString XsdWildcard::absentNamespace() +{ + return QLatin1String("__ns_absent"); +} + +void XsdWildcard::NamespaceConstraint::setVariety(Variety variety) +{ + m_variety = variety; +} + +XsdWildcard::NamespaceConstraint::Variety XsdWildcard::NamespaceConstraint::variety() const +{ + return m_variety; +} + +void XsdWildcard::NamespaceConstraint::setNamespaces(const QSet &namespaces) +{ + m_namespaces = namespaces; +} + +QSet XsdWildcard::NamespaceConstraint::namespaces() const +{ + return m_namespaces; +} + +void XsdWildcard::NamespaceConstraint::setDisallowedNames(const QSet &names) +{ + m_disallowedNames = names; +} + +QSet XsdWildcard::NamespaceConstraint::disallowedNames() const +{ + return m_disallowedNames; +} + +XsdWildcard::XsdWildcard() + : m_namespaceConstraint(new NamespaceConstraint()) + , m_processContents(Strict) +{ + m_namespaceConstraint->setVariety(NamespaceConstraint::Any); +} + +bool XsdWildcard::isWildcard() const +{ + return true; +} + +void XsdWildcard::setNamespaceConstraint(const NamespaceConstraint::Ptr &namespaceConstraint) +{ + m_namespaceConstraint = namespaceConstraint; +} + +XsdWildcard::NamespaceConstraint::Ptr XsdWildcard::namespaceConstraint() const +{ + return m_namespaceConstraint; +} + +void XsdWildcard::setProcessContents(ProcessContents contents) +{ + m_processContents = contents; +} + +XsdWildcard::ProcessContents XsdWildcard::processContents() const +{ + return m_processContents; +} + +QT_END_NAMESPACE diff --git a/src/xmlpatterns/schema/qxsdwildcard_p.h b/src/xmlpatterns/schema/qxsdwildcard_p.h new file mode 100644 index 0000000..8fbecb3 --- /dev/null +++ b/src/xmlpatterns/schema/qxsdwildcard_p.h @@ -0,0 +1,169 @@ +/**************************************************************************** +** +** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the $MODULE$ of the Qt Toolkit. +** +** $TROLLTECH_DUAL_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_XsdWildcard_H +#define Patternist_XsdWildcard_H + +#include "qxsdterm_p.h" + +#include + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +namespace QPatternist +{ + /** + * @short Represents a XSD wildcard object. + * + * This class represents the wildcard object of a XML schema as described + * here. + * + * It contains information from either an any object or an anyAttribute object. + * + * @see XML Schema API reference + * @ingroup Patternist_schema + * @author Tobias Koenig + */ + class XsdWildcard : public XsdTerm + { + public: + typedef QExplicitlySharedDataPointer Ptr; + + /** + * Defines the absent namespace that is used in wildcards. + */ + static QString absentNamespace(); + + /** + * Describes the namespace constraint of the wildcard. + */ + class NamespaceConstraint : public QSharedData + { + public: + typedef QExplicitlySharedDataPointer Ptr; + + /** + * Describes the variety of the namespace constraint. + * + * @see Variety Definition + */ + enum Variety + { + Any, ///< Any namespace is allowed. + Enumeration, ///< Namespaces in the namespaces set are allowed. + Not ///< Namespaces in the namespaces set are not allowed. + }; + + /** + * Sets the @p variety of the namespace constraint. + * + * @see Variety Definition + */ + void setVariety(Variety variety); + + /** + * Returns the variety of the namespace constraint. + */ + Variety variety() const; + + /** + * Sets the set of @p namespaces of the namespace constraint. + */ + void setNamespaces(const QSet &namespaces); + + /** + * Returns the set of namespaces of the namespace constraint. + */ + QSet namespaces() const; + + /** + * Sets the set of disallowed @p names of the namespace constraint. + */ + void setDisallowedNames(const QSet &names); + + /** + * Returns the set of disallowed names of the namespace constraint. + */ + QSet disallowedNames() const; + + private: + Variety m_variety; + QSet m_namespaces; + QSet m_disallowedNames; + }; + + /** + * Describes the type of content processing of the wildcard. + */ + enum ProcessContents + { + Strict, ///< There must be a top-level declaration for the item available, or the item must have an xsi:type, and the item must be valid as appropriate. + Lax, ///< If the item has a uniquely determined declaration available, it must be valid with respect to that definition. + Skip ///< No constraints at all: the item must simply be well-formed XML. + }; + + /** + * Creates a new wildcard object. + */ + XsdWildcard(); + + /** + * Returns always @c true, used to avoid dynamic casts. + */ + virtual bool isWildcard() const; + + /** + * Sets the namespace @p constraint of the wildcard. + * + * @see Namespace Constraint Definition + */ + void setNamespaceConstraint(const NamespaceConstraint::Ptr &constraint); + + /** + * Returns the namespace constraint of the wildcard. + */ + NamespaceConstraint::Ptr namespaceConstraint() const; + + /** + * Sets the process @p contents of the wildcard. + * + * @see Process Contents Definition + */ + void setProcessContents(ProcessContents contents); + + /** + * Returns the process contents of the wildcard. + */ + ProcessContents processContents() const; + + private: + NamespaceConstraint::Ptr m_namespaceConstraint; + ProcessContents m_processContents; + }; +} + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif diff --git a/src/xmlpatterns/schema/qxsdxpathexpression.cpp b/src/xmlpatterns/schema/qxsdxpathexpression.cpp new file mode 100644 index 0000000..ba9d0a4 --- /dev/null +++ b/src/xmlpatterns/schema/qxsdxpathexpression.cpp @@ -0,0 +1,58 @@ +/**************************************************************************** +** +** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the $MODULE$ of the Qt Toolkit. +** +** $TROLLTECH_DUAL_LICENSE$ +** +****************************************************************************/ + +#include "qxsdxpathexpression_p.h" + +QT_BEGIN_NAMESPACE + +using namespace QPatternist; + +void XsdXPathExpression::setNamespaceBindings(const QList &set) +{ + m_namespaceBindings = set; +} + +QList XsdXPathExpression::namespaceBindings() const +{ + return m_namespaceBindings; +} + +void XsdXPathExpression::setDefaultNamespace(const AnyURI::Ptr &defaultNs) +{ + m_defaultNamespace = defaultNs; +} + +AnyURI::Ptr XsdXPathExpression::defaultNamespace() const +{ + return m_defaultNamespace; +} + +void XsdXPathExpression::setBaseURI(const AnyURI::Ptr &uri) +{ + m_baseURI = uri; +} + +AnyURI::Ptr XsdXPathExpression::baseURI() const +{ + return m_baseURI; +} + +void XsdXPathExpression::setExpression(const QString &expression) +{ + m_expression = expression; +} + +QString XsdXPathExpression::expression() const +{ + return m_expression; +} + +QT_END_NAMESPACE diff --git a/src/xmlpatterns/schema/qxsdxpathexpression_p.h b/src/xmlpatterns/schema/qxsdxpathexpression_p.h new file mode 100644 index 0000000..e57f7b7 --- /dev/null +++ b/src/xmlpatterns/schema/qxsdxpathexpression_p.h @@ -0,0 +1,113 @@ +/**************************************************************************** +** +** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the $MODULE$ of the Qt Toolkit. +** +** $TROLLTECH_DUAL_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_XsdXPathExpression_H +#define Patternist_XsdXPathExpression_H + +#include "qanyuri_p.h" +#include "qnamedschemacomponent_p.h" +#include "qxsdannotated_p.h" + +#include + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +namespace QPatternist +{ + /** + * @short Represents a XSD assertion object. + * + * @ingroup Patternist_schema + * @author Tobias Koenig + * @see XPathExpression Definition + */ + class XsdXPathExpression : public NamedSchemaComponent, public XsdAnnotated + { + public: + typedef QExplicitlySharedDataPointer Ptr; + typedef QList List; + + /** + * Sets the list of namespace @p bindings of the XPath expression. + * + * @see Namespace Bindings Definition + * + * @note We can't use a QSet here, as the hash method does not take the prefix + * in account, so we loose entries. + */ + void setNamespaceBindings(const QList &bindings); + + /** + * Returns the list of namespace bindings of the XPath expression. + */ + QList namespaceBindings() const; + + /** + * Sets the default namespace of the XPath expression. + * + * @see Default Namespace Definition + */ + void setDefaultNamespace(const AnyURI::Ptr &defaultNamespace); + + /** + * Returns the default namespace of the XPath expression. + */ + AnyURI::Ptr defaultNamespace() const; + + /** + * Sets the base @p uri of the XPath expression. + * + * @see Base URI Definition + */ + void setBaseURI(const AnyURI::Ptr &uri); + + /** + * Returns the base uri of the XPath expression. + */ + AnyURI::Ptr baseURI() const; + + /** + * Sets the @p expression string of the XPath expression. + * + * @see Expression Definition + */ + void setExpression(const QString &expression); + + /** + * Returns the expression string of the XPath expression. + */ + QString expression() const; + + private: + QList m_namespaceBindings; + AnyURI::Ptr m_defaultNamespace; + AnyURI::Ptr m_baseURI; + QString m_expression; + }; +} + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif diff --git a/src/xmlpatterns/schema/schema.pri b/src/xmlpatterns/schema/schema.pri new file mode 100644 index 0000000..b00d64b --- /dev/null +++ b/src/xmlpatterns/schema/schema.pri @@ -0,0 +1,93 @@ +HEADERS += $$PWD/qnamespacesupport_p.h \ + $$PWD/qxsdalternative_p.h \ + $$PWD/qxsdannotated_p.h \ + $$PWD/qxsdannotation_p.h \ + $$PWD/qxsdapplicationinformation_p.h \ + $$PWD/qxsdassertion_p.h \ + $$PWD/qxsdattribute_p.h \ + $$PWD/qxsdattributereference_p.h \ + $$PWD/qxsdattributeterm_p.h \ + $$PWD/qxsdattributeuse_p.h \ + $$PWD/qxsdattributegroup_p.h \ + $$PWD/qxsdcomplextype_p.h \ + $$PWD/qxsddocumentation_p.h \ + $$PWD/qxsdelement_p.h \ + $$PWD/qxsdfacet_p.h \ + $$PWD/qxsdidcache_p.h \ + $$PWD/qxsdidchelper_p.h \ + $$PWD/qxsdidentityconstraint_p.h \ + $$PWD/qxsdinstancereader_p.h \ + $$PWD/qxsdmodelgroup_p.h \ + $$PWD/qxsdnotation_p.h \ + $$PWD/qxsdparticle_p.h \ + $$PWD/qxsdparticlechecker_p.h \ + $$PWD/qxsdreference_p.h \ + $$PWD/qxsdsimpletype_p.h \ + $$PWD/qxsdschema_p.h \ + $$PWD/qxsdschemachecker_p.h \ + $$PWD/qxsdschemacontext_p.h \ + $$PWD/qxsdschemadebugger_p.h \ + $$PWD/qxsdschemahelper_p.h \ + $$PWD/qxsdschemamerger_p.h \ + $$PWD/qxsdschemaparser_p.h \ + $$PWD/qxsdschemaparsercontext_p.h \ + $$PWD/qxsdschemaresolver_p.h \ + $$PWD/qxsdschematoken_p.h \ + $$PWD/qxsdschematypesfactory_p.h \ + $$PWD/qxsdstatemachine_p.h \ + $$PWD/qxsdstatemachinebuilder_p.h \ + $$PWD/qxsdterm_p.h \ + $$PWD/qxsdtypechecker_p.h \ + $$PWD/qxsduserschematype_p.h \ + $$PWD/qxsdvalidatedxmlnodemodel_p.h \ + $$PWD/qxsdvalidatinginstancereader_p.h \ + $$PWD/qxsdwildcard_p.h \ + $$PWD/qxsdxpathexpression_p.h + +SOURCES += $$PWD/qnamespacesupport.cpp \ + $$PWD/qxsdalternative.cpp \ + $$PWD/qxsdannotated.cpp \ + $$PWD/qxsdannotation.cpp \ + $$PWD/qxsdapplicationinformation.cpp \ + $$PWD/qxsdassertion.cpp \ + $$PWD/qxsdattribute.cpp \ + $$PWD/qxsdattributereference.cpp \ + $$PWD/qxsdattributeterm.cpp \ + $$PWD/qxsdattributeuse.cpp \ + $$PWD/qxsdattributegroup.cpp \ + $$PWD/qxsdcomplextype.cpp \ + $$PWD/qxsddocumentation.cpp \ + $$PWD/qxsdelement.cpp \ + $$PWD/qxsdfacet.cpp \ + $$PWD/qxsdidcache.cpp \ + $$PWD/qxsdidchelper.cpp \ + $$PWD/qxsdidentityconstraint.cpp \ + $$PWD/qxsdinstancereader.cpp \ + $$PWD/qxsdmodelgroup.cpp \ + $$PWD/qxsdnotation.cpp \ + $$PWD/qxsdparticle.cpp \ + $$PWD/qxsdparticlechecker.cpp \ + $$PWD/qxsdreference.cpp \ + $$PWD/qxsdsimpletype.cpp \ + $$PWD/qxsdschema.cpp \ + $$PWD/qxsdschemachecker.cpp \ + $$PWD/qxsdschemachecker_setup.cpp \ + $$PWD/qxsdschemacontext.cpp \ + $$PWD/qxsdschemadebugger.cpp \ + $$PWD/qxsdschemahelper.cpp \ + $$PWD/qxsdschemamerger.cpp \ + $$PWD/qxsdschemaparser.cpp \ + $$PWD/qxsdschemaparser_setup.cpp \ + $$PWD/qxsdschemaparsercontext.cpp \ + $$PWD/qxsdschemaresolver.cpp \ + $$PWD/qxsdschematoken.cpp \ + $$PWD/qxsdschematypesfactory.cpp \ + $$PWD/qxsdstatemachinebuilder.cpp \ + $$PWD/qxsdterm.cpp \ + $$PWD/qxsdtypechecker.cpp \ + $$PWD/qxsdwildcard.cpp \ + $$PWD/qxsdvalidatedxmlnodemodel.cpp \ + $$PWD/qxsdvalidatinginstancereader.cpp \ + $$PWD/qxsdxpathexpression.cpp + +RESOURCES += $$PWD/builtinschemas.qrc diff --git a/src/xmlpatterns/schema/schemas/xml.xsd b/src/xmlpatterns/schema/schemas/xml.xsd new file mode 100644 index 0000000..eeb9db5 --- /dev/null +++ b/src/xmlpatterns/schema/schemas/xml.xsd @@ -0,0 +1,145 @@ + + + + + + See http://www.w3.org/XML/1998/namespace.html and + http://www.w3.org/TR/REC-xml for information about this namespace. + + This schema document describes the XML namespace, in a form + suitable for import by other schema documents. + + Note that local names in this namespace are intended to be defined + only by the World Wide Web Consortium or its subgroups. The + following names are currently defined in this namespace and should + not be used with conflicting semantics by any Working Group, + specification, or document instance: + + base (as an attribute name): denotes an attribute whose value + provides a URI to be used as the base for interpreting any + relative URIs in the scope of the element on which it + appears; its value is inherited. This name is reserved + by virtue of its definition in the XML Base specification. + + id (as an attribute name): denotes an attribute whose value + should be interpreted as if declared to be of type ID. + This name is reserved by virtue of its definition in the + xml:id specification. + + lang (as an attribute name): denotes an attribute whose value + is a language code for the natural language of the content of + any element; its value is inherited. This name is reserved + by virtue of its definition in the XML specification. + + space (as an attribute name): denotes an attribute whose + value is a keyword indicating what whitespace processing + discipline is intended for the content of the element; its + value is inherited. This name is reserved by virtue of its + definition in the XML specification. + + Father (in any context at all): denotes Jon Bosak, the chair of + the original XML Working Group. This name is reserved by + the following decision of the W3C XML Plenary and + XML Coordination groups: + + In appreciation for his vision, leadership and dedication + the W3C XML Plenary on this 10th day of February, 2000 + reserves for Jon Bosak in perpetuity the XML name + xml:Father + + + + + This schema defines attributes and an attribute group + suitable for use by + schemas wishing to allow xml:base, xml:lang, xml:space or xml:id + attributes on elements they define. + + To enable this, such a schema must import this schema + for the XML namespace, e.g. as follows: + <schema . . .> + . . . + <import namespace="http://www.w3.org/XML/1998/namespace" + schemaLocation="http://www.w3.org/2001/xml.xsd"/> + + Subsequently, qualified reference to any of the attributes + or the group defined below will have the desired effect, e.g. + + <type . . .> + . . . + <attributeGroup ref="xml:specialAttrs"/> + + will define a type which will schema-validate an instance + element with any of those attributes + + + + In keeping with the XML Schema WG's standard versioning + policy, this schema document will persist at + http://www.w3.org/2007/08/xml.xsd. + At the date of issue it can also be found at + http://www.w3.org/2001/xml.xsd. + The schema document at that URI may however change in the future, + in order to remain compatible with the latest version of XML Schema + itself, or with the XML namespace itself. In other words, if the XML + Schema or XML namespaces change, the version of this document at + http://www.w3.org/2001/xml.xsd will change + accordingly; the version at + http://www.w3.org/2007/08/xml.xsd will not change. + + + + + + Attempting to install the relevant ISO 2- and 3-letter + codes as the enumerated possible values is probably never + going to be a realistic possibility. See + RFC 3066 at http://www.ietf.org/rfc/rfc3066.txt and the IANA registry + at http://www.iana.org/assignments/lang-tag-apps.htm for + further information. + + The union allows for the 'un-declaration' of xml:lang with + the empty string. + + + + + + + + + + + + + + + + + + + + + + + + See http://www.w3.org/TR/xmlbase/ for + information about this attribute. + + + + + + See http://www.w3.org/TR/xml-id/ for + information about this attribute. + + + + + + + + + + + diff --git a/src/xmlpatterns/schema/tokens.xml b/src/xmlpatterns/schema/tokens.xml new file mode 100644 index 0000000..7ec9752 --- /dev/null +++ b/src/xmlpatterns/schema/tokens.xml @@ -0,0 +1,125 @@ + + + + abstract + all + alternative + annotation + any + anyAttribute + appinfo + appliesToEmpty + assert + assertion + attribute + attributeFormDefault + attributeGroup + base + block + blockDefault + choice + collapse + complexContent + complexType + default + defaultAttributes + defaultAttributesApply + defaultOpenContent + documentation + element + elementFormDefault + enumeration + extension + field + final + finalDefault + fixed + form + fractionDigits + group + id + import + include + itemType + key + keyref + length + list + maxExclusive + maxInclusive + maxLength + maxOccurs + memberTypes + minExclusive + minInclusive + minLength + minOccurs + mixed + mode + name + namespace + nillable + notation + notNamespace + notQName + openContent + override + preserve + pattern + processContents + public + redefine + ref + refer + replace + restriction + schema + schemaLocation + selector + sequence + simpleContent + simpleType + source + substitutionGroup + system + targetNamespace + test + totalDigits + type + union + unique + use + value + version + whiteSpace + xpath + xpathDefaultNamespace + xml:lang + http://www.w3.org/2001/XMLSchema + + + + + /**************************************************************************** +** +** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the $MODULE$ of the Qt Toolkit. +** +** $TROLLTECH_DUAL_LICENSE$ +** +****************************************************************************/ + + + + + + diff --git a/src/xmlpatterns/type/qanysimpletype.cpp b/src/xmlpatterns/type/qanysimpletype.cpp index c685d54..81120a7 100644 --- a/src/xmlpatterns/type/qanysimpletype.cpp +++ b/src/xmlpatterns/type/qanysimpletype.cpp @@ -80,4 +80,14 @@ SchemaType::DerivationMethod AnySimpleType::derivationMethod() const return DerivationRestriction; } +bool AnySimpleType::isSimpleType() const +{ + return true; +} + +bool AnySimpleType::isComplexType() const +{ + return false; +} + QT_END_NAMESPACE diff --git a/src/xmlpatterns/type/qanysimpletype_p.h b/src/xmlpatterns/type/qanysimpletype_p.h index b91c7d0..ebd4b5f 100644 --- a/src/xmlpatterns/type/qanysimpletype_p.h +++ b/src/xmlpatterns/type/qanysimpletype_p.h @@ -73,6 +73,8 @@ namespace QPatternist class AnySimpleType : public AnyType { public: + typedef QExplicitlySharedDataPointer Ptr; + typedef QList List; friend class BuiltinTypes; virtual ~AnySimpleType(); @@ -105,6 +107,16 @@ namespace QPatternist */ virtual SchemaType::DerivationMethod derivationMethod() const; + /** + * Always returns @c true. + */ + virtual bool isSimpleType() const; + + /** + * Always returns @c false. + */ + virtual bool isComplexType() const; + protected: AnySimpleType(); diff --git a/src/xmlpatterns/type/qanytype.cpp b/src/xmlpatterns/type/qanytype.cpp index 95ad2b3..19f029f 100644 --- a/src/xmlpatterns/type/qanytype.cpp +++ b/src/xmlpatterns/type/qanytype.cpp @@ -69,7 +69,7 @@ QXmlName AnyType::name(const NamePool::Ptr &np) const return np->allocateQName(StandardNamespaces::xs, QLatin1String("anyType")); } -QString AnyType::displayName(const NamePool::Ptr &) const +QString AnyType::displayName(const NamePool::Ptr &np) const { /* A bit faster than calling name()->displayName() */ return QLatin1String("xs:anyType"); @@ -85,9 +85,19 @@ SchemaType::TypeCategory AnyType::category() const return None; } +bool AnyType::isComplexType() const +{ + return true; +} + SchemaType::DerivationMethod AnyType::derivationMethod() const { return NoDerivation; } +SchemaType::DerivationConstraints AnyType::derivationConstraints() const +{ + return SchemaType::DerivationConstraints(); +} + QT_END_NAMESPACE diff --git a/src/xmlpatterns/type/qanytype_p.h b/src/xmlpatterns/type/qanytype_p.h index 70477af..8f2505e 100644 --- a/src/xmlpatterns/type/qanytype_p.h +++ b/src/xmlpatterns/type/qanytype_p.h @@ -114,6 +114,16 @@ namespace QPatternist */ virtual DerivationMethod derivationMethod() const; + /** + * @returns an empty set of derivation constraint flags. + */ + virtual DerivationConstraints derivationConstraints() const; + + /** + * Always returns @c true. + */ + virtual bool isComplexType() const; + protected: /** * @short This constructor is protected, because this diff --git a/src/xmlpatterns/type/qnamedschemacomponent.cpp b/src/xmlpatterns/type/qnamedschemacomponent.cpp new file mode 100644 index 0000000..e45b9b6 --- /dev/null +++ b/src/xmlpatterns/type/qnamedschemacomponent.cpp @@ -0,0 +1,41 @@ +/**************************************************************************** +** +** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the $MODULE$ of the Qt Toolkit. +** +** $TROLLTECH_DUAL_LICENSE$ +** +****************************************************************************/ + +#include "qnamedschemacomponent_p.h" + +QT_BEGIN_NAMESPACE + +using namespace QPatternist; + +NamedSchemaComponent::NamedSchemaComponent() +{ +} + +NamedSchemaComponent::~NamedSchemaComponent() +{ +} + +void NamedSchemaComponent::setName(const QXmlName &name) +{ + m_name = name; +} + +QXmlName NamedSchemaComponent::name(const NamePool::Ptr&) const +{ + return m_name; +} + +QString NamedSchemaComponent::displayName(const NamePool::Ptr &np) const +{ + return np->displayName(m_name); +} + +QT_END_NAMESPACE diff --git a/src/xmlpatterns/type/qnamedschemacomponent_p.h b/src/xmlpatterns/type/qnamedschemacomponent_p.h new file mode 100644 index 0000000..bc3121b --- /dev/null +++ b/src/xmlpatterns/type/qnamedschemacomponent_p.h @@ -0,0 +1,97 @@ +/**************************************************************************** +** +** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the $MODULE$ of the Qt Toolkit. +** +** $TROLLTECH_DUAL_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_NamedSchemaComponent_H +#define Patternist_NamedSchemaComponent_H + +#include "qnamepool_p.h" +#include "qschemacomponent_p.h" +#include "qxmlname.h" + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +namespace QPatternist +{ + /** + * @short Base class for all named components that can appear in a W3C XML Schema. + * + * @ingroup Patternist_types + * @author Tobias Koenig + */ + class NamedSchemaComponent : public SchemaComponent + { + public: + typedef QExplicitlySharedDataPointer Ptr; + + /** + * Describes the blocking constraints that are given by the 'block' attributes. + */ + enum BlockingConstraint + { + RestrictionConstraint = 1, + ExtensionConstraint = 2, + SubstitutionConstraint = 4 + }; + Q_DECLARE_FLAGS(BlockingConstraints, BlockingConstraint) + + /** + * Creates a new named schema component. + */ + NamedSchemaComponent(); + + /** + * Destroys the named schema component. + */ + virtual ~NamedSchemaComponent(); + + /** + * Sets the @p name of the schema component. + */ + void setName(const QXmlName &name); + + /** + * Returns the name of the schema component. + * + * @param namePool The name pool the name belongs to. + */ + virtual QXmlName name(const NamePool::Ptr &namePool) const; + + /** + * Returns the display name of the schema component. + * + * @param namePool The name pool the name belongs to. + */ + virtual QString displayName(const NamePool::Ptr &namePool) const; + + private: + QXmlName m_name; + }; + + Q_DECLARE_OPERATORS_FOR_FLAGS(NamedSchemaComponent::BlockingConstraints) +} + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif diff --git a/src/xmlpatterns/type/qprimitives_p.h b/src/xmlpatterns/type/qprimitives_p.h index 354b690..a1a41ae 100644 --- a/src/xmlpatterns/type/qprimitives_p.h +++ b/src/xmlpatterns/type/qprimitives_p.h @@ -53,6 +53,8 @@ #define Patternist_Primitives_H #include +#include +#include /** * @file @@ -72,6 +74,17 @@ QT_BEGIN_NAMESPACE class QString; /** + * @internal + * + * A method to allow a QHash or QSet with QUrl + * as key type. + */ +inline uint qHash(const QUrl &uri) +{ + return qHash(uri.toString()); +} + +/** * @short The namespace for the internal API of QtXmlPatterns * @internal */ diff --git a/src/xmlpatterns/type/qschematype.cpp b/src/xmlpatterns/type/qschematype.cpp index b4d6bc0..1ffd151 100644 --- a/src/xmlpatterns/type/qschematype.cpp +++ b/src/xmlpatterns/type/qschematype.cpp @@ -72,4 +72,9 @@ bool SchemaType::isComplexType() const return category() == ComplexType; } +bool SchemaType::isDefinedBySchema() const +{ + return false; +} + QT_END_NAMESPACE diff --git a/src/xmlpatterns/type/qschematype_p.h b/src/xmlpatterns/type/qschematype_p.h index 30f63c8..ca59bdc 100644 --- a/src/xmlpatterns/type/qschematype_p.h +++ b/src/xmlpatterns/type/qschematype_p.h @@ -57,6 +57,7 @@ #include "qxmlname.h" template class QHash; +template class QList; QT_BEGIN_HEADER @@ -80,6 +81,7 @@ namespace QPatternist typedef QExplicitlySharedDataPointer Ptr; typedef QHash Hash; + typedef QList List; /** * Schema types are divided into different categories such as @@ -117,6 +119,18 @@ namespace QPatternist NoDerivation = 16 }; + /** + * Describes the derivation constraints that are given by the 'final' or 'block' attributes. + */ + enum DerivationConstraint + { + RestrictionConstraint = 1, + ExtensionConstraint = 2, + ListConstraint = 4, + UnionConstraint = 8 + }; + Q_DECLARE_FLAGS(DerivationConstraints, DerivationConstraint) + SchemaType(); virtual ~SchemaType(); @@ -137,6 +151,11 @@ namespace QPatternist virtual DerivationMethod derivationMethod() const = 0; /** + * Determines what derivation constraints exists for the type. + */ + virtual DerivationConstraints derivationConstraints() const = 0; + + /** * Determines whether the type is an abstract type. * * @note It is important a correct value is returned, since @@ -202,7 +221,7 @@ namespace QPatternist * @note Do not re-implement this function, but instead override category() * and let it return an appropriate value. */ - bool isSimpleType() const; + virtual bool isSimpleType() const; /** * Determines whether the type is a complex type, by introspecting @@ -211,8 +230,15 @@ namespace QPatternist * @note Do not re-implement this function, but instead override category() * and let it return an appropriate value. */ - bool isComplexType() const; + virtual bool isComplexType() const; + + /** + * Returns whether the value has been defined by a schema (is not a built in type). + */ + virtual bool isDefinedBySchema() const; }; + + Q_DECLARE_OPERATORS_FOR_FLAGS(SchemaType::DerivationConstraints) } QT_END_NAMESPACE diff --git a/src/xmlpatterns/type/type.pri b/src/xmlpatterns/type/type.pri index ef5976a..5425298 100644 --- a/src/xmlpatterns/type/type.pri +++ b/src/xmlpatterns/type/type.pri @@ -24,6 +24,7 @@ HEADERS += $$PWD/qabstractnodetest_p.h \ $$PWD/qitemtype_p.h \ $$PWD/qlocalnametest_p.h \ $$PWD/qmultiitemtype_p.h \ + $$PWD/qnamedschemacomponent_p.h \ $$PWD/qnamespacenametest_p.h \ $$PWD/qnonetype_p.h \ $$PWD/qnumerictype_p.h \ @@ -57,6 +58,7 @@ SOURCES += $$PWD/qabstractnodetest.cpp \ $$PWD/qitemtype.cpp \ $$PWD/qlocalnametest.cpp \ $$PWD/qmultiitemtype.cpp \ + $$PWD/qnamedschemacomponent.cpp \ $$PWD/qnamespacenametest.cpp \ $$PWD/qnonetype.cpp \ $$PWD/qnumerictype.cpp \ diff --git a/src/xmlpatterns/utils/qpatternistlocale_p.h b/src/xmlpatterns/utils/qpatternistlocale_p.h index e3f645f..c340d95 100644 --- a/src/xmlpatterns/utils/qpatternistlocale_p.h +++ b/src/xmlpatterns/utils/qpatternistlocale_p.h @@ -168,6 +168,16 @@ namespace QPatternist } /** + * @short Formats name of any type. + */ + static inline QString formatType(const NamePool::Ptr &np, const QXmlName &name) + { + return QLatin1String("") + + escape(np->displayName(name)) + + QLatin1String(""); + } + + /** * @short Formats Cardinality. */ static inline QString formatType(const Cardinality &type) diff --git a/src/xmlpatterns/xmlpatterns.pro b/src/xmlpatterns/xmlpatterns.pro index e9d8af9..fb6aa1a 100644 --- a/src/xmlpatterns/xmlpatterns.pro +++ b/src/xmlpatterns/xmlpatterns.pro @@ -21,6 +21,8 @@ include($$PWD/iterators/iterators.pri) include($$PWD/janitors/janitors.pri) include($$PWD/parser/parser.pri) include($$PWD/projection/projection.pri) +include($$PWD/schema/schema.pri) +include($$PWD/schematron/schematron.pri) include($$PWD/type/type.pri) include($$PWD/utils/utils.pri) include($$PWD/qobjectmodel/qobjectmodel.pri) diff --git a/tests/auto/auto.pro b/tests/auto/auto.pro index 443ee7e..e8eea71 100644 --- a/tests/auto/auto.pro +++ b/tests/auto/auto.pro @@ -402,9 +402,14 @@ SUBDIRS += checkxmlfiles \ qxmlnodemodelindex \ qxmlquery \ qxmlresultitems \ + qxmlschema \ + qxmlschemavalidator \ qxmlserializer \ xmlpatterns \ xmlpatternsdiagnosticsts \ + xmlpatternsschema \ + xmlpatternsschemats \ + xmlpatternsvalidator \ xmlpatternsview \ xmlpatternsxqts \ xmlpatternsxslts diff --git a/tests/auto/qabstractxmlnodemodel/tst_qabstractxmlnodemodel.cpp b/tests/auto/qabstractxmlnodemodel/tst_qabstractxmlnodemodel.cpp index 72b43ee..9eacd90 100644 --- a/tests/auto/qabstractxmlnodemodel/tst_qabstractxmlnodemodel.cpp +++ b/tests/auto/qabstractxmlnodemodel/tst_qabstractxmlnodemodel.cpp @@ -45,6 +45,7 @@ #ifdef QTEST_XMLPATTERNS +#include #include #include #include @@ -80,6 +81,7 @@ private Q_SLOTS: void id() const; void idref() const; void typedValue() const; + void sourceLocation() const; private: QAbstractXmlNodeModel::Ptr m_nodeModel; @@ -389,6 +391,12 @@ void tst_QAbstractXmlNodeModel::typedValue() const QVERIFY(output.isEmpty()); } +void tst_QAbstractXmlNodeModel::sourceLocation() const +{ + const QAbstractXmlNodeModel* const constModel = m_nodeModel.data(); + const QSourceLocation location = constModel->sourceLocation(m_rootNode); +} + QTEST_MAIN(tst_QAbstractXmlNodeModel) #include "tst_qabstractxmlnodemodel.moc" diff --git a/tests/auto/qxmlquery/tst_qxmlquery.cpp b/tests/auto/qxmlquery/tst_qxmlquery.cpp index d457581..6d8a803 100644 --- a/tests/auto/qxmlquery/tst_qxmlquery.cpp +++ b/tests/auto/qxmlquery/tst_qxmlquery.cpp @@ -220,6 +220,10 @@ private Q_SLOTS: void bindVariableQXmlNameQXmlQuery() const; void bindVariableQXmlQueryInvalidate() const; + void identityConstraintSuccess() const; + void identityConstraintFailure() const; + void identityConstraintFailure_data() const; + // TODO call all URI resolving functions where 1) the URI resolver return a null QUrl(); 2) resolves into valid, existing URI, 3) invalid, non-existing URI. // TODO bind stringlists, variant lists, both ways. // TODO trigger serialization error, or any error in evaluateToushCallback(). @@ -2920,6 +2924,9 @@ void tst_QXmlQuery::enumQueryLanguage() const /* These enum values should be possible to OR for future plans. */ QCOMPARE(int(QXmlQuery::XQuery10), 1); QCOMPARE(int(QXmlQuery::XSLT20), 2); + QCOMPARE(int(QXmlQuery::XmlSchema11IdentityConstraintSelector), 1024); + QCOMPARE(int(QXmlQuery::XmlSchema11IdentityConstraintField), 2048); + QCOMPARE(int(QXmlQuery::XPath20), 4096); } void tst_QXmlQuery::setInitialTemplateNameQXmlName() const @@ -3222,6 +3229,157 @@ void tst_QXmlQuery::bindVariableQXmlQueryInvalidate() const QVERIFY(!query.isValid()); } +void tst_QXmlQuery::identityConstraintSuccess() const +{ + QXmlQuery::QueryLanguage queryLanguage = QXmlQuery::XmlSchema11IdentityConstraintSelector; + + /* We run this code for Selector and Field. */ + for(int i = 0; i < 3; ++i) + { + QXmlNamePool namePool; + QXmlResultItems result; + QXmlItem node; + + { + QXmlQuery nodeSource(namePool); + nodeSource.setQuery(QLatin1String("")); + + nodeSource.evaluateTo(&result); + node = result.next(); + } + + /* Basic use: + * 1. The focus is undefined, but it's still valid. + * 2. We never evaluate. */ + { + QXmlQuery query(queryLanguage); + query.setQuery(QLatin1String("a")); + QVERIFY(query.isValid()); + } + + /* Basic use: + * 1. The focus is undefined, but it's still valid. + * 2. We afterwards set the focus. */ + { + QXmlQuery query(queryLanguage, namePool); + query.setQuery(QLatin1String("a")); + query.setFocus(node); + QVERIFY(query.isValid()); + } + + /* Basic use: + * 1. The focus is undefined, but it's still valid. + * 2. We afterwards set the focus. + * 3. We evaluate. */ + { + QXmlQuery query(queryLanguage, namePool); + query.setQuery(QString(QLatin1Char('.'))); + query.setFocus(node); + QVERIFY(query.isValid()); + + QString result; + QVERIFY(query.evaluateTo(&result)); + QCOMPARE(result, QString::fromLatin1("\n")); + } + + /* A slightly more complex Field. */ + { + QXmlQuery query(queryLanguage); + query.setQuery(QLatin1String("* | .//xml:*/.")); + QVERIFY(query.isValid()); + } + + /* @ is only allowed in Field. */ + if(queryLanguage == QXmlQuery::XmlSchema11IdentityConstraintField) + { + QXmlQuery query(QXmlQuery::XmlSchema11IdentityConstraintField); + query.setQuery(QLatin1String("@abc")); + QVERIFY(query.isValid()); + } + + /* Field allows attribute:: and child:: .*/ + if(queryLanguage == QXmlQuery::XmlSchema11IdentityConstraintField) + { + QXmlQuery query(QXmlQuery::XmlSchema11IdentityConstraintField); + query.setQuery(QLatin1String("attribute::name | child::name")); + QVERIFY(query.isValid()); + } + + /* Selector allows only child:: .*/ + { + QXmlQuery query(QXmlQuery::XmlSchema11IdentityConstraintSelector); + query.setQuery(QLatin1String("child::name")); + QVERIFY(query.isValid()); + } + + if(i == 0) + queryLanguage = QXmlQuery::XmlSchema11IdentityConstraintField; + else if(i == 1) + queryLanguage = QXmlQuery::XPath20; + } +} + +Q_DECLARE_METATYPE(QXmlQuery::QueryLanguage); + +/*! + We just do some basic tests for boot strapping and sanity checking. The actual regression + testing is in the Schema suite. + */ +void tst_QXmlQuery::identityConstraintFailure() const +{ + QFETCH(QXmlQuery::QueryLanguage, queryLanguage); + QFETCH(QString, inputQuery); + + QXmlQuery query(queryLanguage); + MessageSilencer silencer; + query.setMessageHandler(&silencer); + + query.setQuery(inputQuery); + QVERIFY(!query.isValid()); +} + +void tst_QXmlQuery::identityConstraintFailure_data() const +{ + QTest::addColumn("queryLanguage"); + QTest::addColumn("inputQuery"); + + QTest::newRow("We don't have element constructors in identity constraint pattern, " + "it's an XQuery feature(Selector).") + << QXmlQuery::XmlSchema11IdentityConstraintSelector + << QString::fromLatin1(""); + + QTest::newRow("We don't have functions in identity constraint pattern, " + "it's an XPath feature(Selector).") + << QXmlQuery::XmlSchema11IdentityConstraintSelector + << QString::fromLatin1("current-time()"); + + QTest::newRow("We don't have element constructors in identity constraint pattern, " + "it's an XQuery feature(Field).") + << QXmlQuery::XmlSchema11IdentityConstraintSelector + << QString::fromLatin1(""); + + QTest::newRow("We don't have functions in identity constraint pattern, " + "it's an XPath feature(Field).") + << QXmlQuery::XmlSchema11IdentityConstraintSelector + << QString::fromLatin1("current-time()"); + + QTest::newRow("@attributeName is disallowed for the selector.") + << QXmlQuery::XmlSchema11IdentityConstraintSelector + << QString::fromLatin1("@abc"); + + QTest::newRow("attribute:: is disallowed for the selector.") + << QXmlQuery::XmlSchema11IdentityConstraintSelector + << QString::fromLatin1("attribute::name"); + + QTest::newRow("ancestor::name is disallowed for the selector.") + << QXmlQuery::XmlSchema11IdentityConstraintSelector + << QString::fromLatin1("ancestor::name"); + + QTest::newRow("ancestor::name is disallowed for the field.") + << QXmlQuery::XmlSchema11IdentityConstraintField + << QString::fromLatin1("ancestor::name"); +} + QTEST_MAIN(tst_QXmlQuery) #include "tst_qxmlquery.moc" diff --git a/tests/auto/qxmlschema/.gitignore b/tests/auto/qxmlschema/.gitignore new file mode 100644 index 0000000..5cf52a0 --- /dev/null +++ b/tests/auto/qxmlschema/.gitignore @@ -0,0 +1 @@ +tst_qxmlschema diff --git a/tests/auto/qxmlschema/qxmlschema.pro b/tests/auto/qxmlschema/qxmlschema.pro new file mode 100644 index 0000000..9dd7469 --- /dev/null +++ b/tests/auto/qxmlschema/qxmlschema.pro @@ -0,0 +1,4 @@ +load(qttest_p4) +SOURCES += tst_qxmlschema.cpp + +include (../xmlpatterns.pri) diff --git a/tests/auto/qxmlschema/tst_qxmlschema.cpp b/tests/auto/qxmlschema/tst_qxmlschema.cpp new file mode 100644 index 0000000..64012c1 --- /dev/null +++ b/tests/auto/qxmlschema/tst_qxmlschema.cpp @@ -0,0 +1,231 @@ +/**************************************************************************** +** +** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +****************************************************************************/ + +#include + +#ifdef QTEST_XMLPATTERNS + +#include +#include +#include +#include +#include + +class DummyMessageHandler : public QAbstractMessageHandler +{ + public: + DummyMessageHandler(QObject *parent = 0) + : QAbstractMessageHandler(parent) + { + } + + protected: + virtual void handleMessage(QtMsgType, const QString&, const QUrl&, const QSourceLocation&) + { + } +}; + +class DummyUriResolver : public QAbstractUriResolver +{ + public: + DummyUriResolver(QObject *parent = 0) + : QAbstractUriResolver(parent) + { + } + + virtual QUrl resolve(const QUrl&, const QUrl&) const + { + return QUrl(); + } +}; + +/*! + \class tst_QXmlSchema + \internal + \brief Tests class QXmlSchema. + + This test is not intended for testing the engine, but the functionality specific + to the QXmlSchema class. + */ +class tst_QXmlSchema : public QObject +{ + Q_OBJECT + +private Q_SLOTS: + void defaultConstructor() const; + void copyConstructor() const; + void constructorQXmlNamePool() const; + + void networkAccessManagerSignature() const; + void networkAccessManagerDefaultValue() const; + void networkAccessManager() const; + + void messageHandlerSignature() const; + void messageHandlerDefaultValue() const; + void messageHandler() const; + + void uriResolverSignature() const; + void uriResolverDefaultValue() const; + void uriResolver() const; +}; + +void tst_QXmlSchema::defaultConstructor() const +{ + /* Allocate instance in different orders. */ + { + QXmlSchema schema; + } + + { + QXmlSchema schema1; + QXmlSchema schema2; + } + + { + QXmlSchema schema1; + QXmlSchema schema2; + QXmlSchema schema3; + } +} + +void tst_QXmlSchema::copyConstructor() const +{ + /* Verify that we can take a const reference, and simply do a copy of a default constructed object. */ + { + const QXmlSchema schema1; + QXmlSchema schema2(schema1); + } + + /* Copy twice. */ + { + const QXmlSchema schema1; + QXmlSchema schema2(schema1); + QXmlSchema schema3(schema2); + } + + /* Verify that copying default values works. */ + { + const QXmlSchema schema1; + const QXmlSchema schema2(schema1); + QCOMPARE(schema2.messageHandler(), schema1.messageHandler()); + QCOMPARE(schema2.uriResolver(), schema1.uriResolver()); + QCOMPARE(schema2.networkAccessManager(), schema1.networkAccessManager()); + QCOMPARE(schema2.isValid(), schema1.isValid()); + } +} + +void tst_QXmlSchema::constructorQXmlNamePool() const +{ + QXmlSchema schema; + + QXmlNamePool np = schema.namePool(); + + const QXmlName name(np, QLatin1String("localName"), + QLatin1String("http://example.com/"), + QLatin1String("prefix")); + + QXmlNamePool np2(schema.namePool()); + QCOMPARE(name.namespaceUri(np2), QString::fromLatin1("http://example.com/")); + QCOMPARE(name.localName(np2), QString::fromLatin1("localName")); + QCOMPARE(name.prefix(np2), QString::fromLatin1("prefix")); +} + +void tst_QXmlSchema::networkAccessManagerSignature() const +{ + /* Const object. */ + const QXmlSchema schema; + + /* The function should be const. */ + schema.networkAccessManager(); +} + +void tst_QXmlSchema::networkAccessManagerDefaultValue() const +{ + /* Test that the default value of network access manager is not empty. */ + { + QXmlSchema schema; + QVERIFY(schema.networkAccessManager() != static_cast(0)); + } +} + +void tst_QXmlSchema::networkAccessManager() const +{ + /* Test that we return the network manager that was set. */ + { + QNetworkAccessManager manager; + QXmlSchema schema; + schema.setNetworkAccessManager(&manager); + QCOMPARE(schema.networkAccessManager(), &manager); + } +} + +void tst_QXmlSchema::messageHandlerSignature() const +{ + /* Const object. */ + const QXmlSchema schema; + + /* The function should be const. */ + schema.messageHandler(); +} + +void tst_QXmlSchema::messageHandlerDefaultValue() const +{ + /* Test that the default value of message handler is not empty. */ + { + QXmlSchema schema; + QVERIFY(schema.messageHandler() != static_cast(0)); + } +} + +void tst_QXmlSchema::messageHandler() const +{ + /* Test that we return the message handler that was set. */ + { + DummyMessageHandler handler; + + QXmlSchema schema; + schema.setMessageHandler(&handler); + QCOMPARE(schema.messageHandler(), &handler); + } +} + +void tst_QXmlSchema::uriResolverSignature() const +{ + /* Const object. */ + const QXmlSchema schema; + + /* The function should be const. */ + schema.uriResolver(); +} + +void tst_QXmlSchema::uriResolverDefaultValue() const +{ + /* Test that the default value of uri resolver is empty. */ + { + QXmlSchema schema; + QVERIFY(schema.uriResolver() == static_cast(0)); + } +} + +void tst_QXmlSchema::uriResolver() const +{ + /* Test that we return the uri resolver that was set. */ + { + DummyUriResolver resolver; + + QXmlSchema schema; + schema.setUriResolver(&resolver); + QCOMPARE(schema.uriResolver(), &resolver); + } +} + +QTEST_MAIN(tst_QXmlSchema) + +#include "tst_qxmlschema.moc" +#else //QTEST_PATTERNIST +QTEST_NOOP_MAIN +#endif diff --git a/tests/auto/qxmlschemavalidator/.gitignore b/tests/auto/qxmlschemavalidator/.gitignore new file mode 100644 index 0000000..8857212 --- /dev/null +++ b/tests/auto/qxmlschemavalidator/.gitignore @@ -0,0 +1 @@ +tst_qxmlschemavalidator diff --git a/tests/auto/qxmlschemavalidator/qxmlschemavalidator.pro b/tests/auto/qxmlschemavalidator/qxmlschemavalidator.pro new file mode 100644 index 0000000..88ef317 --- /dev/null +++ b/tests/auto/qxmlschemavalidator/qxmlschemavalidator.pro @@ -0,0 +1,4 @@ +load(qttest_p4) +SOURCES += tst_qxmlschemavalidator.cpp + +include (../xmlpatterns.pri) diff --git a/tests/auto/qxmlschemavalidator/tst_qxmlschemavalidator.cpp b/tests/auto/qxmlschemavalidator/tst_qxmlschemavalidator.cpp new file mode 100644 index 0000000..b021b08 --- /dev/null +++ b/tests/auto/qxmlschemavalidator/tst_qxmlschemavalidator.cpp @@ -0,0 +1,308 @@ +/**************************************************************************** +** +** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +****************************************************************************/ + +#include + +#ifdef QTEST_XMLPATTERNS + +#include +#include +#include +#include +#include +#include + +class DummyMessageHandler : public QAbstractMessageHandler +{ + public: + DummyMessageHandler(QObject *parent = 0) + : QAbstractMessageHandler(parent) + { + } + + protected: + virtual void handleMessage(QtMsgType, const QString&, const QUrl&, const QSourceLocation&) + { + } +}; + +class DummyUriResolver : public QAbstractUriResolver +{ + public: + DummyUriResolver(QObject *parent = 0) + : QAbstractUriResolver(parent) + { + } + + virtual QUrl resolve(const QUrl&, const QUrl&) const + { + return QUrl(); + } +}; + +/*! + \class tst_QXmlSchemaValidatorValidator + \internal + \brief Tests class QXmlSchemaValidator. + + This test is not intended for testing the engine, but the functionality specific + to the QXmlSchemaValidator class. + */ +class tst_QXmlSchemaValidator : public QObject +{ + Q_OBJECT + +private Q_SLOTS: + void defaultConstructor() const; + void propertyInitialization() const; + + void networkAccessManagerSignature() const; + void networkAccessManagerDefaultValue() const; + void networkAccessManager() const; + + void messageHandlerSignature() const; + void messageHandlerDefaultValue() const; + void messageHandler() const; + + void uriResolverSignature() const; + void uriResolverDefaultValue() const; + void uriResolver() const; +}; + +void tst_QXmlSchemaValidator::defaultConstructor() const +{ + /* Allocate instance in different orders. */ + { + QXmlSchema schema; + QXmlSchemaValidator validator(schema); + } + + { + QXmlSchema schema1; + QXmlSchema schema2; + + QXmlSchemaValidator validator1(schema1); + QXmlSchemaValidator validator2(schema2); + } + + { + QXmlSchema schema; + + QXmlSchemaValidator validator1(schema); + QXmlSchemaValidator validator2(schema); + } +} + +void tst_QXmlSchemaValidator::propertyInitialization() const +{ + /* Verify that properties set in the schema are used as default values for the validator */ + { + DummyMessageHandler handler; + DummyUriResolver resolver; + QNetworkAccessManager manager; + + QXmlSchema schema; + schema.setMessageHandler(&handler); + schema.setUriResolver(&resolver); + schema.setNetworkAccessManager(&manager); + + QXmlSchemaValidator validator(schema); + QCOMPARE(validator.messageHandler(), &handler); + QCOMPARE(validator.uriResolver(), &resolver); + QCOMPARE(validator.networkAccessManager(), &manager); + } +} + +void tst_QXmlSchemaValidator::networkAccessManagerSignature() const +{ + const QXmlSchema schema; + + /* Const object. */ + const QXmlSchemaValidator validator(schema); + + /* The function should be const. */ + validator.networkAccessManager(); +} + +void tst_QXmlSchemaValidator::networkAccessManagerDefaultValue() const +{ + /* Test that the default value of network access manager is equal to the one from the schema. */ + { + const QXmlSchema schema; + const QXmlSchemaValidator validator(schema); + QVERIFY(validator.networkAccessManager() == schema.networkAccessManager()); + } + + /* Test that the default value of network access manager is equal to the one from the schema. */ + { + QXmlSchema schema; + + QNetworkAccessManager manager; + schema.setNetworkAccessManager(&manager); + + const QXmlSchemaValidator validator(schema); + QVERIFY(validator.networkAccessManager() == schema.networkAccessManager()); + } +} + +void tst_QXmlSchemaValidator::networkAccessManager() const +{ + /* Test that we return the network access manager that was set. */ + { + QNetworkAccessManager manager; + + const QXmlSchema schema; + QXmlSchemaValidator validator(schema); + + validator.setNetworkAccessManager(&manager); + QCOMPARE(validator.networkAccessManager(), &manager); + } + + /* Test that we return the network access manager that was set, even if the schema changed in between. */ + { + QNetworkAccessManager manager; + + const QXmlSchema schema; + QXmlSchemaValidator validator(schema); + + validator.setNetworkAccessManager(&manager); + + const QXmlSchema schema2; + validator.setSchema(schema2); + + QCOMPARE(validator.networkAccessManager(), &manager); + } +} + +void tst_QXmlSchemaValidator::messageHandlerSignature() const +{ + const QXmlSchema schema; + + /* Const object. */ + const QXmlSchemaValidator validator(schema); + + /* The function should be const. */ + validator.messageHandler(); +} + +void tst_QXmlSchemaValidator::messageHandlerDefaultValue() const +{ + /* Test that the default value of message handler is equal to the one from the schema. */ + { + const QXmlSchema schema; + const QXmlSchemaValidator validator(schema); + QVERIFY(validator.messageHandler() == schema.messageHandler()); + } + + /* Test that the default value of network access manager is equal to the one from the schema. */ + { + QXmlSchema schema; + + DummyMessageHandler handler; + schema.setMessageHandler(&handler); + + const QXmlSchemaValidator validator(schema); + QVERIFY(validator.messageHandler() == schema.messageHandler()); + } +} + +void tst_QXmlSchemaValidator::messageHandler() const +{ + /* Test that we return the message handler that was set. */ + { + DummyMessageHandler handler; + + const QXmlSchema schema; + QXmlSchemaValidator validator(schema); + + validator.setMessageHandler(&handler); + QCOMPARE(validator.messageHandler(), &handler); + } + + /* Test that we return the message handler that was set, even if the schema changed in between. */ + { + DummyMessageHandler handler; + + const QXmlSchema schema; + QXmlSchemaValidator validator(schema); + + validator.setMessageHandler(&handler); + + const QXmlSchema schema2; + validator.setSchema(schema2); + + QCOMPARE(validator.messageHandler(), &handler); + } +} + +void tst_QXmlSchemaValidator::uriResolverSignature() const +{ + const QXmlSchema schema; + + /* Const object. */ + const QXmlSchemaValidator validator(schema); + + /* The function should be const. */ + validator.uriResolver(); +} + +void tst_QXmlSchemaValidator::uriResolverDefaultValue() const +{ + /* Test that the default value of uri resolver is equal to the one from the schema. */ + { + const QXmlSchema schema; + const QXmlSchemaValidator validator(schema); + QVERIFY(validator.uriResolver() == schema.uriResolver()); + } + + /* Test that the default value of uri resolver is equal to the one from the schema. */ + { + QXmlSchema schema; + + DummyUriResolver resolver; + schema.setUriResolver(&resolver); + + const QXmlSchemaValidator validator(schema); + QVERIFY(validator.uriResolver() == schema.uriResolver()); + } +} + +void tst_QXmlSchemaValidator::uriResolver() const +{ + /* Test that we return the uri resolver that was set. */ + { + DummyUriResolver resolver; + + const QXmlSchema schema; + QXmlSchemaValidator validator(schema); + + validator.setUriResolver(&resolver); + QCOMPARE(validator.uriResolver(), &resolver); + } + + /* Test that we return the uri resolver that was set, even if the schema changed in between. */ + { + DummyUriResolver resolver; + + const QXmlSchema schema; + QXmlSchemaValidator validator(schema); + + validator.setUriResolver(&resolver); + + const QXmlSchema schema2; + validator.setSchema(schema2); + + QCOMPARE(validator.uriResolver(), &resolver); + } +} + +QTEST_MAIN(tst_QXmlSchemaValidator) + +#include "tst_qxmlschemavalidator.moc" +#else //QTEST_PATTERNIST +QTEST_NOOP_MAIN +#endif diff --git a/tests/auto/runQtXmlPatternsTests.sh b/tests/auto/runQtXmlPatternsTests.sh index 49ea840..41d6c83 100755 --- a/tests/auto/runQtXmlPatternsTests.sh +++ b/tests/auto/runQtXmlPatternsTests.sh @@ -34,6 +34,8 @@ qxmlserializer \ xmlpatterns \ xmlpatternsxqts \ xmlpatternsdiagnosticsts \ +xmlpatternsschema \ +xmlpatternsschemats \ xmlpatternsview \ xmlpatternsxslts" diff --git a/tests/auto/xmlpatterns.pri b/tests/auto/xmlpatterns.pri index bf13c3b..7cdd67f 100644 --- a/tests/auto/xmlpatterns.pri +++ b/tests/auto/xmlpatterns.pri @@ -19,3 +19,17 @@ if(!debug_and_release|build_pass):CONFIG(debug, debug|release) { else: XMLPATTERNS_SDK = $${XMLPATTERNS_SDK}_debug } +INCLUDEPATH += \ + $$QT_SOURCE_TREE/src/xmlpatterns/acceltree \ + $$QT_SOURCE_TREE/src/xmlpatterns/api \ + $$QT_SOURCE_TREE/src/xmlpatterns/data \ + $$QT_SOURCE_TREE/src/xmlpatterns/environment \ + $$QT_SOURCE_TREE/src/xmlpatterns/expr \ + $$QT_SOURCE_TREE/src/xmlpatterns/functions \ + $$QT_SOURCE_TREE/src/xmlpatterns/iterators \ + $$QT_SOURCE_TREE/src/xmlpatterns/janitors \ + $$QT_SOURCE_TREE/src/xmlpatterns/parser \ + $$QT_SOURCE_TREE/src/xmlpatterns/projection \ + $$QT_SOURCE_TREE/src/xmlpatterns/schema \ + $$QT_SOURCE_TREE/src/xmlpatterns/type \ + $$QT_SOURCE_TREE/src/xmlpatterns/utils diff --git a/tests/auto/xmlpatternsdiagnosticsts/test/tst_xmlpatternsdiagnosticsts.cpp b/tests/auto/xmlpatternsdiagnosticsts/test/tst_xmlpatternsdiagnosticsts.cpp index 60037f9..13c3534 100644 --- a/tests/auto/xmlpatternsdiagnosticsts/test/tst_xmlpatternsdiagnosticsts.cpp +++ b/tests/auto/xmlpatternsdiagnosticsts/test/tst_xmlpatternsdiagnosticsts.cpp @@ -61,7 +61,7 @@ protected: virtual void catalogPath(QString &write) const; }; -tst_XmlPatternsXSLTS::tst_XmlPatternsXSLTS() : tst_SuiteTest(false, true) +tst_XmlPatternsXSLTS::tst_XmlPatternsXSLTS() : tst_SuiteTest(tst_SuiteTest::XQuerySuite, true) { } diff --git a/tests/auto/xmlpatternsschema/.gitignore b/tests/auto/xmlpatternsschema/.gitignore new file mode 100644 index 0000000..a37a2b7 --- /dev/null +++ b/tests/auto/xmlpatternsschema/.gitignore @@ -0,0 +1 @@ +tst_xmlpatternsschema diff --git a/tests/auto/xmlpatternsschema/tst_xmlpatternsschema.cpp b/tests/auto/xmlpatternsschema/tst_xmlpatternsschema.cpp new file mode 100644 index 0000000..030e9c0 --- /dev/null +++ b/tests/auto/xmlpatternsschema/tst_xmlpatternsschema.cpp @@ -0,0 +1,988 @@ + +#include + +#include "qxsdstatemachine_p.h" +#include "qxsdschematoken_p.h" + +using namespace QPatternist; + +class tst_XMLPatternsSchema : public QObject +{ + Q_OBJECT + + public slots: + void init(); + void cleanup(); + + private slots: + void stateMachineTest1(); + void stateMachineTest2(); + void stateMachineTest3(); + void stateMachineTest4(); + void stateMachineTest5(); + void stateMachineTest6(); + void stateMachineTest7(); + void stateMachineTest8(); + void stateMachineTest9(); + void stateMachineTest10(); + void stateMachineTest11(); + void stateMachineTest12(); + void stateMachineTest13(); + void stateMachineTest14(); + void stateMachineTest15(); + void stateMachineTest16(); + void stateMachineTest17(); + void stateMachineTest18(); + void stateMachineTest19(); + + private: + bool runTest(const QVector &list, XsdStateMachine &machine); +}; + +void tst_XMLPatternsSchema::init() +{ +} + +void tst_XMLPatternsSchema::cleanup() +{ +} + +bool tst_XMLPatternsSchema::runTest(const QVector &list, XsdStateMachine &machine) +{ + machine.reset(); + for (int i = 0; i < list.count(); ++i) { + if (!machine.proceed(list.at(i))) + return false; + } + if (!machine.inEndState()) + return false; + + return true; +} + +void tst_XMLPatternsSchema::stateMachineTest1() +{ + XsdStateMachine machine; + + // setup state machine for (annotation?, simpleType?) : attribute + const XsdStateMachine::StateId startState = machine.addState(XsdStateMachine::StartEndState); + const XsdStateMachine::StateId s1 = machine.addState(XsdStateMachine::EndState); + const XsdStateMachine::StateId s2 = machine.addState(XsdStateMachine::EndState); + + machine.addTransition(startState, XsdSchemaToken::Annotation, s1); + machine.addTransition(startState, XsdSchemaToken::SimpleType, s2); + machine.addTransition(s1, XsdSchemaToken::SimpleType, s2); + + QVERIFY(machine.inEndState() == true); + QVERIFY(machine.proceed(XsdSchemaToken::Annotation) == true); + QVERIFY(machine.inEndState() == true); + QVERIFY(machine.proceed(XsdSchemaToken::SimpleType) == true); + QVERIFY(machine.inEndState() == true); + QVERIFY(machine.proceed(XsdSchemaToken::SimpleType) == false); + QVERIFY(machine.proceed(XsdSchemaToken::Annotation) == false); + machine.reset(); + QVERIFY(machine.proceed(XsdSchemaToken::SimpleType) == true); + QVERIFY(machine.inEndState() == true); + QVERIFY(machine.proceed(XsdSchemaToken::Annotation) == false); +} + +void tst_XMLPatternsSchema::stateMachineTest2() +{ + XsdStateMachine machine; + + // setup state machine for (annotation?, ((simpleType | complexType)?, (unique | key | keyref)*)) : element + const XsdStateMachine::StateId startState = machine.addState(XsdStateMachine::StartEndState); + const XsdStateMachine::StateId s1 = machine.addState(XsdStateMachine::EndState); + const XsdStateMachine::StateId s2 = machine.addState(XsdStateMachine::EndState); + const XsdStateMachine::StateId s3 = machine.addState(XsdStateMachine::EndState); + const XsdStateMachine::StateId s4 = machine.addState(XsdStateMachine::EndState); + const XsdStateMachine::StateId s5 = machine.addState(XsdStateMachine::EndState); + const XsdStateMachine::StateId s6 = machine.addState(XsdStateMachine::EndState); + + machine.addTransition(startState, XsdSchemaToken::Annotation, s1); + machine.addTransition(startState, XsdSchemaToken::SimpleType, s2); + machine.addTransition(startState, XsdSchemaToken::ComplexType, s3); + machine.addTransition(startState, XsdSchemaToken::Unique, s4); + machine.addTransition(startState, XsdSchemaToken::Key, s5); + machine.addTransition(startState, XsdSchemaToken::Keyref, s6); + + machine.addTransition(s1, XsdSchemaToken::SimpleType, s2); + machine.addTransition(s1, XsdSchemaToken::ComplexType, s3); + machine.addTransition(s1, XsdSchemaToken::Unique, s4); + machine.addTransition(s1, XsdSchemaToken::Key, s5); + machine.addTransition(s1, XsdSchemaToken::Keyref, s6); + + machine.addTransition(s2, XsdSchemaToken::Unique, s4); + machine.addTransition(s2, XsdSchemaToken::Key, s5); + machine.addTransition(s2, XsdSchemaToken::Keyref, s6); + + machine.addTransition(s3, XsdSchemaToken::Unique, s4); + machine.addTransition(s3, XsdSchemaToken::Key, s5); + machine.addTransition(s3, XsdSchemaToken::Keyref, s6); + + machine.addTransition(s4, XsdSchemaToken::Unique, s4); + machine.addTransition(s4, XsdSchemaToken::Key, s5); + machine.addTransition(s4, XsdSchemaToken::Keyref, s6); + + machine.addTransition(s5, XsdSchemaToken::Unique, s4); + machine.addTransition(s5, XsdSchemaToken::Key, s5); + machine.addTransition(s5, XsdSchemaToken::Keyref, s6); + + machine.addTransition(s6, XsdSchemaToken::Unique, s4); + machine.addTransition(s6, XsdSchemaToken::Key, s5); + machine.addTransition(s6, XsdSchemaToken::Keyref, s6); + + QVector data1, data2, data3; + + data1 << XsdSchemaToken::Annotation + << XsdSchemaToken::SimpleType + << XsdSchemaToken::Unique + << XsdSchemaToken::Keyref; + + data2 << XsdSchemaToken::Annotation + << XsdSchemaToken::SimpleType + << XsdSchemaToken::Annotation + << XsdSchemaToken::Keyref; + + data3 << XsdSchemaToken::Annotation + << XsdSchemaToken::SimpleType + << XsdSchemaToken::SimpleType; + + QVERIFY(runTest(data1, machine) == true); + QVERIFY(runTest(data2, machine) == false); + QVERIFY(runTest(data3, machine) == false); +} + +void tst_XMLPatternsSchema::stateMachineTest3() +{ + XsdStateMachine machine; + + // setup state machine for (annotation?, (simpleContent | complexContent | ((group | all | choice | sequence)?, ((attribute | attributeGroup)*, anyAttribute?)))) : complexType + const XsdStateMachine::StateId startState = machine.addState(XsdStateMachine::StartEndState); + const XsdStateMachine::StateId s1 = machine.addState(XsdStateMachine::EndState); + const XsdStateMachine::StateId s2 = machine.addState(XsdStateMachine::EndState); + const XsdStateMachine::StateId s3 = machine.addState(XsdStateMachine::EndState); + const XsdStateMachine::StateId s4 = machine.addState(XsdStateMachine::EndState); + const XsdStateMachine::StateId s5 = machine.addState(XsdStateMachine::EndState); + const XsdStateMachine::StateId s6 = machine.addState(XsdStateMachine::EndState); + const XsdStateMachine::StateId s7 = machine.addState(XsdStateMachine::EndState); + const XsdStateMachine::StateId s8 = machine.addState(XsdStateMachine::EndState); + const XsdStateMachine::StateId s9 = machine.addState(XsdStateMachine::EndState); + const XsdStateMachine::StateId s10 = machine.addState(XsdStateMachine::EndState); + + machine.addTransition(startState, XsdSchemaToken::Annotation, s1); + machine.addTransition(startState, XsdSchemaToken::SimpleContent, s2); + machine.addTransition(startState, XsdSchemaToken::ComplexContent, s3); + machine.addTransition(startState, XsdSchemaToken::Group, s4); + machine.addTransition(startState, XsdSchemaToken::All, s5); + machine.addTransition(startState, XsdSchemaToken::Choice, s6); + machine.addTransition(startState, XsdSchemaToken::Sequence, s7); + machine.addTransition(startState, XsdSchemaToken::Attribute, s8); + machine.addTransition(startState, XsdSchemaToken::AttributeGroup, s9); + machine.addTransition(startState, XsdSchemaToken::AnyAttribute, s10); + + machine.addTransition(s1, XsdSchemaToken::SimpleContent, s2); + machine.addTransition(s1, XsdSchemaToken::ComplexContent, s3); + machine.addTransition(s1, XsdSchemaToken::Group, s4); + machine.addTransition(s1, XsdSchemaToken::All, s5); + machine.addTransition(s1, XsdSchemaToken::Choice, s6); + machine.addTransition(s1, XsdSchemaToken::Sequence, s7); + machine.addTransition(s1, XsdSchemaToken::Attribute, s8); + machine.addTransition(s1, XsdSchemaToken::AttributeGroup, s9); + machine.addTransition(s1, XsdSchemaToken::AnyAttribute, s10); + + machine.addTransition(s4, XsdSchemaToken::Attribute, s8); + machine.addTransition(s4, XsdSchemaToken::AttributeGroup, s9); + machine.addTransition(s4, XsdSchemaToken::AnyAttribute, s10); + + machine.addTransition(s5, XsdSchemaToken::Attribute, s8); + machine.addTransition(s5, XsdSchemaToken::AttributeGroup, s9); + machine.addTransition(s5, XsdSchemaToken::AnyAttribute, s10); + + machine.addTransition(s6, XsdSchemaToken::Attribute, s8); + machine.addTransition(s6, XsdSchemaToken::AttributeGroup, s9); + machine.addTransition(s6, XsdSchemaToken::AnyAttribute, s10); + + machine.addTransition(s7, XsdSchemaToken::Attribute, s8); + machine.addTransition(s7, XsdSchemaToken::AttributeGroup, s9); + machine.addTransition(s7, XsdSchemaToken::AnyAttribute, s10); + + machine.addTransition(s8, XsdSchemaToken::Attribute, s8); + machine.addTransition(s8, XsdSchemaToken::AttributeGroup, s9); + machine.addTransition(s8, XsdSchemaToken::AnyAttribute, s10); + + QVector data1, data2, data3, data4; + + data1 << XsdSchemaToken::Annotation + << XsdSchemaToken::SimpleContent; + + data2 << XsdSchemaToken::Group + << XsdSchemaToken::Attribute + << XsdSchemaToken::Attribute + << XsdSchemaToken::AnyAttribute; + + data3 << XsdSchemaToken::Group + << XsdSchemaToken::Choice + << XsdSchemaToken::Attribute + << XsdSchemaToken::AnyAttribute; + + data4 << XsdSchemaToken::Annotation + << XsdSchemaToken::Sequence + << XsdSchemaToken::AnyAttribute; + + QVERIFY(runTest(data1, machine) == true); + QVERIFY(runTest(data2, machine) == true); + QVERIFY(runTest(data3, machine) == false); + QVERIFY(runTest(data4, machine) == true); +} + +void tst_XMLPatternsSchema::stateMachineTest4() +{ + XsdStateMachine machine; + + // setup state machine for (annotation?, ((attribute | attributeGroup)*, anyAttribute?)) : named attribute group/simple content extension/ + const XsdStateMachine::StateId startState = machine.addState(XsdStateMachine::StartEndState); + const XsdStateMachine::StateId s1 = machine.addState(XsdStateMachine::EndState); + const XsdStateMachine::StateId s2 = machine.addState(XsdStateMachine::EndState); + const XsdStateMachine::StateId s3 = machine.addState(XsdStateMachine::EndState); + const XsdStateMachine::StateId s4 = machine.addState(XsdStateMachine::EndState); + + machine.addTransition(startState, XsdSchemaToken::Annotation, s1); + machine.addTransition(startState, XsdSchemaToken::Attribute, s2); + machine.addTransition(startState, XsdSchemaToken::AttributeGroup, s3); + machine.addTransition(startState, XsdSchemaToken::AnyAttribute, s4); + + machine.addTransition(s1, XsdSchemaToken::Attribute, s2); + machine.addTransition(s1, XsdSchemaToken::AttributeGroup, s3); + machine.addTransition(s1, XsdSchemaToken::AnyAttribute, s4); + + machine.addTransition(s2, XsdSchemaToken::Attribute, s2); + machine.addTransition(s2, XsdSchemaToken::AttributeGroup, s3); + machine.addTransition(s2, XsdSchemaToken::AnyAttribute, s4); + + machine.addTransition(s3, XsdSchemaToken::Attribute, s2); + machine.addTransition(s3, XsdSchemaToken::AttributeGroup, s3); + machine.addTransition(s3, XsdSchemaToken::AnyAttribute, s4); + + QVector data1, data2, data3, data4; + + data1 << XsdSchemaToken::Annotation; + + data2 << XsdSchemaToken::Attribute + << XsdSchemaToken::Attribute + << XsdSchemaToken::Attribute + << XsdSchemaToken::AnyAttribute; + + data3 << XsdSchemaToken::Group + << XsdSchemaToken::Attribute + << XsdSchemaToken::AnyAttribute; + + data4 << XsdSchemaToken::Attribute + << XsdSchemaToken::AnyAttribute + << XsdSchemaToken::Attribute; + + QVERIFY(runTest(data1, machine) == true); + QVERIFY(runTest(data2, machine) == true); + QVERIFY(runTest(data3, machine) == false); + QVERIFY(runTest(data4, machine) == false); +} + +void tst_XMLPatternsSchema::stateMachineTest5() +{ + XsdStateMachine machine; + + // setup state machine for (annotation?, (all | choice | sequence)?) : group + const XsdStateMachine::StateId startState = machine.addState(XsdStateMachine::StartEndState); + const XsdStateMachine::StateId s1 = machine.addState(XsdStateMachine::EndState); + const XsdStateMachine::StateId s2 = machine.addState(XsdStateMachine::EndState); + const XsdStateMachine::StateId s3 = machine.addState(XsdStateMachine::EndState); + const XsdStateMachine::StateId s4 = machine.addState(XsdStateMachine::EndState); + + machine.addTransition(startState, XsdSchemaToken::Annotation, s1); + machine.addTransition(startState, XsdSchemaToken::All, s2); + machine.addTransition(startState, XsdSchemaToken::Choice, s3); + machine.addTransition(startState, XsdSchemaToken::Sequence, s4); + + machine.addTransition(s1, XsdSchemaToken::All, s2); + machine.addTransition(s1, XsdSchemaToken::Choice, s3); + machine.addTransition(s1, XsdSchemaToken::Sequence, s4); + + QVector data1, data2, data3, data4, data5, data6, data7, data8, data9; + + data1 << XsdSchemaToken::Annotation; + data2 << XsdSchemaToken::Annotation << XsdSchemaToken::All; + data3 << XsdSchemaToken::Annotation << XsdSchemaToken::Choice; + data4 << XsdSchemaToken::Annotation << XsdSchemaToken::Sequence; + data5 << XsdSchemaToken::All; + data6 << XsdSchemaToken::Choice; + data7 << XsdSchemaToken::Sequence; + data8 << XsdSchemaToken::Sequence << XsdSchemaToken::All; + + QVERIFY(runTest(data1, machine) == true); + QVERIFY(runTest(data2, machine) == true); + QVERIFY(runTest(data3, machine) == true); + QVERIFY(runTest(data4, machine) == true); + QVERIFY(runTest(data5, machine) == true); + QVERIFY(runTest(data6, machine) == true); + QVERIFY(runTest(data7, machine) == true); + QVERIFY(runTest(data8, machine) == false); + QVERIFY(runTest(data9, machine) == true); +} + +void tst_XMLPatternsSchema::stateMachineTest6() +{ + XsdStateMachine machine; + + // setup state machine for (annotation?, element*) : all + const XsdStateMachine::StateId startState = machine.addState(XsdStateMachine::StartEndState); + const XsdStateMachine::StateId s1 = machine.addState(XsdStateMachine::EndState); + const XsdStateMachine::StateId s2 = machine.addState(XsdStateMachine::EndState); + + machine.addTransition(startState, XsdSchemaToken::Annotation, s1); + machine.addTransition(startState, XsdSchemaToken::Element, s2); + + machine.addTransition(s1, XsdSchemaToken::Element, s2); + + machine.addTransition(s2, XsdSchemaToken::Element, s2); + + QVector data1, data2, data3, data4, data5, data6, data7, data8, data9; + + data1 << XsdSchemaToken::Annotation; + data2 << XsdSchemaToken::Annotation << XsdSchemaToken::Element; + data3 << XsdSchemaToken::Element; + data4 << XsdSchemaToken::Element << XsdSchemaToken::Sequence; + data5 << XsdSchemaToken::Annotation << XsdSchemaToken::Element << XsdSchemaToken::Annotation; + data6 << XsdSchemaToken::Annotation << XsdSchemaToken::Annotation << XsdSchemaToken::Element; + + QVERIFY(runTest(data1, machine) == true); + QVERIFY(runTest(data2, machine) == true); + QVERIFY(runTest(data3, machine) == true); + QVERIFY(runTest(data4, machine) == false); + QVERIFY(runTest(data5, machine) == false); + QVERIFY(runTest(data6, machine) == false); +} + +void tst_XMLPatternsSchema::stateMachineTest7() +{ + XsdStateMachine machine; + + // setup state machine for (annotation?, (element | group | choice | sequence | any)*) : choice sequence + const XsdStateMachine::StateId startState = machine.addState(XsdStateMachine::StartEndState); + const XsdStateMachine::StateId s1 = machine.addState(XsdStateMachine::EndState); + const XsdStateMachine::StateId s2 = machine.addState(XsdStateMachine::EndState); + const XsdStateMachine::StateId s3 = machine.addState(XsdStateMachine::EndState); + const XsdStateMachine::StateId s4 = machine.addState(XsdStateMachine::EndState); + const XsdStateMachine::StateId s5 = machine.addState(XsdStateMachine::EndState); + const XsdStateMachine::StateId s6 = machine.addState(XsdStateMachine::EndState); + + machine.addTransition(startState, XsdSchemaToken::Annotation, s1); + machine.addTransition(startState, XsdSchemaToken::Element, s2); + machine.addTransition(startState, XsdSchemaToken::Group, s3); + machine.addTransition(startState, XsdSchemaToken::Choice, s4); + machine.addTransition(startState, XsdSchemaToken::Sequence, s5); + machine.addTransition(startState, XsdSchemaToken::Any, s6); + + machine.addTransition(s1, XsdSchemaToken::Element, s2); + machine.addTransition(s1, XsdSchemaToken::Group, s3); + machine.addTransition(s1, XsdSchemaToken::Choice, s4); + machine.addTransition(s1, XsdSchemaToken::Sequence, s5); + machine.addTransition(s1, XsdSchemaToken::Any, s6); + + machine.addTransition(s2, XsdSchemaToken::Element, s2); + machine.addTransition(s2, XsdSchemaToken::Group, s3); + machine.addTransition(s2, XsdSchemaToken::Choice, s4); + machine.addTransition(s2, XsdSchemaToken::Sequence, s5); + machine.addTransition(s2, XsdSchemaToken::Any, s6); + + machine.addTransition(s3, XsdSchemaToken::Element, s2); + machine.addTransition(s3, XsdSchemaToken::Group, s3); + machine.addTransition(s3, XsdSchemaToken::Choice, s4); + machine.addTransition(s3, XsdSchemaToken::Sequence, s5); + machine.addTransition(s3, XsdSchemaToken::Any, s6); + + machine.addTransition(s4, XsdSchemaToken::Element, s2); + machine.addTransition(s4, XsdSchemaToken::Group, s3); + machine.addTransition(s4, XsdSchemaToken::Choice, s4); + machine.addTransition(s4, XsdSchemaToken::Sequence, s5); + machine.addTransition(s4, XsdSchemaToken::Any, s6); + + machine.addTransition(s5, XsdSchemaToken::Element, s2); + machine.addTransition(s5, XsdSchemaToken::Group, s3); + machine.addTransition(s5, XsdSchemaToken::Choice, s4); + machine.addTransition(s5, XsdSchemaToken::Sequence, s5); + machine.addTransition(s5, XsdSchemaToken::Any, s6); + + machine.addTransition(s6, XsdSchemaToken::Element, s2); + machine.addTransition(s6, XsdSchemaToken::Group, s3); + machine.addTransition(s6, XsdSchemaToken::Choice, s4); + machine.addTransition(s6, XsdSchemaToken::Sequence, s5); + machine.addTransition(s6, XsdSchemaToken::Any, s6); + + QVector data1, data2, data3, data4, data5, data6, data7, data8, data9; + + data1 << XsdSchemaToken::Annotation; + data2 << XsdSchemaToken::Annotation << XsdSchemaToken::Element << XsdSchemaToken::Sequence << XsdSchemaToken::Choice; + data3 << XsdSchemaToken::Group; + data4 << XsdSchemaToken::Element << XsdSchemaToken::Sequence << XsdSchemaToken::Annotation; + + QVERIFY(runTest(data1, machine) == true); + QVERIFY(runTest(data2, machine) == true); + QVERIFY(runTest(data3, machine) == true); + QVERIFY(runTest(data4, machine) == false); +} + +void tst_XMLPatternsSchema::stateMachineTest8() +{ + XsdStateMachine machine; + + // setup state machine for (annotation?) : any/selector/field/notation/include/import/referred attribute group/anyAttribute/all facets + const XsdStateMachine::StateId startState = machine.addState(XsdStateMachine::StartEndState); + const XsdStateMachine::StateId s1 = machine.addState(XsdStateMachine::EndState); + + machine.addTransition(startState, XsdSchemaToken::Annotation, s1); + + QVector data1, data2, data3, data4; + + data1 << XsdSchemaToken::Annotation; + data2 << XsdSchemaToken::Annotation << XsdSchemaToken::Element; + data3 << XsdSchemaToken::Group; + + QVERIFY(runTest(data1, machine) == true); + QVERIFY(runTest(data2, machine) == false); + QVERIFY(runTest(data3, machine) == false); + QVERIFY(runTest(data4, machine) == true); +} + +void tst_XMLPatternsSchema::stateMachineTest9() +{ + XsdStateMachine machine; + + // setup state machine for (annotation?, (selector, field+)) : unique/key/keyref + const XsdStateMachine::StateId startState = machine.addState(XsdStateMachine::StartState); + const XsdStateMachine::StateId s1 = machine.addState(XsdStateMachine::InternalState); + const XsdStateMachine::StateId s2 = machine.addState(XsdStateMachine::InternalState); + const XsdStateMachine::StateId s3 = machine.addState(XsdStateMachine::EndState); + + machine.addTransition(startState, XsdSchemaToken::Annotation, s1); + machine.addTransition(startState, XsdSchemaToken::Selector, s2); + + machine.addTransition(s1, XsdSchemaToken::Selector, s2); + machine.addTransition(s2, XsdSchemaToken::Field, s3); + machine.addTransition(s3, XsdSchemaToken::Field, s3); + + QVector data1, data2, data3, data4, data5; + + data1 << XsdSchemaToken::Annotation; + data2 << XsdSchemaToken::Annotation << XsdSchemaToken::Selector; + data3 << XsdSchemaToken::Annotation << XsdSchemaToken::Selector << XsdSchemaToken::Field; + data4 << XsdSchemaToken::Selector << XsdSchemaToken::Field; + data5 << XsdSchemaToken::Selector << XsdSchemaToken::Field << XsdSchemaToken::Field; + + QVERIFY(runTest(data1, machine) == false); + QVERIFY(runTest(data2, machine) == false); + QVERIFY(runTest(data3, machine) == true); + QVERIFY(runTest(data4, machine) == true); + QVERIFY(runTest(data5, machine) == true); +} + +void tst_XMLPatternsSchema::stateMachineTest10() +{ + XsdStateMachine machine; + + // setup state machine for (appinfo | documentation)* : annotation + const XsdStateMachine::StateId startState = machine.addState(XsdStateMachine::StartEndState); + const XsdStateMachine::StateId s1 = machine.addState(XsdStateMachine::EndState); + const XsdStateMachine::StateId s2 = machine.addState(XsdStateMachine::EndState); + + machine.addTransition(startState, XsdSchemaToken::Appinfo, s1); + machine.addTransition(startState, XsdSchemaToken::Documentation, s2); + + machine.addTransition(s1, XsdSchemaToken::Appinfo, s1); + machine.addTransition(s1, XsdSchemaToken::Documentation, s2); + + machine.addTransition(s2, XsdSchemaToken::Appinfo, s1); + machine.addTransition(s2, XsdSchemaToken::Documentation, s2); + + QVector data1, data2, data3, data4, data5; + + data1 << XsdSchemaToken::Appinfo; + data2 << XsdSchemaToken::Appinfo << XsdSchemaToken::Appinfo; + data3 << XsdSchemaToken::Documentation << XsdSchemaToken::Appinfo << XsdSchemaToken::Documentation; + data4 << XsdSchemaToken::Selector << XsdSchemaToken::Field; + + QVERIFY(runTest(data1, machine) == true); + QVERIFY(runTest(data2, machine) == true); + QVERIFY(runTest(data3, machine) == true); + QVERIFY(runTest(data4, machine) == false); + QVERIFY(runTest(data5, machine) == true); +} + +void tst_XMLPatternsSchema::stateMachineTest11() +{ + XsdStateMachine machine; + + // setup state machine for (annotation?, (restriction | list | union)) : simpleType + const XsdStateMachine::StateId startState = machine.addState(XsdStateMachine::StartState); + const XsdStateMachine::StateId s1 = machine.addState(XsdStateMachine::InternalState); + const XsdStateMachine::StateId s2 = machine.addState(XsdStateMachine::EndState); + const XsdStateMachine::StateId s3 = machine.addState(XsdStateMachine::EndState); + const XsdStateMachine::StateId s4 = machine.addState(XsdStateMachine::EndState); + + machine.addTransition(startState, XsdSchemaToken::Annotation, s1); + machine.addTransition(startState, XsdSchemaToken::Restriction, s2); + machine.addTransition(startState, XsdSchemaToken::List, s3); + machine.addTransition(startState, XsdSchemaToken::Union, s4); + + machine.addTransition(s1, XsdSchemaToken::Restriction, s2); + machine.addTransition(s1, XsdSchemaToken::List, s3); + machine.addTransition(s1, XsdSchemaToken::Union, s4); + + QVector data1, data2, data3, data4, data5, data6, data7, data8; + + data1 << XsdSchemaToken::Annotation; + data2 << XsdSchemaToken::Annotation << XsdSchemaToken::Restriction; + data3 << XsdSchemaToken::Annotation << XsdSchemaToken::List; + data4 << XsdSchemaToken::Annotation << XsdSchemaToken::Union; + data5 << XsdSchemaToken::Restriction; + data6 << XsdSchemaToken::List; + data7 << XsdSchemaToken::Union; + data8 << XsdSchemaToken::Union << XsdSchemaToken::Union; + + QVERIFY(runTest(data1, machine) == false); + QVERIFY(runTest(data2, machine) == true); + QVERIFY(runTest(data3, machine) == true); + QVERIFY(runTest(data4, machine) == true); + QVERIFY(runTest(data5, machine) == true); + QVERIFY(runTest(data6, machine) == true); + QVERIFY(runTest(data7, machine) == true); + QVERIFY(runTest(data8, machine) == false); +} + +void tst_XMLPatternsSchema::stateMachineTest12() +{ + XsdStateMachine machine; + + // setup state machine for (annotation?, (simpleType?, (minExclusive | minInclusive | maxExclusive | maxInclusive | totalDigits | fractionDigits | length | minLength | maxLength | enumeration | whiteSpace | pattern)*)) : simple type restriction + const XsdStateMachine::StateId startState = machine.addState(XsdStateMachine::StartEndState); + const XsdStateMachine::StateId s1 = machine.addState(XsdStateMachine::EndState); + const XsdStateMachine::StateId s2 = machine.addState(XsdStateMachine::EndState); + const XsdStateMachine::StateId s3 = machine.addState(XsdStateMachine::EndState); + + machine.addTransition(startState, XsdSchemaToken::Annotation, s1); + machine.addTransition(startState, XsdSchemaToken::SimpleType, s2); + machine.addTransition(startState, XsdSchemaToken::MinExclusive, s3); + machine.addTransition(startState, XsdSchemaToken::MinInclusive, s3); + machine.addTransition(startState, XsdSchemaToken::MaxExclusive, s3); + machine.addTransition(startState, XsdSchemaToken::MaxInclusive, s3); + machine.addTransition(startState, XsdSchemaToken::TotalDigits, s3); + machine.addTransition(startState, XsdSchemaToken::FractionDigits, s3); + machine.addTransition(startState, XsdSchemaToken::Length, s3); + machine.addTransition(startState, XsdSchemaToken::MinLength, s3); + machine.addTransition(startState, XsdSchemaToken::MaxLength, s3); + machine.addTransition(startState, XsdSchemaToken::Enumeration, s3); + machine.addTransition(startState, XsdSchemaToken::WhiteSpace, s3); + machine.addTransition(startState, XsdSchemaToken::Pattern, s3); + + machine.addTransition(s1, XsdSchemaToken::SimpleType, s2); + machine.addTransition(s1, XsdSchemaToken::MinExclusive, s3); + machine.addTransition(s1, XsdSchemaToken::MinInclusive, s3); + machine.addTransition(s1, XsdSchemaToken::MaxExclusive, s3); + machine.addTransition(s1, XsdSchemaToken::MaxInclusive, s3); + machine.addTransition(s1, XsdSchemaToken::TotalDigits, s3); + machine.addTransition(s1, XsdSchemaToken::FractionDigits, s3); + machine.addTransition(s1, XsdSchemaToken::Length, s3); + machine.addTransition(s1, XsdSchemaToken::MinLength, s3); + machine.addTransition(s1, XsdSchemaToken::MaxLength, s3); + machine.addTransition(s1, XsdSchemaToken::Enumeration, s3); + machine.addTransition(s1, XsdSchemaToken::WhiteSpace, s3); + machine.addTransition(s1, XsdSchemaToken::Pattern, s3); + + machine.addTransition(s2, XsdSchemaToken::MinExclusive, s3); + machine.addTransition(s2, XsdSchemaToken::MinInclusive, s3); + machine.addTransition(s2, XsdSchemaToken::MaxExclusive, s3); + machine.addTransition(s2, XsdSchemaToken::MaxInclusive, s3); + machine.addTransition(s2, XsdSchemaToken::TotalDigits, s3); + machine.addTransition(s2, XsdSchemaToken::FractionDigits, s3); + machine.addTransition(s2, XsdSchemaToken::Length, s3); + machine.addTransition(s2, XsdSchemaToken::MinLength, s3); + machine.addTransition(s2, XsdSchemaToken::MaxLength, s3); + machine.addTransition(s2, XsdSchemaToken::Enumeration, s3); + machine.addTransition(s2, XsdSchemaToken::WhiteSpace, s3); + machine.addTransition(s2, XsdSchemaToken::Pattern, s3); + + machine.addTransition(s3, XsdSchemaToken::MinExclusive, s3); + machine.addTransition(s3, XsdSchemaToken::MinInclusive, s3); + machine.addTransition(s3, XsdSchemaToken::MaxExclusive, s3); + machine.addTransition(s3, XsdSchemaToken::MaxInclusive, s3); + machine.addTransition(s3, XsdSchemaToken::TotalDigits, s3); + machine.addTransition(s3, XsdSchemaToken::FractionDigits, s3); + machine.addTransition(s3, XsdSchemaToken::Length, s3); + machine.addTransition(s3, XsdSchemaToken::MinLength, s3); + machine.addTransition(s3, XsdSchemaToken::MaxLength, s3); + machine.addTransition(s3, XsdSchemaToken::Enumeration, s3); + machine.addTransition(s3, XsdSchemaToken::WhiteSpace, s3); + machine.addTransition(s3, XsdSchemaToken::Pattern, s3); + + QVector data1, data2, data3, data4, data5; + + data1 << XsdSchemaToken::Annotation; + data2 << XsdSchemaToken::Annotation << XsdSchemaToken::Length << XsdSchemaToken::MaxLength; + data3 << XsdSchemaToken::Annotation << XsdSchemaToken::List; + data4 << XsdSchemaToken::SimpleType << XsdSchemaToken::Pattern; + + QVERIFY(runTest(data1, machine) == true); + QVERIFY(runTest(data2, machine) == true); + QVERIFY(runTest(data3, machine) == false); + QVERIFY(runTest(data4, machine) == true); + QVERIFY(runTest(data5, machine) == true); +} + +void tst_XMLPatternsSchema::stateMachineTest13() +{ + XsdStateMachine machine; + + // setup state machine for (annotation?, simpleType?) : list + const XsdStateMachine::StateId startState = machine.addState(XsdStateMachine::StartEndState); + const XsdStateMachine::StateId s1 = machine.addState(XsdStateMachine::EndState); + const XsdStateMachine::StateId s2 = machine.addState(XsdStateMachine::EndState); + + machine.addTransition(startState, XsdSchemaToken::Annotation, s1); + machine.addTransition(startState, XsdSchemaToken::SimpleType, s2); + + machine.addTransition(s1, XsdSchemaToken::SimpleType, s2); + + QVector data1, data2, data3, data4, data5; + + data1 << XsdSchemaToken::Annotation; + data2 << XsdSchemaToken::Annotation << XsdSchemaToken::SimpleType; + data3 << XsdSchemaToken::SimpleType; + data4 << XsdSchemaToken::SimpleType << XsdSchemaToken::SimpleType; + + QVERIFY(runTest(data1, machine) == true); + QVERIFY(runTest(data2, machine) == true); + QVERIFY(runTest(data3, machine) == true); + QVERIFY(runTest(data4, machine) == false); + QVERIFY(runTest(data5, machine) == true); +} + +void tst_XMLPatternsSchema::stateMachineTest14() +{ + XsdStateMachine machine; + + // setup state machine for (annotation?, simpleType*) : union + const XsdStateMachine::StateId startState = machine.addState(XsdStateMachine::StartEndState); + const XsdStateMachine::StateId s1 = machine.addState(XsdStateMachine::EndState); + const XsdStateMachine::StateId s2 = machine.addState(XsdStateMachine::EndState); + + machine.addTransition(startState, XsdSchemaToken::Annotation, s1); + machine.addTransition(startState, XsdSchemaToken::SimpleType, s2); + + machine.addTransition(s1, XsdSchemaToken::SimpleType, s2); + machine.addTransition(s2, XsdSchemaToken::SimpleType, s2); + + QVector data1, data2, data3, data4, data5, data6; + + data1 << XsdSchemaToken::Annotation; + data2 << XsdSchemaToken::Annotation << XsdSchemaToken::SimpleType; + data3 << XsdSchemaToken::SimpleType; + data4 << XsdSchemaToken::SimpleType << XsdSchemaToken::SimpleType; + data6 << XsdSchemaToken::Annotation << XsdSchemaToken::Annotation; + + QVERIFY(runTest(data1, machine) == true); + QVERIFY(runTest(data2, machine) == true); + QVERIFY(runTest(data3, machine) == true); + QVERIFY(runTest(data4, machine) == true); + QVERIFY(runTest(data5, machine) == true); + QVERIFY(runTest(data6, machine) == false); +} + +void tst_XMLPatternsSchema::stateMachineTest15() +{ + XsdStateMachine machine; + + // setup state machine for ((include | import | redefine | annotation)*, (((simpleType | complexType | group | attributeGroup) | element | attribute | notation), annotation*)*) : schema + const XsdStateMachine::StateId startState = machine.addState(XsdStateMachine::StartEndState); + const XsdStateMachine::StateId s1 = machine.addState(XsdStateMachine::EndState); + const XsdStateMachine::StateId s2 = machine.addState(XsdStateMachine::EndState); + const XsdStateMachine::StateId s3 = machine.addState(XsdStateMachine::EndState); + + machine.addTransition(startState, XsdSchemaToken::Include, s1); + machine.addTransition(startState, XsdSchemaToken::Import, s1); + machine.addTransition(startState, XsdSchemaToken::Redefine, s1); + machine.addTransition(startState, XsdSchemaToken::Annotation, s1); + machine.addTransition(startState, XsdSchemaToken::SimpleType, s2); + machine.addTransition(startState, XsdSchemaToken::ComplexType, s2); + machine.addTransition(startState, XsdSchemaToken::Group, s2); + machine.addTransition(startState, XsdSchemaToken::AttributeGroup, s2); + machine.addTransition(startState, XsdSchemaToken::Element, s2); + machine.addTransition(startState, XsdSchemaToken::Attribute, s2); + machine.addTransition(startState, XsdSchemaToken::Notation, s2); + + machine.addTransition(s1, XsdSchemaToken::Include, s1); + machine.addTransition(s1, XsdSchemaToken::Import, s1); + machine.addTransition(s1, XsdSchemaToken::Redefine, s1); + machine.addTransition(s1, XsdSchemaToken::Annotation, s1); + machine.addTransition(s1, XsdSchemaToken::SimpleType, s2); + machine.addTransition(s1, XsdSchemaToken::ComplexType, s2); + machine.addTransition(s1, XsdSchemaToken::Group, s2); + machine.addTransition(s1, XsdSchemaToken::AttributeGroup, s2); + machine.addTransition(s1, XsdSchemaToken::Element, s2); + machine.addTransition(s1, XsdSchemaToken::Attribute, s2); + machine.addTransition(s1, XsdSchemaToken::Notation, s2); + + machine.addTransition(s2, XsdSchemaToken::SimpleType, s2); + machine.addTransition(s2, XsdSchemaToken::ComplexType, s2); + machine.addTransition(s2, XsdSchemaToken::Group, s2); + machine.addTransition(s2, XsdSchemaToken::AttributeGroup, s2); + machine.addTransition(s2, XsdSchemaToken::Element, s2); + machine.addTransition(s2, XsdSchemaToken::Attribute, s2); + machine.addTransition(s2, XsdSchemaToken::Notation, s2); + machine.addTransition(s2, XsdSchemaToken::Annotation, s3); + + machine.addTransition(s3, XsdSchemaToken::SimpleType, s2); + machine.addTransition(s3, XsdSchemaToken::ComplexType, s2); + machine.addTransition(s3, XsdSchemaToken::Group, s2); + machine.addTransition(s3, XsdSchemaToken::AttributeGroup, s2); + machine.addTransition(s3, XsdSchemaToken::Element, s2); + machine.addTransition(s3, XsdSchemaToken::Attribute, s2); + machine.addTransition(s3, XsdSchemaToken::Notation, s2); + machine.addTransition(s3, XsdSchemaToken::Annotation, s3); + + QVector data1, data2, data3, data4, data5, data6; + + data1 << XsdSchemaToken::Annotation << XsdSchemaToken::Import << XsdSchemaToken::SimpleType << XsdSchemaToken::Annotation; + data2 << XsdSchemaToken::SimpleType; + data3 << XsdSchemaToken::Annotation << XsdSchemaToken::Import << XsdSchemaToken::Include << XsdSchemaToken::Import; + data4 << XsdSchemaToken::SimpleType << XsdSchemaToken::ComplexType << XsdSchemaToken::Annotation << XsdSchemaToken::Attribute; + data5 << XsdSchemaToken::SimpleType << XsdSchemaToken::Include << XsdSchemaToken::Annotation << XsdSchemaToken::Attribute; + + QVERIFY(runTest(data1, machine) == true); + QVERIFY(runTest(data2, machine) == true); + QVERIFY(runTest(data3, machine) == true); + QVERIFY(runTest(data4, machine) == true); + QVERIFY(runTest(data5, machine) == false); + QVERIFY(runTest(data6, machine) == true); +} + +void tst_XMLPatternsSchema::stateMachineTest16() +{ + XsdStateMachine machine; + + // setup state machine for (annotation | (simpleType | complexType | group | attributeGroup))* : redefine + const XsdStateMachine::StateId startState = machine.addState(XsdStateMachine::StartEndState); + const XsdStateMachine::StateId s1 = machine.addState(XsdStateMachine::EndState); + + machine.addTransition(startState, XsdSchemaToken::Annotation, s1); + machine.addTransition(startState, XsdSchemaToken::SimpleType, s1); + machine.addTransition(startState, XsdSchemaToken::ComplexType, s1); + machine.addTransition(startState, XsdSchemaToken::Group, s1); + machine.addTransition(startState, XsdSchemaToken::AttributeGroup, s1); + + machine.addTransition(s1, XsdSchemaToken::Annotation, s1); + machine.addTransition(s1, XsdSchemaToken::SimpleType, s1); + machine.addTransition(s1, XsdSchemaToken::ComplexType, s1); + machine.addTransition(s1, XsdSchemaToken::Group, s1); + machine.addTransition(s1, XsdSchemaToken::AttributeGroup, s1); + + QVector data1, data2, data3, data4, data5, data6; + + data1 << XsdSchemaToken::Annotation; + data2 << XsdSchemaToken::Annotation << XsdSchemaToken::SimpleType; + data3 << XsdSchemaToken::SimpleType; + data4 << XsdSchemaToken::SimpleType << XsdSchemaToken::SimpleType; + data6 << XsdSchemaToken::Annotation << XsdSchemaToken::Annotation; + + QVERIFY(runTest(data1, machine) == true); + QVERIFY(runTest(data2, machine) == true); + QVERIFY(runTest(data3, machine) == true); + QVERIFY(runTest(data4, machine) == true); + QVERIFY(runTest(data5, machine) == true); + QVERIFY(runTest(data6, machine) == true); +} + +void tst_XMLPatternsSchema::stateMachineTest17() +{ + XsdStateMachine machine; + + // setup state machine for (annotation?, (restriction | extension)) : simpleContent + const XsdStateMachine::StateId startState = machine.addState(XsdStateMachine::StartState); + const XsdStateMachine::StateId s1 = machine.addState(XsdStateMachine::InternalState); + const XsdStateMachine::StateId s2 = machine.addState(XsdStateMachine::EndState); + + machine.addTransition(startState, XsdSchemaToken::Annotation, s1); + machine.addTransition(startState, XsdSchemaToken::Restriction, s2); + machine.addTransition(startState, XsdSchemaToken::Extension, s2); + + machine.addTransition(s1, XsdSchemaToken::Restriction, s2); + machine.addTransition(s1, XsdSchemaToken::Extension, s2); + + QVector data1, data2, data3, data4, data5, data6; + + data1 << XsdSchemaToken::Annotation; + data2 << XsdSchemaToken::Annotation << XsdSchemaToken::Extension; + data3 << XsdSchemaToken::Restriction; + data4 << XsdSchemaToken::Extension << XsdSchemaToken::Restriction; + data5 << XsdSchemaToken::Annotation << XsdSchemaToken::Annotation; + + QVERIFY(runTest(data1, machine) == false); + QVERIFY(runTest(data2, machine) == true); + QVERIFY(runTest(data3, machine) == true); + QVERIFY(runTest(data4, machine) == false); + QVERIFY(runTest(data5, machine) == false); + QVERIFY(runTest(data6, machine) == false); +} + +void tst_XMLPatternsSchema::stateMachineTest18() +{ + XsdStateMachine machine; + + // setup state machine for (annotation?, (simpleType?, (minExclusive | minInclusive | maxExclusive | maxInclusive | totalDigits | fractionDigits | length | minLength | maxLength | enumeration | whiteSpace | pattern)*)?, ((attribute | attributeGroup)*, anyAttribute?)) : simpleContent restriction + const XsdStateMachine::StateId startState = machine.addState(XsdStateMachine::StartEndState); + const XsdStateMachine::StateId s1 = machine.addState(XsdStateMachine::EndState); + const XsdStateMachine::StateId s2 = machine.addState(XsdStateMachine::EndState); + const XsdStateMachine::StateId s3 = machine.addState(XsdStateMachine::EndState); + const XsdStateMachine::StateId s4 = machine.addState(XsdStateMachine::EndState); + const XsdStateMachine::StateId s5 = machine.addState(XsdStateMachine::EndState); + + machine.addTransition(startState, XsdSchemaToken::Annotation, s1); + machine.addTransition(startState, XsdSchemaToken::SimpleType, s2); + machine.addTransition(startState, XsdSchemaToken::MinExclusive, s3); + machine.addTransition(startState, XsdSchemaToken::MinInclusive, s3); + machine.addTransition(startState, XsdSchemaToken::MaxExclusive, s3); + machine.addTransition(startState, XsdSchemaToken::MaxInclusive, s3); + machine.addTransition(startState, XsdSchemaToken::TotalDigits, s3); + machine.addTransition(startState, XsdSchemaToken::FractionDigits, s3); + machine.addTransition(startState, XsdSchemaToken::Length, s3); + machine.addTransition(startState, XsdSchemaToken::MinLength, s3); + machine.addTransition(startState, XsdSchemaToken::MaxLength, s3); + machine.addTransition(startState, XsdSchemaToken::Enumeration, s3); + machine.addTransition(startState, XsdSchemaToken::WhiteSpace, s3); + machine.addTransition(startState, XsdSchemaToken::Pattern, s3); + machine.addTransition(startState, XsdSchemaToken::Attribute, s4); + machine.addTransition(startState, XsdSchemaToken::AttributeGroup, s4); + machine.addTransition(startState, XsdSchemaToken::AnyAttribute, s5); + + machine.addTransition(s1, XsdSchemaToken::SimpleType, s2); + machine.addTransition(s1, XsdSchemaToken::MinExclusive, s3); + machine.addTransition(s1, XsdSchemaToken::MinInclusive, s3); + machine.addTransition(s1, XsdSchemaToken::MaxExclusive, s3); + machine.addTransition(s1, XsdSchemaToken::MaxInclusive, s3); + machine.addTransition(s1, XsdSchemaToken::TotalDigits, s3); + machine.addTransition(s1, XsdSchemaToken::FractionDigits, s3); + machine.addTransition(s1, XsdSchemaToken::Length, s3); + machine.addTransition(s1, XsdSchemaToken::MinLength, s3); + machine.addTransition(s1, XsdSchemaToken::MaxLength, s3); + machine.addTransition(s1, XsdSchemaToken::Enumeration, s3); + machine.addTransition(s1, XsdSchemaToken::WhiteSpace, s3); + machine.addTransition(s1, XsdSchemaToken::Pattern, s3); + machine.addTransition(s1, XsdSchemaToken::Attribute, s4); + machine.addTransition(s1, XsdSchemaToken::AttributeGroup, s4); + machine.addTransition(s1, XsdSchemaToken::AnyAttribute, s5); + + machine.addTransition(s2, XsdSchemaToken::MinExclusive, s3); + machine.addTransition(s2, XsdSchemaToken::MinInclusive, s3); + machine.addTransition(s2, XsdSchemaToken::MaxExclusive, s3); + machine.addTransition(s2, XsdSchemaToken::MaxInclusive, s3); + machine.addTransition(s2, XsdSchemaToken::TotalDigits, s3); + machine.addTransition(s2, XsdSchemaToken::FractionDigits, s3); + machine.addTransition(s2, XsdSchemaToken::Length, s3); + machine.addTransition(s2, XsdSchemaToken::MinLength, s3); + machine.addTransition(s2, XsdSchemaToken::MaxLength, s3); + machine.addTransition(s2, XsdSchemaToken::Enumeration, s3); + machine.addTransition(s2, XsdSchemaToken::WhiteSpace, s3); + machine.addTransition(s2, XsdSchemaToken::Pattern, s3); + machine.addTransition(s2, XsdSchemaToken::Attribute, s4); + machine.addTransition(s2, XsdSchemaToken::AttributeGroup, s4); + machine.addTransition(s2, XsdSchemaToken::AnyAttribute, s5); + + machine.addTransition(s3, XsdSchemaToken::MinExclusive, s3); + machine.addTransition(s3, XsdSchemaToken::MinInclusive, s3); + machine.addTransition(s3, XsdSchemaToken::MaxExclusive, s3); + machine.addTransition(s3, XsdSchemaToken::MaxInclusive, s3); + machine.addTransition(s3, XsdSchemaToken::TotalDigits, s3); + machine.addTransition(s3, XsdSchemaToken::FractionDigits, s3); + machine.addTransition(s3, XsdSchemaToken::Length, s3); + machine.addTransition(s3, XsdSchemaToken::MinLength, s3); + machine.addTransition(s3, XsdSchemaToken::MaxLength, s3); + machine.addTransition(s3, XsdSchemaToken::Enumeration, s3); + machine.addTransition(s3, XsdSchemaToken::WhiteSpace, s3); + machine.addTransition(s3, XsdSchemaToken::Pattern, s3); + machine.addTransition(s3, XsdSchemaToken::Attribute, s4); + machine.addTransition(s3, XsdSchemaToken::AttributeGroup, s4); + machine.addTransition(s3, XsdSchemaToken::AnyAttribute, s5); + + machine.addTransition(s4, XsdSchemaToken::Attribute, s4); + machine.addTransition(s4, XsdSchemaToken::AttributeGroup, s4); + machine.addTransition(s4, XsdSchemaToken::AnyAttribute, s5); + + QVector data1, data2, data3, data4, data5, data6; + + data1 << XsdSchemaToken::Annotation; + data2 << XsdSchemaToken::SimpleType << XsdSchemaToken::MinExclusive << XsdSchemaToken::MaxExclusive; + data3 << XsdSchemaToken::AnyAttribute << XsdSchemaToken::Attribute; + data4 << XsdSchemaToken::MinExclusive << XsdSchemaToken::TotalDigits << XsdSchemaToken::Enumeration; + data5 << XsdSchemaToken::Annotation << XsdSchemaToken::Annotation; + + QVERIFY(runTest(data1, machine) == true); + QVERIFY(runTest(data2, machine) == true); + QVERIFY(runTest(data3, machine) == false); + QVERIFY(runTest(data4, machine) == true); + QVERIFY(runTest(data5, machine) == false); + QVERIFY(runTest(data6, machine) == true); +} + +void tst_XMLPatternsSchema::stateMachineTest19() +{ + XsdStateMachine machine; + + // setup state machine for (annotation?, (group | all | choice | sequence)?, ((attribute | attributeGroup)*, anyAttribute?)) : complex content restriction/complex content extension + const XsdStateMachine::StateId startState = machine.addState(XsdStateMachine::StartEndState); + const XsdStateMachine::StateId s1 = machine.addState(XsdStateMachine::EndState); + const XsdStateMachine::StateId s2 = machine.addState(XsdStateMachine::EndState); + const XsdStateMachine::StateId s3 = machine.addState(XsdStateMachine::EndState); + const XsdStateMachine::StateId s4 = machine.addState(XsdStateMachine::EndState); + + machine.addTransition(startState, XsdSchemaToken::Annotation, s1); + machine.addTransition(startState, XsdSchemaToken::Group, s2); + machine.addTransition(startState, XsdSchemaToken::All, s2); + machine.addTransition(startState, XsdSchemaToken::Choice, s2); + machine.addTransition(startState, XsdSchemaToken::Sequence, s2); + machine.addTransition(startState, XsdSchemaToken::Attribute, s3); + machine.addTransition(startState, XsdSchemaToken::AttributeGroup, s3); + machine.addTransition(startState, XsdSchemaToken::AnyAttribute, s4); + + machine.addTransition(s1, XsdSchemaToken::Group, s2); + machine.addTransition(s1, XsdSchemaToken::All, s2); + machine.addTransition(s1, XsdSchemaToken::Choice, s2); + machine.addTransition(s1, XsdSchemaToken::Sequence, s2); + machine.addTransition(s1, XsdSchemaToken::Attribute, s3); + machine.addTransition(s1, XsdSchemaToken::AttributeGroup, s3); + machine.addTransition(s1, XsdSchemaToken::AnyAttribute, s4); + + machine.addTransition(s2, XsdSchemaToken::Attribute, s3); + machine.addTransition(s2, XsdSchemaToken::AttributeGroup, s3); + machine.addTransition(s2, XsdSchemaToken::AnyAttribute, s4); + + machine.addTransition(s3, XsdSchemaToken::Attribute, s3); + machine.addTransition(s3, XsdSchemaToken::AttributeGroup, s3); + machine.addTransition(s3, XsdSchemaToken::AnyAttribute, s4); + + QVector data1, data2, data3, data4, data5, data6; + + data1 << XsdSchemaToken::Annotation; + data2 << XsdSchemaToken::Annotation << XsdSchemaToken::Group; + data3 << XsdSchemaToken::Annotation << XsdSchemaToken::Group << XsdSchemaToken::Sequence; + data4 << XsdSchemaToken::Attribute << XsdSchemaToken::Attribute; + data5 << XsdSchemaToken::Attribute << XsdSchemaToken::Sequence; + data6 << XsdSchemaToken::Annotation << XsdSchemaToken::Annotation; + + QVERIFY(runTest(data1, machine) == true); + QVERIFY(runTest(data2, machine) == true); + QVERIFY(runTest(data3, machine) == false); + QVERIFY(runTest(data4, machine) == true); + QVERIFY(runTest(data5, machine) == false); + QVERIFY(runTest(data6, machine) == false); +} + +QTEST_MAIN(tst_XMLPatternsSchema) +#include "tst_xmlpatternsschema.moc" diff --git a/tests/auto/xmlpatternsschema/xmlpatternsschema.pro b/tests/auto/xmlpatternsschema/xmlpatternsschema.pro new file mode 100644 index 0000000..2ba869a --- /dev/null +++ b/tests/auto/xmlpatternsschema/xmlpatternsschema.pro @@ -0,0 +1,6 @@ +load(qttest_p4) +SOURCES += tst_xmlpatternsschema.cpp \ + +include (../xmlpatterns.pri) + +INCLUDEPATH += $$QT_BUILD_TREE/include/QtXmlPatterns/private diff --git a/tests/auto/xmlpatternsschemats/.gitignore b/tests/auto/xmlpatternsschemats/.gitignore new file mode 100644 index 0000000..5fd11f8 --- /dev/null +++ b/tests/auto/xmlpatternsschemats/.gitignore @@ -0,0 +1,4 @@ +CandidateBaseline.xml +runTests +tst_xmlpatternsschemats +runTests diff --git a/tests/auto/xmlpatternsschemats/Baseline.xml b/tests/auto/xmlpatternsschemats/Baseline.xml new file mode 100644 index 0000000..9baef9c --- /dev/null +++ b/tests/auto/xmlpatternsschemats/Baseline.xml @@ -0,0 +1,2 @@ + +

Patternist is an implementation written in C++ and with the Qt/KDE libraries. It is licensed under GNU LGPL and part of KDE, the K Desktop Environment.

XQuery
\ No newline at end of file diff --git a/tests/auto/xmlpatternsschemats/TESTSUITE/.gitignore b/tests/auto/xmlpatternsschemats/TESTSUITE/.gitignore new file mode 100644 index 0000000..35cb85e --- /dev/null +++ b/tests/auto/xmlpatternsschemats/TESTSUITE/.gitignore @@ -0,0 +1,3 @@ +testSuites.xml +xmlschema2006-11-06 +xmlschema2006-11-06-new diff --git a/tests/auto/xmlpatternsschemats/TESTSUITE/unifyCatalog.xsl b/tests/auto/xmlpatternsschemats/TESTSUITE/unifyCatalog.xsl new file mode 100644 index 0000000..325f626 --- /dev/null +++ b/tests/auto/xmlpatternsschemats/TESTSUITE/unifyCatalog.xsl @@ -0,0 +1,21 @@ + + + + + + + + + + + + + + + + + + diff --git a/tests/auto/xmlpatternsschemats/TESTSUITE/updateSuite.sh b/tests/auto/xmlpatternsschemats/TESTSUITE/updateSuite.sh new file mode 100755 index 0000000..1770f1e --- /dev/null +++ b/tests/auto/xmlpatternsschemats/TESTSUITE/updateSuite.sh @@ -0,0 +1,20 @@ +#!/bin/bash + +# This script updates the suite from W3C's server. +# +# NOTE: the files checked out CANNOT be added to Trolltech's +# repository at the moment, due to legal complications. + +DIRECTORY_NAME="xmlschema2006-11-06" +ARCHIVE_NAME="xsts-2007-06-20.tar.gz" + +rm -Rf $DIRECTORY_NAME + +wget http://www.w3.org/XML/2004/xml-schema-test-suite/xmlschema2006-11-06/$ARCHIVE_NAME +tar -xzf $ARCHIVE_NAME +rm $ARCHIVE_NAME + +CVSROOT=:pserver:anonymous@dev.w3.org:/sources/public cvs login +CVSROOT=:pserver:anonymous@dev.w3.org:/sources/public cvs checkout -d xmlschema2006-11-06-new XML/xml-schema-test-suite/2004-01-14/xmlschema2006-11-06 + +java net.sf.saxon.Transform -xsl:unifyCatalog.xsl $DIRECTORY_NAME/suite.xml > testSuites.xml diff --git a/tests/auto/xmlpatternsschemats/tst_xmlpatternsschemats.cpp b/tests/auto/xmlpatternsschemats/tst_xmlpatternsschemats.cpp new file mode 100644 index 0000000..7a6f4c8 --- /dev/null +++ b/tests/auto/xmlpatternsschemats/tst_xmlpatternsschemats.cpp @@ -0,0 +1,44 @@ +/**************************************************************************** +** +** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +****************************************************************************/ + +#include + +#ifdef QTEST_XMLPATTERNS + +#include "tst_suitetest.h" + +/*! + \internal + \brief Test QXsdSchemaParser against W3C's XSD test suite. + */ +class tst_XmlPatternsSchemaTS : public tst_SuiteTest +{ + Q_OBJECT +public: + tst_XmlPatternsSchemaTS(); +protected: + virtual void catalogPath(QString &write) const; +}; + +tst_XmlPatternsSchemaTS::tst_XmlPatternsSchemaTS() + : tst_SuiteTest(tst_SuiteTest::XsdSuite) +{ +} + +void tst_XmlPatternsSchemaTS::catalogPath(QString &write) const +{ + write = QLatin1String("TESTSUITE/testSuites.xml"); +} + +QTEST_MAIN(tst_XmlPatternsSchemaTS) + +#include "tst_xmlpatternsschemats.moc" +#else +QTEST_NOOP_MAIN +#endif + +// vim: et:ts=4:sw=4:sts=4 diff --git a/tests/auto/xmlpatternsschemats/xmlpatternsschemats.pro b/tests/auto/xmlpatternsschemats/xmlpatternsschemats.pro new file mode 100644 index 0000000..4978c35 --- /dev/null +++ b/tests/auto/xmlpatternsschemats/xmlpatternsschemats.pro @@ -0,0 +1,23 @@ +load(qttest_p4) +SOURCES += tst_xmlpatternsschemats.cpp \ + ../qxmlquery/TestFundament.cpp + +include (../xmlpatterns.pri) + +contains(QT_CONFIG,xmlpatterns) { +HEADERS += ../xmlpatternsxqts/test/tst_suitetest.h +SOURCES += ../xmlpatternsxqts/test/tst_suitetest.cpp +} + +PATTERNIST_SDK = QtXmlPatternsSDK +if(!debug_and_release|build_pass):CONFIG(debug, debug|release) { + win32:PATTERNIST_SDK = $${PATTERNIST_SDK}d + else: PATTERNIST_SDK = $${PATTERNIST_SDK}_debug +} +LIBS += -l$$PATTERNIST_SDK + +INCLUDEPATH += $$QT_SOURCE_TREE/tests/auto/xmlpatternsxqts/lib/ \ + $$QT_BUILD_TREE/include/QtXmlPatterns/private \ + $$QT_SOURCE_TREE/tests/auto/xmlpatternsxqts/test \ + ../xmlpatternsxqts/test \ + ../xmlpatternsxqts/lib diff --git a/tests/auto/xmlpatternsvalidator/files/instance.xml b/tests/auto/xmlpatternsvalidator/files/instance.xml new file mode 100644 index 0000000..544ff8c --- /dev/null +++ b/tests/auto/xmlpatternsvalidator/files/instance.xml @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/tests/auto/xmlpatternsvalidator/files/invalid_schema.xsd b/tests/auto/xmlpatternsvalidator/files/invalid_schema.xsd new file mode 100644 index 0000000..99e3525 --- /dev/null +++ b/tests/auto/xmlpatternsvalidator/files/invalid_schema.xsd @@ -0,0 +1,12 @@ + + + + + + + + + + + + diff --git a/tests/auto/xmlpatternsvalidator/files/other_valid_schema.xsd b/tests/auto/xmlpatternsvalidator/files/other_valid_schema.xsd new file mode 100644 index 0000000..850ed92 --- /dev/null +++ b/tests/auto/xmlpatternsvalidator/files/other_valid_schema.xsd @@ -0,0 +1,12 @@ + + + + + + + + + + + + diff --git a/tests/auto/xmlpatternsvalidator/files/sa_invalid_instance.xml b/tests/auto/xmlpatternsvalidator/files/sa_invalid_instance.xml new file mode 100644 index 0000000..1804e88 --- /dev/null +++ b/tests/auto/xmlpatternsvalidator/files/sa_invalid_instance.xml @@ -0,0 +1,3 @@ + + + diff --git a/tests/auto/xmlpatternsvalidator/files/sa_valid_instance.xml b/tests/auto/xmlpatternsvalidator/files/sa_valid_instance.xml new file mode 100644 index 0000000..47c980e --- /dev/null +++ b/tests/auto/xmlpatternsvalidator/files/sa_valid_instance.xml @@ -0,0 +1,3 @@ + + + diff --git a/tests/auto/xmlpatternsvalidator/files/valid_schema.xsd b/tests/auto/xmlpatternsvalidator/files/valid_schema.xsd new file mode 100644 index 0000000..a1b765a --- /dev/null +++ b/tests/auto/xmlpatternsvalidator/files/valid_schema.xsd @@ -0,0 +1,12 @@ + + + + + + + + + + + + diff --git a/tests/auto/xmlpatternsvalidator/tst_xmlpatternsvalidator.cpp b/tests/auto/xmlpatternsvalidator/tst_xmlpatternsvalidator.cpp new file mode 100644 index 0000000..9643e56 --- /dev/null +++ b/tests/auto/xmlpatternsvalidator/tst_xmlpatternsvalidator.cpp @@ -0,0 +1,174 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +****************************************************************************/ + +#include +#include + +#ifdef QTEST_XMLPATTERNS + +#include "../qxmlquery/TestFundament.h" +#include "../network-settings.h" + +/*! + \class tst_XmlPatterns + \internal + \since 4.6 + \brief Tests the command line interface, \c xmlpatternsvalidator, for the XML validation code. + */ +class tst_XmlPatternsValidator : public QObject + , private TestFundament +{ + Q_OBJECT + +public: + tst_XmlPatternsValidator(); + +private Q_SLOTS: + void initTestCase(); + void xsdSupport(); + void xsdSupport_data() const; + +private: + const QString m_command; + bool m_dontRun; +}; + +tst_XmlPatternsValidator::tst_XmlPatternsValidator() + : m_command(QLatin1String("xmlpatternsvalidator")) + , m_dontRun(false) +{ +} + +void tst_XmlPatternsValidator::initTestCase() +{ + QProcess process; + process.start(m_command); + + if(!process.waitForFinished()) + { + m_dontRun = true; + QEXPECT_FAIL("", "The command line tool is not in the path, most likely because Qt " + "has been partically built, such as only the sub-src rule. No tests will be run.", Abort); + QVERIFY(false); + } +} + +void tst_XmlPatternsValidator::xsdSupport() +{ + if(m_dontRun) + QSKIP("The command line utility is not in the path.", SkipAll); + +#ifdef Q_OS_WINCE + QSKIP("WinCE: This test uses unsupported WinCE functionality", SkipAll); +#endif + + QFETCH(int, expectedExitCode); + QFETCH(QStringList, arguments); + QFETCH(QString, cwd); + + QProcess process; + + if(!cwd.isEmpty()) + process.setWorkingDirectory(inputFile(cwd)); + + process.start(m_command, arguments); + + QCOMPARE(process.exitStatus(), QProcess::NormalExit); + QVERIFY(process.waitForFinished()); + + if(process.exitCode() != expectedExitCode) + QTextStream(stderr) << "foo:" << process.readAllStandardError(); + + QCOMPARE(process.exitCode(), expectedExitCode); +} + +void tst_XmlPatternsValidator::xsdSupport_data() const +{ +#ifdef Q_OS_WINCE + return; +#endif + + QTest::addColumn("expectedExitCode"); + QTest::addColumn("arguments"); + QTest::addColumn("cwd"); + + QTest::newRow("No arguments") + << 2 + << QStringList() + << QString(); + + QTest::newRow("A valid schema") + << 0 + << QStringList(QLatin1String("files/valid_schema.xsd")) + << QString(); + + QTest::newRow("An invalid schema") + << 1 + << QStringList(QLatin1String("files/invalid_schema.xsd")) + << QString(); + + QTest::newRow("An instance and valid schema") + << 0 + << (QStringList() << QLatin1String("files/instance.xml") + << QLatin1String("files/valid_schema.xsd")) + << QString(); + + QTest::newRow("An instance and invalid schema") + << 1 + << (QStringList() << QLatin1String("files/instance.xml") + << QLatin1String("files/invalid_schema.xsd")) + << QString(); + + QTest::newRow("An instance and not matching schema") + << 1 + << (QStringList() << QLatin1String("files/instance.xml") + << QLatin1String("files/other_valid_schema.xsd")) + << QString(); + + QTest::newRow("Two instance documents") + << 1 + << (QStringList() << QLatin1String("files/instance.xml") + << QLatin1String("files/instance.xml")) + << QString(); + + QTest::newRow("Three instance documents") + << 2 + << (QStringList() << QLatin1String("files/instance.xml") + << QLatin1String("files/instance.xml") + << QLatin1String("files/instance.xml")) + << QString(); + + QTest::newRow("Two schema documents") + << 1 + << (QStringList() << QLatin1String("files/valid_schema.xsd") + << QLatin1String("files/valid_schema.xsd")) + << QString(); + + QTest::newRow("A schema aware valid instance document") + << 0 + << (QStringList() << QLatin1String("files/sa_valid_instance.xml")) + << QString(); + + QTest::newRow("A schema aware invalid instance document") + << 1 + << (QStringList() << QLatin1String("files/sa_invalid_instance.xml")) + << QString(); + + QTest::newRow("A non-schema aware instance document") + << 1 + << (QStringList() << QLatin1String("files/instance.xml")) + << QString(); +} + +QTEST_MAIN(tst_XmlPatternsValidator) + +#include "tst_xmlpatternsvalidator.moc" +#else +QTEST_NOOP_MAIN +#endif + +// vim: et:ts=4:sw=4:sts=4 diff --git a/tests/auto/xmlpatternsvalidator/xmlpatternsvalidator.pro b/tests/auto/xmlpatternsvalidator/xmlpatternsvalidator.pro new file mode 100644 index 0000000..7091840 --- /dev/null +++ b/tests/auto/xmlpatternsvalidator/xmlpatternsvalidator.pro @@ -0,0 +1,5 @@ +load(qttest_p4) +SOURCES += tst_xmlpatternsvalidator.cpp \ + ../qxmlquery/TestFundament.cpp + +include (../xmlpatterns.pri) diff --git a/tests/auto/xmlpatternsview/view/MainWindow.cpp b/tests/auto/xmlpatternsview/view/MainWindow.cpp index 57aaca0..b5424a3 100644 --- a/tests/auto/xmlpatternsview/view/MainWindow.cpp +++ b/tests/auto/xmlpatternsview/view/MainWindow.cpp @@ -220,7 +220,8 @@ void MainWindow::on_actionOpen_triggered() if(fileName.isNull()) return; - openCatalog(QUrl::fromLocalFile(fileName), true, false); + m_currentSuiteType = TestSuite::XQuerySuite; + openCatalog(QUrl::fromLocalFile(fileName), true, TestSuite::XQuerySuite); } void MainWindow::on_actionOpenXSLTSCatalog_triggered() @@ -234,18 +235,34 @@ void MainWindow::on_actionOpenXSLTSCatalog_triggered() if(fileName.isNull()) return; - openCatalog(QUrl::fromLocalFile(fileName), true, true); + m_currentSuiteType = TestSuite::XsltSuite; + openCatalog(QUrl::fromLocalFile(fileName), true, TestSuite::XsltSuite); +} + +void MainWindow::on_actionOpenXSDTSCatalog_triggered() +{ + const QString fileName(QFileDialog::getOpenFileName(this, + QLatin1String("Open Test Suite Catalog"), + m_previousOpenedCatalog.toLocalFile(), + QLatin1String("Test Suite Catalog file (*.xml)"))); + + /* "If the user presses Cancel, it returns a null string." */ + if(fileName.isNull()) + return; + + m_currentSuiteType = TestSuite::XsdSuite; + openCatalog(QUrl::fromLocalFile(fileName), true, TestSuite::XsdSuite); } void MainWindow::openCatalog(const QUrl &fileName, const bool reportError, - const bool isXSLT) + const TestSuite::SuiteType suiteType) { setCurrentFile(fileName); m_previousOpenedCatalog = fileName; QString errorMsg; - TestSuite *const loadedSuite = TestSuite::openCatalog(fileName, errorMsg, false, isXSLT); + TestSuite *const loadedSuite = TestSuite::openCatalog(fileName, errorMsg, false, suiteType); if(!loadedSuite) { @@ -334,12 +351,12 @@ void MainWindow::readSettings() focusURI->setText(settings.value(QLatin1String("focusURI")).toString()); isXSLT20->setChecked(settings.value(QLatin1String("isXSLT20")).toBool()); compileOnly->setChecked(settings.value(QLatin1String("compileOnly")).toBool()); + m_currentSuiteType = (TestSuite::SuiteType)settings.value(QLatin1String("PreviousSuiteType"), isXSLT20->isChecked() ? TestSuite::XsltSuite : TestSuite::XQuerySuite).toInt(); /* Open the previously opened catalog. */ if(!m_previousOpenedCatalog.isEmpty()) { - /* We don't know what kind of catalog it is, so we just take a chance. */ - openCatalog(m_previousOpenedCatalog, false, isXSLT20->isChecked()); + openCatalog(m_previousOpenedCatalog, false, m_currentSuiteType); } sourceInput->setPlainText(settings.value(QLatin1String("sourceInput")).toString()); @@ -393,6 +410,7 @@ void MainWindow::writeSettings() settings.setValue(QLatin1String("size"), size()); settings.setValue(QLatin1String("sourceInput"), sourceInput->toPlainText()); settings.setValue(QLatin1String("PreviousOpenedCatalogFile"), m_previousOpenedCatalog); + settings.setValue(QLatin1String("PreviousSuiteType"), m_currentSuiteType); settings.setValue(QLatin1String("SelectedTab"), sourceTab->currentIndex()); settings.setValue(QLatin1String("ResultViewMethod"), testResultView->resultViewSelection->currentIndex()); @@ -470,7 +488,7 @@ void MainWindow::openRecentFile() { const QAction *const action = qobject_cast(sender()); if(action) - openCatalog(action->data().toUrl(), true, false); + openCatalog(action->data().toUrl(), true, TestSuite::XQuerySuite); } void MainWindow::closeEvent(QCloseEvent *ev) diff --git a/tests/auto/xmlpatternsview/view/MainWindow.h b/tests/auto/xmlpatternsview/view/MainWindow.h index 1d14f41..778d7cd 100644 --- a/tests/auto/xmlpatternsview/view/MainWindow.h +++ b/tests/auto/xmlpatternsview/view/MainWindow.h @@ -88,6 +88,7 @@ #include "ui_ui_MainWindow.h" #include "DebugExpressionFactory.h" +#include "TestSuite.h" QT_BEGIN_HEADER @@ -142,6 +143,8 @@ namespace QPatternistSDK void on_actionOpenXSLTSCatalog_triggered(); + void on_actionOpenXSDTSCatalog_triggered(); + /** * Executes the selected test case or test group. */ @@ -153,7 +156,7 @@ namespace QPatternistSDK * an informative message box will be displayed, if any errors occurred. */ void openCatalog(const QUrl &file, const bool reportError, - const bool isXSLT); + const TestSuite::SuiteType suitType); void openRecentFile(); @@ -205,6 +208,7 @@ namespace QPatternistSDK TestCaseView * testCaseView; TestResultView * testResultView; FunctionSignaturesView * functionView; + TestSuite::SuiteType m_currentSuiteType; }; } QT_END_NAMESPACE diff --git a/tests/auto/xmlpatternsview/view/ui_MainWindow.ui b/tests/auto/xmlpatternsview/view/ui_MainWindow.ui index 5d74331..0240350 100644 --- a/tests/auto/xmlpatternsview/view/ui_MainWindow.ui +++ b/tests/auto/xmlpatternsview/view/ui_MainWindow.ui @@ -234,6 +234,7 @@ + @@ -304,6 +305,14 @@ Ctrl+L + + + O&pen XSDTS Catalog... + + + Ctrl+S + + diff --git a/tests/auto/xmlpatternsxqts/lib/TestBaseLine.cpp b/tests/auto/xmlpatternsxqts/lib/TestBaseLine.cpp index b699ead..841266c 100644 --- a/tests/auto/xmlpatternsxqts/lib/TestBaseLine.cpp +++ b/tests/auto/xmlpatternsxqts/lib/TestBaseLine.cpp @@ -178,6 +178,7 @@ void TestBaseLine::toXML(XMLWriter &receiver) const { case XML: /* Fallthrough. */ case Fragment: /* Fallthrough. */ + case SchemaIsValid: /* Fallthrough. */ case Text: { QXmlAttributes inspectAtts; @@ -343,6 +344,8 @@ TestResult::Status TestBaseLine::verify(const QString &serializedInput) const { switch(m_type) { + case SchemaIsValid: + /* Fall through. */ case Text: { if(serializedInput == details()) @@ -491,6 +494,8 @@ QString TestBaseLine::displayName(const Type id) return QLatin1String("Inspect"); case ExpectedError: return QLatin1String("ExpectedError"); + case SchemaIsValid: + return QLatin1String("SchemaIsValid"); } Q_ASSERT(false); @@ -503,6 +508,8 @@ QString TestBaseLine::details() const return QString(); if(m_type == ExpectedError) /* We're an error code. */ return m_details; + if(m_type == SchemaIsValid) /* We're a schema validation information . */ + return m_details; if(m_details.isEmpty()) return m_details; diff --git a/tests/auto/xmlpatternsxqts/lib/TestBaseLine.h b/tests/auto/xmlpatternsxqts/lib/TestBaseLine.h index 577c4b1..b5dc46e 100644 --- a/tests/auto/xmlpatternsxqts/lib/TestBaseLine.h +++ b/tests/auto/xmlpatternsxqts/lib/TestBaseLine.h @@ -168,7 +168,14 @@ namespace QPatternistSDK * because an implementation does not support the feature is not * considered a correct result. */ - ExpectedError + ExpectedError, + + /** + * A special comparison for the schema validation tests. The details + * can only be 'true' or 'false' depending on whether it is a valid + * schema or not. + */ + SchemaIsValid }; /** diff --git a/tests/auto/xmlpatternsxqts/lib/TestGroup.cpp b/tests/auto/xmlpatternsxqts/lib/TestGroup.cpp index 060f993..e59e4b4 100644 --- a/tests/auto/xmlpatternsxqts/lib/TestGroup.cpp +++ b/tests/auto/xmlpatternsxqts/lib/TestGroup.cpp @@ -94,7 +94,7 @@ TestGroup::TestGroup(TreeItem *p) : m_parent(p) QVariant TestGroup::data(const Qt::ItemDataRole role, int column) const { - if(role != Qt::DisplayRole && role != Qt::BackgroundRole) + if(role != Qt::DisplayRole && role != Qt::BackgroundRole && role != Qt::ToolTipRole) return QVariant(); /* In ResultSummary, the first is the amount of passes and the second is the total. */ @@ -154,6 +154,10 @@ QVariant TestGroup::data(const Qt::ItemDataRole role, int column) const return QVariant(); } } + case Qt::ToolTipRole: + { + return description(); + } default: { Q_ASSERT_X(false, Q_FUNC_INFO, "This shouldn't be reached"); diff --git a/tests/auto/xmlpatternsxqts/lib/TestSuite.cpp b/tests/auto/xmlpatternsxqts/lib/TestSuite.cpp index 3bca281..13d5880 100644 --- a/tests/auto/xmlpatternsxqts/lib/TestSuite.cpp +++ b/tests/auto/xmlpatternsxqts/lib/TestSuite.cpp @@ -91,6 +91,7 @@ #include "TestSuiteResult.h" #include "XMLWriter.h" #include "XSLTTestSuiteHandler.h" +#include "XSDTestSuiteHandler.h" #include "qdebug_p.h" #include "TestSuite.h" @@ -132,7 +133,7 @@ TestSuiteResult *TestSuite::runSuite() TestSuite *TestSuite::openCatalog(const QUrl &catalogURI, QString &errorMsg, const bool useExclusionList, - const bool isXSLTCatalog) + SuiteType suiteType) { pDebug() << "Opening catalog:" << catalogURI.toString(); QFile ts(catalogURI.toLocalFile()); @@ -167,14 +168,14 @@ TestSuite *TestSuite::openCatalog(const QUrl &catalogURI, return 0; } - return openCatalog(&ts, errorMsg, catalogURI, useExclusionList, isXSLTCatalog); + return openCatalog(&ts, errorMsg, catalogURI, useExclusionList, suiteType); } TestSuite *TestSuite::openCatalog(QIODevice *input, QString &errorMsg, const QUrl &fileName, const bool useExclusionList, - const bool isXSLTCatalog) + SuiteType suiteType) { Q_ASSERT(input); @@ -183,10 +184,12 @@ TestSuite *TestSuite::openCatalog(QIODevice *input, HandlerPtr loader; - if(isXSLTCatalog) - loader = HandlerPtr(new XSLTTestSuiteHandler(fileName)); - else - loader = HandlerPtr(new TestSuiteHandler(fileName, useExclusionList)); + switch (suiteType) { + case XQuerySuite: loader = HandlerPtr(new TestSuiteHandler(fileName, useExclusionList)); break; + case XsltSuite: loader = HandlerPtr(new XSLTTestSuiteHandler(fileName)); break; + case XsdSuite: loader = HandlerPtr(new XSDTestSuiteHandler(fileName)); break; + default: Q_ASSERT(false); break; + } reader.setContentHandler(loader.data()); @@ -198,8 +201,13 @@ TestSuite *TestSuite::openCatalog(QIODevice *input, return 0; } - TestSuite *const suite = isXSLTCatalog ? static_cast(loader.data())->testSuite() - : static_cast(loader.data())->testSuite(); + TestSuite *suite = 0; + switch (suiteType) { + case XQuerySuite: suite = static_cast(loader.data())->testSuite(); break; + case XsltSuite: suite = static_cast(loader.data())->testSuite(); break; + case XsdSuite: suite = static_cast(loader.data())->testSuite(); break; + default: Q_ASSERT(false); break; + } if(suite) return suite; diff --git a/tests/auto/xmlpatternsxqts/lib/TestSuite.h b/tests/auto/xmlpatternsxqts/lib/TestSuite.h index cdd511f..5141886 100644 --- a/tests/auto/xmlpatternsxqts/lib/TestSuite.h +++ b/tests/auto/xmlpatternsxqts/lib/TestSuite.h @@ -112,6 +112,16 @@ namespace QPatternistSDK class Q_PATTERNISTSDK_EXPORT TestSuite : public TestContainer { public: + /** + * Describes the type of test suite. + */ + enum SuiteType + { + XQuerySuite, ///< The test suite for XQuery + XsltSuite, ///< The test suite for XSLT + XsdSuite ///< The test suite for XML Schema + }; + TestSuite(); virtual QVariant data(const Qt::ItemDataRole role, int column) const; @@ -148,7 +158,7 @@ namespace QPatternistSDK static TestSuite *openCatalog(const QUrl &catalogFile, QString &errorMsg, const bool useExclusionList, - const bool isXSLTCatalog = false); + SuiteType type); void toXML(XMLWriter &receiver, TestCase *const tc) const; @@ -177,7 +187,7 @@ namespace QPatternistSDK QString &errorMsg, const QUrl &fileName, const bool useExclusionList, - const bool isXSLTCatalog); + SuiteType type); QString m_version; QDate m_designDate; }; diff --git a/tests/auto/xmlpatternsxqts/lib/TreeModel.cpp b/tests/auto/xmlpatternsxqts/lib/TreeModel.cpp index d9ba200..4991b26 100644 --- a/tests/auto/xmlpatternsxqts/lib/TreeModel.cpp +++ b/tests/auto/xmlpatternsxqts/lib/TreeModel.cpp @@ -118,9 +118,14 @@ QVariant TreeModel::headerData(int section, Qt::Orientation orientation, int rol return QVariant(); } -void TreeModel::childChanged(TreeItem *) +void TreeModel::childChanged(TreeItem *item) { - layoutChanged(); + if (item) { + const QModelIndex index = createIndex(item->row(), 0, item); + dataChanged(index, index); + } else { + layoutChanged(); + } } QModelIndex TreeModel::index(int row, int column, const QModelIndex &p) const diff --git a/tests/auto/xmlpatternsxqts/lib/XSDTSTestCase.cpp b/tests/auto/xmlpatternsxqts/lib/XSDTSTestCase.cpp new file mode 100644 index 0000000..b19eb91 --- /dev/null +++ b/tests/auto/xmlpatternsxqts/lib/XSDTSTestCase.cpp @@ -0,0 +1,346 @@ +/**************************************************************************** +** +** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the Patternist project on Trolltech Labs. +** +** $TROLLTECH_GPL_LICENSE$ +** +*************************************************************************** +*/ + +#include +#include +#include +#include +#include + +#include "XSDTSTestCase.h" + +#include "qxmlschema.h" +#include "qxmlschemavalidator.h" + +using namespace QPatternistSDK; +using namespace QPatternist; + +XSDTSTestCase::XSDTSTestCase(const Scenario scen, TreeItem *p, TestType testType) + : m_scenario(scen) + , m_parent(p) + , m_testType(testType) +{ +} + +XSDTSTestCase::~XSDTSTestCase() +{ + qDeleteAll(m_baseLines); +} + +TestResult::List XSDTSTestCase::execute(const ExecutionStage, TestSuite*) +{ + ErrorHandler errHandler; + ErrorHandler::installQtMessageHandler(&errHandler); + + TestResult::List retval; + TestResult::Status resultStatus = TestResult::Unknown; + QString serialized; + + if (m_testType == SchemaTest) { + executeSchemaTest(resultStatus, serialized, &errHandler); + } else { + executeInstanceTest(resultStatus, serialized, &errHandler); + } + + resultStatus = TestBaseLine::scan(serialized, baseLines()); + Q_ASSERT(resultStatus != TestResult::Unknown); + + m_result = new TestResult(name(), resultStatus, 0, errHandler.messages(), + QPatternist::Item::List(), serialized); + retval.append(m_result); + ErrorHandler::installQtMessageHandler(0); + changed(this); + return retval; +} + +void XSDTSTestCase::executeSchemaTest(TestResult::Status &resultStatus, QString &serialized, QAbstractMessageHandler *handler) +{ + QFile file(m_schemaUri.path()); + if (!file.open(QIODevice::ReadOnly)) { + resultStatus = TestResult::Fail; + serialized = QString(); + return; + } + + QXmlSchema schema; + schema.setMessageHandler(handler); + schema.load(&file, m_schemaUri); + + if (schema.isValid()) { + resultStatus = TestResult::Pass; + serialized = QString::fromLatin1("true"); + } else { + resultStatus = TestResult::Pass; + serialized = QString::fromLatin1("false"); + } +} + +void XSDTSTestCase::executeInstanceTest(TestResult::Status &resultStatus, QString &serialized, QAbstractMessageHandler *handler) +{ + QFile instanceFile(m_instanceUri.path()); + if (!instanceFile.open(QIODevice::ReadOnly)) { + resultStatus = TestResult::Fail; + serialized = QString(); + return; + } + + QXmlSchema schema; + if (m_schemaUri.isValid()) { + QFile file(m_schemaUri.path()); + if (!file.open(QIODevice::ReadOnly)) { + resultStatus = TestResult::Fail; + serialized = QString(); + return; + } + + schema.setMessageHandler(handler); + schema.load(&file, m_schemaUri); + + if (!schema.isValid()) { + resultStatus = TestResult::Pass; + serialized = QString::fromLatin1("false"); + return; + } + } + + QXmlSchemaValidator validator(schema); + validator.setMessageHandler(handler); + + qDebug("check %s", qPrintable(m_instanceUri.path())); + if (validator.validate(&instanceFile, m_instanceUri)) { + resultStatus = TestResult::Pass; + serialized = QString::fromLatin1("true"); + } else { + resultStatus = TestResult::Pass; + serialized = QString::fromLatin1("false"); + } +} + +QVariant XSDTSTestCase::data(const Qt::ItemDataRole role, int column) const +{ + if(role == Qt::DisplayRole) + { + if(column == 0) + return title(); + + const TestResult *const tr = testResult(); + if(!tr) + { + if(column == 1) + return TestResult::displayName(TestResult::NotTested); + else + return QString(); + } + const TestResult::Status status = tr->status(); + + switch(column) + { + case 1: + return status == TestResult::Pass ? QString(QChar::fromLatin1('1')) + : QString(QChar::fromLatin1('0')); + case 2: + return status == TestResult::Fail ? QString(QChar::fromLatin1('1')) + : QString(QChar::fromLatin1('0')); + default: + return QString(); + } + } + + if(role != Qt::BackgroundRole) + return QVariant(); + + const TestResult *const tr = testResult(); + + if(!tr) + { + if(column == 0) + return Qt::yellow; + else + return QVariant(); + } + + const TestResult::Status status = tr->status(); + + if(status == TestResult::NotTested || status == TestResult::Unknown) + return Qt::yellow; + + switch(column) + { + case 1: + return status == TestResult::Pass ? Qt::green : QVariant(); + case 2: + return status == TestResult::Fail ? Qt::red : QVariant(); + default: + return QVariant(); + } +} + +QString XSDTSTestCase::sourceCode(bool &ok) const +{ + QFile file((m_testType == SchemaTest ? m_schemaUri : m_instanceUri).toLocalFile()); + + QString err; + + if(!file.exists()) + err = QString::fromLatin1("Error: %1 does not exist.").arg(file.fileName()); + else if(!QFileInfo(file.fileName()).isFile()) + err = QString::fromLatin1("Error: %1 is not a file, cannot display it.").arg(file.fileName()); + else if(!file.open(QIODevice::ReadOnly)) + err = QString::fromLatin1("Error: Could not open %1. Likely a permission error.") + .arg(file.fileName()); + + if(err.isNull()) /* No errors. */ + { + ok = true; + /* Scary, we assume the query is stored in UTF-8. */ + return QString::fromUtf8(file.readAll()); + } + else + { + ok = false; + return err; + } +} + +int XSDTSTestCase::columnCount() const +{ + return 2; +} + +void XSDTSTestCase::addBaseLine(TestBaseLine *line) +{ + m_baseLines.append(line); +} + +QString XSDTSTestCase::name() const +{ + return m_name; +} + +QString XSDTSTestCase::creator() const +{ + return m_creator; +} + +QString XSDTSTestCase::description() const +{ + return m_description; +} + +QDate XSDTSTestCase::lastModified() const +{ + return m_lastModified; +} + +bool XSDTSTestCase::isXPath() const +{ + return false; +} + +TestCase::Scenario XSDTSTestCase::scenario() const +{ + return m_scenario; +} + +void XSDTSTestCase::setName(const QString &n) +{ + m_name = n; +} + +void XSDTSTestCase::setCreator(const QString &ctor) +{ + m_creator = ctor; +} + +void XSDTSTestCase::setDescription(const QString &descriptionP) +{ + m_description = descriptionP; +} + +void XSDTSTestCase::setLastModified(const QDate &date) +{ + m_lastModified = date; +} + +void XSDTSTestCase::setSchemaUri(const QUrl &uri) +{ + m_schemaUri = uri; +} + +void XSDTSTestCase::setInstanceUri(const QUrl &uri) +{ + m_instanceUri = uri; +} + +TreeItem *XSDTSTestCase::parent() const +{ + return m_parent; +} + +QString XSDTSTestCase::title() const +{ + return m_name; +} + +TestBaseLine::List XSDTSTestCase::baseLines() const +{ + Q_ASSERT_X(!m_baseLines.isEmpty(), Q_FUNC_INFO, + qPrintable(QString::fromLatin1("The test %1 has no base lines, it should have at least one.").arg(name()))); + return m_baseLines; +} + +QUrl XSDTSTestCase::schemaUri() const +{ + return m_schemaUri; +} + +QUrl XSDTSTestCase::instanceUri() const +{ + return m_instanceUri; +} + +void XSDTSTestCase::setContextItemSource(const QUrl &uri) +{ + m_contextItemSource = uri; +} + +QUrl XSDTSTestCase::contextItemSource() const +{ + return m_contextItemSource; +} + +void XSDTSTestCase::setParent(TreeItem *const p) +{ + m_parent = p; +} + +QPatternist::ExternalVariableLoader::Ptr XSDTSTestCase::externalVariableLoader() const +{ + return QPatternist::ExternalVariableLoader::Ptr(); +} + +TestResult *XSDTSTestCase::testResult() const +{ + return m_result; +} + +TestItem::ResultSummary XSDTSTestCase::resultSummary() const +{ + if(m_result) + return ResultSummary(m_result->status() == TestResult::Pass ? 1 : 0, + 1); + + return ResultSummary(0, 1); +} + +// vim: et:ts=4:sw=4:sts=4 + diff --git a/tests/auto/xmlpatternsxqts/lib/XSDTSTestCase.h b/tests/auto/xmlpatternsxqts/lib/XSDTSTestCase.h new file mode 100644 index 0000000..ce84988 --- /dev/null +++ b/tests/auto/xmlpatternsxqts/lib/XSDTSTestCase.h @@ -0,0 +1,130 @@ +/**************************************************************************** +** +** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the Patternist project on Trolltech Labs. +** +** $TROLLTECH_GPL_LICENSE$ +** +*************************************************************************** +*/ + +#ifndef PatternistSDK_XSDTSTestCase_H +#define PatternistSDK_XSDTSTestCase_H + +#include +#include +#include + +#include "TestBaseLine.h" +#include "TestCase.h" + +QT_BEGIN_HEADER + +namespace QPatternistSDK +{ + /** + * @short Represents a test case in a test suite in the XML Query Test Suite. + * + * TestCase is a memory representation of a test case, and maps + * to the @c test-case element in the XQuery Test Suite test + * case catalog. + * + * @ingroup PatternistSDK + * @author Frans Englich + */ + class Q_PATTERNISTSDK_EXPORT XSDTSTestCase : public TestCase + { + public: + enum TestType + { + SchemaTest, + InstanceTest + }; + + XSDTSTestCase(const Scenario scen, TreeItem *parent, TestType testType); + virtual ~XSDTSTestCase(); + + /** + * Executes the test, and returns the result. The returned list + * will always contain exactly one TestResult. + * + * @p stage is ignored when running out-of-process. + */ + virtual TestResult::List execute(const ExecutionStage stage, + TestSuite *ts); + /** + * The identifier, the name of the test. For example, "Literals034". + * The name of a test case must be unique. + */ + virtual QString name() const; + virtual QString creator() const; + virtual QString description() const; + /** + * @returns the query inside the file, specified by testCasePath(). Loading + * of the file is not cached in order to avoid complications. + * @param ok is set to @c false if loading the query file fails + */ + virtual QString sourceCode(bool &ok) const; + virtual QUrl schemaUri() const; + virtual QUrl instanceUri() const; + virtual QUrl testCasePath() const {return QUrl();} + virtual QDate lastModified() const; + + bool isXPath() const; + + /** + * What kind of test case this is, what kind of scenario it takes part + * of. For example, whether the test case should evaluate normally or fail. + */ + Scenario scenario() const; + + void setCreator(const QString &creator); + void setLastModified(const QDate &date); + void setDescription(const QString &description); + void setName(const QString &name); + void setSchemaUri(const QUrl &uri); + void setInstanceUri(const QUrl &uri); + void setTestCasePath(const QUrl &uri) {} + void setContextItemSource(const QUrl &uri); + void addBaseLine(TestBaseLine *lines); + + virtual TreeItem *parent() const; + + virtual QVariant data(const Qt::ItemDataRole role, int column) const; + + virtual QString title() const; + virtual TestBaseLine::List baseLines() const; + + virtual int columnCount() const; + + virtual QUrl contextItemSource() const; + void setParent(TreeItem *const parent); + virtual QPatternist::ExternalVariableLoader::Ptr externalVariableLoader() const; + virtual TestResult *testResult() const; + virtual ResultSummary resultSummary() const; + + private: + void executeSchemaTest(TestResult::Status &resultStatus, QString &serialized, QAbstractMessageHandler *handler); + void executeInstanceTest(TestResult::Status &resultStatus, QString &serialized, QAbstractMessageHandler *handler); + + QString m_name; + QString m_creator; + QString m_description; + QUrl m_schemaUri; + QUrl m_instanceUri; + QDate m_lastModified; + const Scenario m_scenario; + TreeItem * m_parent; + TestBaseLine::List m_baseLines; + QUrl m_contextItemSource; + TestType m_testType; + QPointer m_result; + }; +} + +QT_END_HEADER + +#endif +// vim: et:ts=4:sw=4:sts=4 diff --git a/tests/auto/xmlpatternsxqts/lib/XSDTestSuiteHandler.cpp b/tests/auto/xmlpatternsxqts/lib/XSDTestSuiteHandler.cpp new file mode 100644 index 0000000..b6ee379 --- /dev/null +++ b/tests/auto/xmlpatternsxqts/lib/XSDTestSuiteHandler.cpp @@ -0,0 +1,881 @@ +/**************************************************************************** +** +** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the Patternist project on Trolltech Labs. +** +** $TROLLTECH_GPL_LICENSE$ +** +*************************************************************************** +*/ + +#include + +#include "qacceltreeresourceloader_p.h" +#include "qnetworkaccessdelegator_p.h" + +#include "Global.h" +#include "TestBaseLine.h" +#include "TestGroup.h" + +#include "XSDTestSuiteHandler.h" +#include "XSDTSTestCase.h" + +using namespace QPatternistSDK; + +extern QNetworkAccessManager s_networkManager; + +XSDTestSuiteHandler::XSDTestSuiteHandler(const QUrl &catalogFile) : m_ts(0) + , m_catalogFile(catalogFile) + , m_inSchemaTest(false) + , m_inInstanceTest(false) + , m_inTestGroup(false) + , m_inDescription(false) + , m_schemaBlacklisted(false) + , m_counter(0) +{ + Q_ASSERT(!m_catalogFile.isRelative()); + m_ts = new TestSuite(); + m_topLevelGroup = new TestGroup(m_ts); + m_topLevelGroup->setTitle("XML Schema Test Suite"); + m_ts->appendChild(m_topLevelGroup); + + // exclude these test cases, as they break our current state machine + m_blackList << QLatin1String("addB099") + << QLatin1String("addB118") + << QLatin1String("elemJ003") + << QLatin1String("elemJ011") + << QLatin1String("elemZ004") + << QLatin1String("elemZ020") + << QLatin1String("groupH021v") + << QLatin1String("groupJ009v") + << QLatin1String("name00101m2") + << QLatin1String("schL5") + << QLatin1String("ste110") + << QLatin1String("stZ007") + << QLatin1String("stZ047") + << QLatin1String("stZ055") + << QLatin1String("addB049") + << QLatin1String("addB068") + << QLatin1String("addB078") + << QLatin1String("addB078A") + << QLatin1String("addB078B") + << QLatin1String("addB167") + << QLatin1String("addB191") + << QLatin1String("isDefault060_2") + << QLatin1String("isDefault069") + << QLatin1String("annotB025") + << QLatin1String("base64Binary_enumeration003_1321") + << QLatin1String("anyURI_a001_1336") + << QLatin1String("anyURI_a001_1336") + << QLatin1String("anyURI_a003_1338") + << QLatin1String("anyURI_a004_1339") + << QLatin1String("anyURI_b004_1354") + << QLatin1String("anyURI_b004_1354") + << QLatin1String("anyURI_b006_1356") + << QLatin1String("QName_length001_1357") + << QLatin1String("QName_length003_1359") + << QLatin1String("QName_minLength003_1362") + << QLatin1String("QName_maxLength001_1364") + << QLatin1String("NOTATION_length001_1372") + << QLatin1String("NOTATION_length003_1374") + << QLatin1String("NOTATION_minLength003_1377") + << QLatin1String("NOTATION_maxLength001_1379") + << QLatin1String("hexBinary003_2069") + << QLatin1String("QName009_2092") + << QLatin1String("dtZ107447_a_2245") + << QLatin1String("elemE001") + << QLatin1String("elemE002") + << QLatin1String("elemE003") + << QLatin1String("elemE004") + << QLatin1String("elemE005") + << QLatin1String("elemT026") + << QLatin1String("elemT027") + << QLatin1String("elemT028") + << QLatin1String("elemT029") + << QLatin1String("elemT054") + << QLatin1String("elemT055") + << QLatin1String("elemT056") + << QLatin1String("elemT057") + << QLatin1String("elemZ006") + << QLatin1String("elemZ007") + << QLatin1String("elemZ026") + << QLatin1String("elemZ027_c") + << QLatin1String("elemZ028c") + << QLatin1String("elemZ028d") + << QLatin1String("elemZ028f1") + << QLatin1String("elemZ028f1") + << QLatin1String("elemZ028f2") + << QLatin1String("elemZ028f2") + << QLatin1String("elemZ028f3") + << QLatin1String("elemZ028f3") + << QLatin1String("elemZ031") + << QLatin1String("errF001") + << QLatin1String("idC019") + << QLatin1String("idL100") + << QLatin1String("idZ011") + << QLatin1String("idZ015") + << QLatin1String("mgO013") + << QLatin1String("particlesA012") + << QLatin1String("particlesA013") + << QLatin1String("particlesA014") + << QLatin1String("particlesA015") + << QLatin1String("particlesHa161") + << QLatin1String("particlesHb008") + << QLatin1String("particlesHb011") + << QLatin1String("particlesIe003") + << QLatin1String("particlesIg003") + << QLatin1String("particlesIg004") + << QLatin1String("particlesJb003") + << QLatin1String("particlesJd003") + << QLatin1String("particlesJf003") + << QLatin1String("particlesJk003") + << QLatin1String("particlesOb001") + << QLatin1String("particlesOb002") + << QLatin1String("particlesOb004") + << QLatin1String("particlesOb008") + << QLatin1String("particlesOb009") + << QLatin1String("particlesOb013") + << QLatin1String("particlesOb018") + << QLatin1String("particlesQ005") + << QLatin1String("particlesS002") + << QLatin1String("particlesT002") + << QLatin1String("particlesT009") + << QLatin1String("particlesT014") + << QLatin1String("particlesV001") + << QLatin1String("particlesV002") + << QLatin1String("particlesV020") + << QLatin1String("particlesZ001") + << QLatin1String("particlesZ005") + << QLatin1String("particlesZ007") + << QLatin1String("particlesZ023") + << QLatin1String("particlesZ024") + << QLatin1String("particlesZ026") + << QLatin1String("particlesZ028") + << QLatin1String("particlesZ033_c") + << QLatin1String("particlesZ033_d") + << QLatin1String("particlesZ033_e") + << QLatin1String("particlesZ033_f") + << QLatin1String("particlesZ033_g") + << QLatin1String("particlesZ034_a1") + << QLatin1String("particlesZ034_a2") + << QLatin1String("particlesZ034_a3") + << QLatin1String("particlesZ034_b") + << QLatin1String("particlesZ035_a") + << QLatin1String("particlesZ035_b") + << QLatin1String("particlesZ036_a") + << QLatin1String("particlesZ036_b1") + << QLatin1String("particlesZ036_b2") + << QLatin1String("particlesZ036_c") +/* + << QLatin1String("reC65") + << QLatin1String("reC66") + << QLatin1String("reC67") + << QLatin1String("reC68") + << QLatin1String("reF58") + << QLatin1String("reG50") + << QLatin1String("reJ11") + << QLatin1String("reJ13") + << QLatin1String("reJ19") + << QLatin1String("reJ21") + << QLatin1String("reJ23") + << QLatin1String("reJ25") + << QLatin1String("reJ29") + << QLatin1String("reJ31") + << QLatin1String("reJ33") + << QLatin1String("reJ35") + << QLatin1String("reJ61") + << QLatin1String("reJ69") + << QLatin1String("reJ75") + << QLatin1String("reJ77") + << QLatin1String("reL98") + << QLatin1String("reL99") + << QLatin1String("reM98") + << QLatin1String("reN99") + << QLatin1String("reS21") + << QLatin1String("reS42") + << QLatin1String("reT63") + << QLatin1String("reT84") + << QLatin1String("reDG2") + << QLatin1String("RegexTest_9") + << QLatin1String("RegexTest_11") + << QLatin1String("RegexTest_14") + << QLatin1String("RegexTest_15") + << QLatin1String("RegexTest_16") + << QLatin1String("RegexTest_17") + << QLatin1String("RegexTest_23") + << QLatin1String("RegexTest_24") + << QLatin1String("RegexTest_25") + << QLatin1String("RegexTest_26") + << QLatin1String("RegexTest_27") + << QLatin1String("RegexTest_28") + << QLatin1String("RegexTest_30") + << QLatin1String("RegexTest_30") + << QLatin1String("RegexTest_33") + << QLatin1String("RegexTest_34") + << QLatin1String("RegexTest_34") + << QLatin1String("RegexTest_43") + << QLatin1String("RegexTest_44") + << QLatin1String("RegexTest_45") + << QLatin1String("RegexTest_46") + << QLatin1String("RegexTest_47") + << QLatin1String("RegexTest_48") + << QLatin1String("RegexTest_49") + << QLatin1String("RegexTest_50") + << QLatin1String("RegexTest_51") + << QLatin1String("RegexTest_52") + << QLatin1String("RegexTest_53") + << QLatin1String("RegexTest_54") + << QLatin1String("RegexTest_55") + << QLatin1String("RegexTest_56") + << QLatin1String("RegexTest_57") + << QLatin1String("RegexTest_57") + << QLatin1String("RegexTest_58") + << QLatin1String("RegexTest_58") + << QLatin1String("RegexTest_65") + << QLatin1String("RegexTest_113") + << QLatin1String("RegexTest_116") + << QLatin1String("RegexTest_119") + << QLatin1String("RegexTest_120") + << QLatin1String("RegexTest_121") + << QLatin1String("RegexTest_141") + << QLatin1String("RegexTest_142") + << QLatin1String("RegexTest_143") + << QLatin1String("RegexTest_145") + << QLatin1String("RegexTest_146") + << QLatin1String("RegexTest_147") + << QLatin1String("RegexTest_148") + << QLatin1String("RegexTest_149") + << QLatin1String("RegexTest_150") + << QLatin1String("RegexTest_151") + << QLatin1String("RegexTest_152") + << QLatin1String("RegexTest_154") + << QLatin1String("RegexTest_155") + << QLatin1String("RegexTest_156") + << QLatin1String("RegexTest_157") + << QLatin1String("RegexTest_158") + << QLatin1String("RegexTest_163") + << QLatin1String("RegexTest_164") + << QLatin1String("RegexTest_165") + << QLatin1String("RegexTest_166") + << QLatin1String("RegexTest_167") + << QLatin1String("RegexTest_168") + << QLatin1String("RegexTest_169") + << QLatin1String("RegexTest_170") + << QLatin1String("RegexTest_171") + << QLatin1String("RegexTest_172") + << QLatin1String("RegexTest_173") + << QLatin1String("RegexTest_174") + << QLatin1String("RegexTest_178") + << QLatin1String("RegexTest_194") + << QLatin1String("RegexTest_194") + << QLatin1String("RegexTest_195") + << QLatin1String("RegexTest_195") + << QLatin1String("RegexTest_196") + << QLatin1String("RegexTest_196") + << QLatin1String("RegexTest_197") + << QLatin1String("RegexTest_198") + << QLatin1String("RegexTest_199") + << QLatin1String("RegexTest_200") + << QLatin1String("RegexTest_200") + << QLatin1String("RegexTest_201") + << QLatin1String("RegexTest_201") + << QLatin1String("RegexTest_202") + << QLatin1String("RegexTest_202") + << QLatin1String("RegexTest_203") + << QLatin1String("RegexTest_204") + << QLatin1String("RegexTest_205") + << QLatin1String("RegexTest_206") + << QLatin1String("RegexTest_207") + << QLatin1String("RegexTest_208") + << QLatin1String("RegexTest_209") + << QLatin1String("RegexTest_209") + << QLatin1String("RegexTest_210") + << QLatin1String("RegexTest_210") + << QLatin1String("RegexTest_211") + << QLatin1String("RegexTest_211") + << QLatin1String("RegexTest_212") + << QLatin1String("RegexTest_213") + << QLatin1String("RegexTest_214") + << QLatin1String("RegexTest_215") + << QLatin1String("RegexTest_216") + << QLatin1String("RegexTest_217") + << QLatin1String("RegexTest_218") + << QLatin1String("RegexTest_220") + << QLatin1String("RegexTest_221") + << QLatin1String("RegexTest_222") + << QLatin1String("RegexTest_226") + << QLatin1String("RegexTest_230") + << QLatin1String("RegexTest_232") + << QLatin1String("RegexTest_233") + << QLatin1String("RegexTest_294") + << QLatin1String("RegexTest_294") + << QLatin1String("RegexTest_295") + << QLatin1String("RegexTest_295") + << QLatin1String("RegexTest_299") + << QLatin1String("RegexTest_300") + << QLatin1String("RegexTest_301") + << QLatin1String("RegexTest_302") + << QLatin1String("RegexTest_303") + << QLatin1String("RegexTest_304") + << QLatin1String("RegexTest_305") + << QLatin1String("RegexTest_306") + << QLatin1String("RegexTest_307") + << QLatin1String("RegexTest_308") + << QLatin1String("RegexTest_309") + << QLatin1String("RegexTest_310") + << QLatin1String("RegexTest_311") + << QLatin1String("RegexTest_312") + << QLatin1String("RegexTest_313") + << QLatin1String("RegexTest_314") + << QLatin1String("RegexTest_315") + << QLatin1String("RegexTest_315") + << QLatin1String("RegexTest_316") + << QLatin1String("RegexTest_316") + << QLatin1String("RegexTest_317") + << QLatin1String("RegexTest_317") + << QLatin1String("RegexTest_440") + << QLatin1String("RegexTest_441") + << QLatin1String("RegexTest_442") + << QLatin1String("RegexTest_443") + << QLatin1String("RegexTest_448") + << QLatin1String("RegexTest_449") + << QLatin1String("RegexTest_450") + << QLatin1String("RegexTest_451") + << QLatin1String("RegexTest_458") + << QLatin1String("RegexTest_464") + << QLatin1String("RegexTest_464") + << QLatin1String("RegexTest_465") + << QLatin1String("RegexTest_469") + << QLatin1String("RegexTest_470") + << QLatin1String("RegexTest_471") + << QLatin1String("RegexTest_472") + << QLatin1String("RegexTest_473") + << QLatin1String("RegexTest_477") + << QLatin1String("RegexTest_478") + << QLatin1String("RegexTest_478") + << QLatin1String("RegexTest_479") + << QLatin1String("RegexTest_480") + << QLatin1String("RegexTest_481") + << QLatin1String("RegexTest_482") + << QLatin1String("RegexTest_482") + << QLatin1String("RegexTest_483") + << QLatin1String("RegexTest_483") + << QLatin1String("RegexTest_484") + << QLatin1String("RegexTest_487") + << QLatin1String("RegexTest_516") + << QLatin1String("RegexTest_516") + << QLatin1String("RegexTest_517") + << QLatin1String("RegexTest_517") + << QLatin1String("RegexTest_518") + << QLatin1String("RegexTest_518") + << QLatin1String("RegexTest_519") + << QLatin1String("RegexTest_519") + << QLatin1String("RegexTest_521") + << QLatin1String("RegexTest_523") + << QLatin1String("RegexTest_524") + << QLatin1String("RegexTest_524") + << QLatin1String("RegexTest_586") + << QLatin1String("RegexTest_587") + << QLatin1String("RegexTest_592") + << QLatin1String("RegexTest_593") + << QLatin1String("RegexTest_594") + << QLatin1String("RegexTest_595") + << QLatin1String("RegexTest_596") + << QLatin1String("RegexTest_597") + << QLatin1String("RegexTest_598") + << QLatin1String("RegexTest_599") + << QLatin1String("RegexTest_600") + << QLatin1String("RegexTest_601") + << QLatin1String("RegexTest_602") + << QLatin1String("RegexTest_603") + << QLatin1String("RegexTest_604") + << QLatin1String("RegexTest_605") + << QLatin1String("RegexTest_648") + << QLatin1String("RegexTest_655") + << QLatin1String("RegexTest_688") + << QLatin1String("RegexTest_696") + << QLatin1String("RegexTest_697") + << QLatin1String("RegexTest_698") + << QLatin1String("RegexTest_700") + << QLatin1String("RegexTest_701") + << QLatin1String("RegexTest_702") + << QLatin1String("RegexTest_703") + << QLatin1String("RegexTest_704") + << QLatin1String("RegexTest_705") + << QLatin1String("RegexTest_706") + << QLatin1String("RegexTest_707") + << QLatin1String("RegexTest_717") + << QLatin1String("RegexTest_718") + << QLatin1String("RegexTest_719") + << QLatin1String("RegexTest_724") + << QLatin1String("RegexTest_725") + << QLatin1String("RegexTest_726") + << QLatin1String("RegexTest_727") + << QLatin1String("RegexTest_728") + << QLatin1String("RegexTest_729") + << QLatin1String("RegexTest_730") + << QLatin1String("RegexTest_731") + << QLatin1String("RegexTest_732") + << QLatin1String("RegexTest_733") + << QLatin1String("RegexTest_743") + << QLatin1String("RegexTest_755") + << QLatin1String("RegexTest_756") + << QLatin1String("RegexTest_761") + << QLatin1String("RegexTest_762") + << QLatin1String("RegexTest_781") + << QLatin1String("RegexTest_782") + << QLatin1String("RegexTest_783") + << QLatin1String("RegexTest_790") + << QLatin1String("RegexTest_791") + << QLatin1String("RegexTest_824") + << QLatin1String("RegexTest_826") + << QLatin1String("RegexTest_827") + << QLatin1String("RegexTest_836") + << QLatin1String("RegexTest_837") + << QLatin1String("RegexTest_841") + << QLatin1String("RegexTest_842") + << QLatin1String("RegexTest_843") + << QLatin1String("RegexTest_844") + << QLatin1String("RegexTest_845") + << QLatin1String("RegexTest_846") + << QLatin1String("RegexTest_847") + << QLatin1String("RegexTest_848") + << QLatin1String("RegexTest_851") + << QLatin1String("RegexTest_852") + << QLatin1String("RegexTest_853") + << QLatin1String("RegexTest_854") + << QLatin1String("RegexTest_855") + << QLatin1String("RegexTest_856") + << QLatin1String("RegexTest_857") + << QLatin1String("RegexTest_861") + << QLatin1String("RegexTest_862") + << QLatin1String("RegexTest_863") + << QLatin1String("RegexTest_864") + << QLatin1String("RegexTest_865") + << QLatin1String("RegexTest_866") + << QLatin1String("RegexTest_870") + << QLatin1String("RegexTest_879") + << QLatin1String("RegexTest_880") + << QLatin1String("RegexTest_888") + << QLatin1String("RegexTest_889") + << QLatin1String("RegexTest_890") + << QLatin1String("RegexTest_891") + << QLatin1String("RegexTest_892") + << QLatin1String("RegexTest_893") + << QLatin1String("RegexTest_894") + << QLatin1String("RegexTest_895") + << QLatin1String("RegexTest_896") + << QLatin1String("RegexTest_897") + << QLatin1String("RegexTest_898") + << QLatin1String("RegexTest_899") + << QLatin1String("RegexTest_900") + << QLatin1String("RegexTest_901") + << QLatin1String("RegexTest_902") + << QLatin1String("RegexTest_903") + << QLatin1String("RegexTest_904") + << QLatin1String("RegexTest_905") + << QLatin1String("RegexTest_906") + << QLatin1String("RegexTest_907") + << QLatin1String("RegexTest_908") + << QLatin1String("RegexTest_909") + << QLatin1String("RegexTest_910") + << QLatin1String("RegexTest_911") + << QLatin1String("RegexTest_912") + << QLatin1String("RegexTest_913") + << QLatin1String("RegexTest_914") + << QLatin1String("RegexTest_915") + << QLatin1String("RegexTest_916") + << QLatin1String("RegexTest_917") + << QLatin1String("RegexTest_918") + << QLatin1String("RegexTest_919") + << QLatin1String("RegexTest_920") + << QLatin1String("RegexTest_921") + << QLatin1String("RegexTest_922") + << QLatin1String("RegexTest_923") + << QLatin1String("RegexTest_924") + << QLatin1String("RegexTest_925") + << QLatin1String("RegexTest_926") + << QLatin1String("RegexTest_928") + << QLatin1String("RegexTest_929") + << QLatin1String("RegexTest_930") + << QLatin1String("RegexTest_936") + << QLatin1String("RegexTest_937") + << QLatin1String("RegexTest_938") + << QLatin1String("RegexTest_939") + << QLatin1String("RegexTest_940") + << QLatin1String("RegexTest_941") + << QLatin1String("RegexTest_942") + << QLatin1String("RegexTest_943") + << QLatin1String("RegexTest_944") + << QLatin1String("RegexTest_945") + << QLatin1String("RegexTest_946") + << QLatin1String("RegexTest_949") + << QLatin1String("RegexTest_950") + << QLatin1String("RegexTest_951") + << QLatin1String("RegexTest_952") + << QLatin1String("RegexTest_953") + << QLatin1String("RegexTest_954") + << QLatin1String("RegexTest_955") + << QLatin1String("RegexTest_956") + << QLatin1String("RegexTest_957") + << QLatin1String("RegexTest_958") + << QLatin1String("RegexTest_959") + << QLatin1String("RegexTest_960") + << QLatin1String("RegexTest_961") + << QLatin1String("RegexTest_962") + << QLatin1String("RegexTest_963") + << QLatin1String("RegexTest_964") + << QLatin1String("RegexTest_976") + << QLatin1String("RegexTest_977") + << QLatin1String("RegexTest_988") + << QLatin1String("RegexTest_989") + << QLatin1String("RegexTest_990") + << QLatin1String("RegexTest_991") + << QLatin1String("RegexTest_994") + << QLatin1String("RegexTest_995") + << QLatin1String("RegexTest_996") + << QLatin1String("RegexTest_997") + << QLatin1String("RegexTest_1000") + << QLatin1String("RegexTest_1001") + << QLatin1String("RegexTest_1002") + << QLatin1String("RegexTest_1003") + << QLatin1String("RegexTest_1004") + << QLatin1String("RegexTest_1007") + << QLatin1String("RegexTest_1008") + << QLatin1String("RegexTest_1009") + << QLatin1String("RegexTest_1010") + << QLatin1String("RegexTest_1011") + << QLatin1String("RegexTest_1012") + << QLatin1String("RegexTest_1013") + << QLatin1String("RegexTest_1014") + << QLatin1String("RegexTest_1015") + << QLatin1String("RegexTest_1016") + << QLatin1String("RegexTest_1017") + << QLatin1String("RegexTest_1018") + << QLatin1String("RegexTest_1019") + << QLatin1String("RegexTest_1070") + << QLatin1String("RegexTest_1071") + << QLatin1String("RegexTest_1076") + << QLatin1String("RegexTest_1077") + << QLatin1String("RegexTest_1078") + << QLatin1String("RegexTest_1079") + << QLatin1String("RegexTest_1080") + << QLatin1String("RegexTest_1081") + << QLatin1String("RegexTest_1082") + << QLatin1String("RegexTest_1083") + << QLatin1String("RegexTest_1084") + << QLatin1String("RegexTest_1085") + << QLatin1String("RegexTest_1086") + << QLatin1String("RegexTest_1087") + << QLatin1String("RegexTest_1088") + << QLatin1String("RegexTest_1089") + << QLatin1String("RegexTest_1132") + << QLatin1String("RegexTest_1139") + << QLatin1String("RegexTest_1172") + << QLatin1String("RegexTest_1180") + << QLatin1String("RegexTest_1181") + << QLatin1String("RegexTest_1182") + << QLatin1String("RegexTest_1184") + << QLatin1String("RegexTest_1185") + << QLatin1String("RegexTest_1186") + << QLatin1String("RegexTest_1187") + << QLatin1String("RegexTest_1188") + << QLatin1String("RegexTest_1189") + << QLatin1String("RegexTest_1190") + << QLatin1String("RegexTest_1191") + << QLatin1String("RegexTest_1201") + << QLatin1String("RegexTest_1202") + << QLatin1String("RegexTest_1203") + << QLatin1String("RegexTest_1208") + << QLatin1String("RegexTest_1209") + << QLatin1String("RegexTest_1210") + << QLatin1String("RegexTest_1211") + << QLatin1String("RegexTest_1212") + << QLatin1String("RegexTest_1213") + << QLatin1String("RegexTest_1214") + << QLatin1String("RegexTest_1215") + << QLatin1String("RegexTest_1216") + << QLatin1String("RegexTest_1217") + << QLatin1String("RegexTest_1227") + << QLatin1String("RegexTest_1239") + << QLatin1String("RegexTest_1240") + << QLatin1String("RegexTest_1245") + << QLatin1String("RegexTest_1246") + << QLatin1String("RegexTest_1265") + << QLatin1String("RegexTest_1266") + << QLatin1String("RegexTest_1267") + << QLatin1String("RegexTest_1274") + << QLatin1String("RegexTest_1275") + << QLatin1String("RegexTest_1308") + << QLatin1String("RegexTest_1310") + << QLatin1String("RegexTest_1311") + << QLatin1String("RegexTest_1320") + << QLatin1String("RegexTest_1321") + << QLatin1String("RegexTest_1322") + << QLatin1String("RegexTest_1323") + << QLatin1String("RegexTest_1324") + << QLatin1String("RegexTest_1325") + << QLatin1String("RegexTest_1326") + << QLatin1String("RegexTest_1327") + << QLatin1String("RegexTest_1328") + << QLatin1String("RegexTest_1329") + << QLatin1String("RegexTest_1330") + << QLatin1String("RegexTest_1331") + << QLatin1String("RegexTest_1332") + << QLatin1String("RegexTest_1335") + << QLatin1String("RegexTest_1336") + << QLatin1String("RegexTest_1337") + << QLatin1String("RegexTest_1338") + << QLatin1String("RegexTest_1339") + << QLatin1String("RegexTest_1340") + << QLatin1String("RegexTest_1341") + << QLatin1String("RegexTest_1345") + << QLatin1String("RegexTest_1346") + << QLatin1String("RegexTest_1347") + << QLatin1String("RegexTest_1348") + << QLatin1String("RegexTest_1349") + << QLatin1String("RegexTest_1350") + << QLatin1String("RegexTest_1354") + << QLatin1String("RegexTest_1363") + << QLatin1String("RegexTest_1364") + << QLatin1String("RegexTest_1365") + << QLatin1String("RegexTest_1372") + << QLatin1String("RegexTest_1373") + << QLatin1String("RegexTest_1374") + << QLatin1String("RegexTest_1375") + << QLatin1String("RegexTest_1376") + << QLatin1String("RegexTest_1377") + << QLatin1String("RegexTest_1378") + << QLatin1String("RegexTest_1379") + << QLatin1String("RegexTest_1380") + << QLatin1String("RegexTest_1381") + << QLatin1String("RegexTest_1382") + << QLatin1String("RegexTest_1383") + << QLatin1String("RegexTest_1384") + << QLatin1String("RegexTest_1385") + << QLatin1String("RegexTest_1386") + << QLatin1String("RegexTest_1387") + << QLatin1String("RegexTest_1388") + << QLatin1String("RegexTest_1389") + << QLatin1String("RegexTest_1390") + << QLatin1String("RegexTest_1391") + << QLatin1String("RegexTest_1392") + << QLatin1String("RegexTest_1393") + << QLatin1String("RegexTest_1394") + << QLatin1String("RegexTest_1395") + << QLatin1String("RegexTest_1396") + << QLatin1String("RegexTest_1397") + << QLatin1String("RegexTest_1398") + << QLatin1String("RegexTest_1399") + << QLatin1String("RegexTest_1400") + << QLatin1String("RegexTest_1401") + << QLatin1String("RegexTest_1402") + << QLatin1String("RegexTest_1403") + << QLatin1String("RegexTest_1404") + << QLatin1String("RegexTest_1405") + << QLatin1String("RegexTest_1406") + << QLatin1String("RegexTest_1407") + << QLatin1String("RegexTest_1408") + << QLatin1String("RegexTest_1409") + << QLatin1String("RegexTest_1410") + << QLatin1String("RegexTest_1412") + << QLatin1String("RegexTest_1413") + << QLatin1String("RegexTest_1414") + << QLatin1String("RegexTest_1420") + << QLatin1String("RegexTest_1421") + << QLatin1String("RegexTest_1422") + << QLatin1String("RegexTest_1423") + << QLatin1String("RegexTest_1424") + << QLatin1String("RegexTest_1425") + << QLatin1String("RegexTest_1426") + << QLatin1String("RegexTest_1427") + << QLatin1String("RegexTest_1428") + << QLatin1String("RegexTest_1429") + << QLatin1String("RegexTest_1430") + << QLatin1String("RegexTest_1433") + << QLatin1String("RegexTest_1434") + << QLatin1String("RegexTest_1435") + << QLatin1String("RegexTest_1436") + << QLatin1String("RegexTest_1437") + << QLatin1String("RegexTest_1438") + << QLatin1String("RegexTest_1439") + << QLatin1String("RegexTest_1440") + << QLatin1String("RegexTest_1441") + << QLatin1String("RegexTest_1442") + << QLatin1String("RegexTest_1443") + << QLatin1String("RegexTest_1444") + << QLatin1String("RegexTest_1445") + << QLatin1String("RegexTest_1446") + << QLatin1String("RegexTest_1447") + << QLatin1String("RegexTest_1448") + << QLatin1String("RegexTest_1451") + << QLatin1String("RegexTest_1452") + << QLatin1String("RegexTest_1453") + << QLatin1String("RegexTest_1454") + << QLatin1String("RegexTest_1455") + << QLatin1String("RegexTest_1456") + << QLatin1String("RegexTest_1472") + << QLatin1String("RegexTest_1473") + << QLatin1String("RegexTest_1474") + << QLatin1String("RegexTest_1475") + << QLatin1String("RegexTest_1478") + << QLatin1String("RegexTest_1479") + << QLatin1String("RegexTest_1480") + << QLatin1String("RegexTest_1481") + << QLatin1String("RegexTest_1484") + << QLatin1String("RegexTest_1485") + << QLatin1String("RegexTest_1486") + << QLatin1String("RegexTest_1487") + << QLatin1String("RegexTest_1488") + << QLatin1String("RegexTest_1491") + << QLatin1String("RegexTest_1492") + << QLatin1String("RegexTest_1493") + << QLatin1String("RegexTest_1494") + << QLatin1String("RegexTest_1495") + << QLatin1String("RegexTest_1496") + << QLatin1String("RegexTest_1497") + << QLatin1String("RegexTest_1498") + << QLatin1String("RegexTest_1499") + << QLatin1String("RegexTest_1500") + << QLatin1String("RegexTest_1501") + << QLatin1String("RegexTest_1502") + << QLatin1String("RegexTest_1503") + << QLatin1String("RegexTest_1543") + << QLatin1String("RegexTest_1544") + << QLatin1String("reZ001") +*/ + << QLatin1String("schA2") + << QLatin1String("schA5") + << QLatin1String("schA7") + << QLatin1String("schD8") + << QLatin1String("schG3") + << QLatin1String("schG6") + << QLatin1String("schG9") + << QLatin1String("schG11") + << QLatin1String("schG12") + << QLatin1String("schU1") + << QLatin1String("schU3") + << QLatin1String("schU4") + << QLatin1String("schU5") + << QLatin1String("schZ004") + << QLatin1String("schZ005") + << QLatin1String("schZ012_a") + << QLatin1String("stZ041") + << QLatin1String("wildZ010"); +} + +bool XSDTestSuiteHandler::startElement(const QString &namespaceURI, + const QString &localName, + const QString &/*qName*/, + const QXmlAttributes &atts) +{ + if(namespaceURI != QString::fromLatin1("http://www.w3.org/XML/2004/xml-schema-test-suite/")) + return true; + + if (localName == QLatin1String("testSet")) { + m_currentTestSet = new TestGroup(m_topLevelGroup); + Q_ASSERT(m_currentTestSet); + m_currentTestSet->setTitle(atts.value("name")); + m_topLevelGroup->appendChild(m_currentTestSet); + } else if (localName == QLatin1String("testGroup")) { + m_currentTestGroup = new TestGroup(m_currentTestSet); + Q_ASSERT(m_currentTestGroup); + m_currentTestGroup->setTitle(atts.value("name")); + m_currentTestSet->appendChild(m_currentTestGroup); + m_inTestGroup = true; + } else if (localName == QLatin1String("schemaTest")) { + if (m_blackList.contains(atts.value("name"))) { + m_currentTestCase = 0; + m_schemaBlacklisted = true; + return true; + } + m_schemaBlacklisted = false; + + m_currentTestCase = new XSDTSTestCase(TestCase::Standard, m_currentTestGroup, XSDTSTestCase::SchemaTest); + Q_ASSERT(m_currentTestCase); + m_counter++; + m_currentTestCase->setName(QString::number(m_counter) + atts.value("name")); + m_currentTestGroup->appendChild(m_currentTestCase); + m_currentTestCase->setParent(m_currentTestGroup); + + m_inSchemaTest = true; + } else if (localName == QLatin1String("instanceTest")) { + if (m_schemaBlacklisted) { + m_currentTestCase = 0; + return true; + } + + m_currentTestCase = new XSDTSTestCase(TestCase::Standard, m_currentTestGroup, XSDTSTestCase::InstanceTest); + Q_ASSERT(m_currentTestCase); + m_counter++; + m_currentTestCase->setName(QString::number(m_counter) + atts.value("name")); + m_currentTestGroup->appendChild(m_currentTestCase); + + m_inInstanceTest = true; + } else if (localName == QLatin1String("schemaDocument") || localName == QLatin1String("instanceDocument")) { + if (m_inSchemaTest) { + m_currentTestCase->setSchemaUri(QUrl(atts.value("xlink:href"))); + if (m_currentSchemaLink.isEmpty()) // we only use the first schema document for validation + m_currentSchemaLink = atts.value("xlink:href"); + } + if (m_inInstanceTest) { + m_currentTestCase->setInstanceUri(QUrl(atts.value("xlink:href"))); + m_currentTestCase->setSchemaUri(QUrl(m_currentSchemaLink)); + } + } else if (localName == QLatin1String("expected") && (m_inSchemaTest || m_inInstanceTest)) { + TestBaseLine *baseLine = new TestBaseLine(TestBaseLine::SchemaIsValid); + if (atts.value("validity") == QLatin1String("valid")) { + baseLine->setDetails(QLatin1String("true")); + m_currentTestCase->setName(m_currentTestCase->name() + QLatin1String(" tokoe:valid")); + } else { + baseLine->setDetails(QLatin1String("false")); + m_currentTestCase->setName(m_currentTestCase->name() + QLatin1String(" tokoe:invalid")); + } + + m_currentTestCase->addBaseLine(baseLine); + } else if (localName == QLatin1String("documentation") && m_inTestGroup) { + m_inDescription = true; + } + + return true; +} + +bool XSDTestSuiteHandler::endElement(const QString &namespaceURI, + const QString &localName, + const QString &/*qName*/) +{ + if (localName == QLatin1String("testGroup")) { + m_inTestGroup = false; + m_currentTestGroup->setDescription(m_documentation); + m_documentation.clear(); + m_currentSchemaLink.clear(); + + if (m_currentTestGroup->childCount() == 0) + m_currentTestSet->removeLast(); + } else if (localName == QLatin1String("schemaTest")) + m_inSchemaTest = false; + else if (localName == QLatin1String("instanceTest")) + m_inInstanceTest = false; + else if (localName == QLatin1String("documentation")) + m_inDescription = false; + + return true; +} + +bool XSDTestSuiteHandler::characters(const QString &ch) +{ + if (m_inDescription) + m_documentation += ch; + + return true; +} + +TestSuite *XSDTestSuiteHandler::testSuite() const +{ + return m_ts; +} + +// vim: et:ts=4:sw=4:sts=4 + diff --git a/tests/auto/xmlpatternsxqts/lib/XSDTestSuiteHandler.h b/tests/auto/xmlpatternsxqts/lib/XSDTestSuiteHandler.h new file mode 100644 index 0000000..8c57e82 --- /dev/null +++ b/tests/auto/xmlpatternsxqts/lib/XSDTestSuiteHandler.h @@ -0,0 +1,90 @@ +/**************************************************************************** +** +** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the Patternist project on Trolltech Labs. +** +** $TROLLTECH_GPL_LICENSE$ +** +*************************************************************************** +*/ + +#ifndef PatternistSDK_XSDTestSuiteHandler_H +#define PatternistSDK_XSDTestSuiteHandler_H + +#include +#include + +#include "ExternalSourceLoader.h" +#include "TestSuite.h" +#include "XQTSTestCase.h" + +QT_BEGIN_HEADER + +namespace QPatternistSDK +{ + class TestBaseLine; + class TestGroup; + class XSDTSTestCase; + + /** + * @short Creates a TestSuite from the XSD Test Suite. + * + * The created TestSuite can be retrieved via testSuite(). + * + * @note XSDTestSuiteHandler assumes the XML is valid by having been validated + * against the W3C XML Schema. It has no safety checks for that the XML format + * is correct but is hard coded for it. Thus, the behavior is undefined if + * the XML is invalid. + * + * @ingroup PatternistSDK + * @author Tobias Koenig + */ + class Q_PATTERNISTSDK_EXPORT XSDTestSuiteHandler : public QXmlDefaultHandler + { + public: + /** + * @param catalogFile the URI for the catalog file being parsed. This + * URI is used for creating absolute URIs for files mentioned in + * the catalog with relative URIs. + * @param useExclusionList whether excludeTestGroups.txt should be used to ignore + * test groups when loading + */ + XSDTestSuiteHandler(const QUrl &catalogFile); + virtual bool characters(const QString &ch); + + virtual bool endElement(const QString &namespaceURI, + const QString &localName, + const QString &qName); + virtual bool startElement(const QString &namespaceURI, + const QString &localName, + const QString &qName, + const QXmlAttributes &atts); + + virtual TestSuite *testSuite() const; + + private: + TestSuite* m_ts; + const QUrl m_catalogFile; + + TestGroup* m_topLevelGroup; + TestGroup* m_currentTestSet; + TestGroup* m_currentTestGroup; + XSDTSTestCase* m_currentTestCase; + bool m_inSchemaTest; + bool m_inInstanceTest; + bool m_inTestGroup; + bool m_inDescription; + bool m_schemaBlacklisted; + QString m_documentation; + QString m_currentSchemaLink; + int m_counter; + QSet m_blackList; + }; +} + +QT_END_HEADER + +#endif +// vim: et:ts=4:sw=4:sts=4 diff --git a/tests/auto/xmlpatternsxqts/lib/lib.pro b/tests/auto/xmlpatternsxqts/lib/lib.pro index 5b12d63..cb9453a 100644 --- a/tests/auto/xmlpatternsxqts/lib/lib.pro +++ b/tests/auto/xmlpatternsxqts/lib/lib.pro @@ -50,6 +50,8 @@ HEADERS = ASTItem.h \ Worker.h \ XMLWriter.h \ XQTSTestCase.h \ + XSDTestSuiteHandler.h \ + XSDTSTestCase.h \ XSLTTestSuiteHandler.h SOURCES = ASTItem.cpp \ @@ -75,4 +77,6 @@ SOURCES = ASTItem.cpp \ Worker.cpp \ XMLWriter.cpp \ XQTSTestCase.cpp \ + XSDTestSuiteHandler.cpp \ + XSDTSTestCase.cpp \ XSLTTestSuiteHandler.cpp diff --git a/tests/auto/xmlpatternsxqts/test/tst_suitetest.cpp b/tests/auto/xmlpatternsxqts/test/tst_suitetest.cpp index 1f9e396..71abbb9 100644 --- a/tests/auto/xmlpatternsxqts/test/tst_suitetest.cpp +++ b/tests/auto/xmlpatternsxqts/test/tst_suitetest.cpp @@ -55,11 +55,11 @@ using namespace QPatternistSDK; -tst_SuiteTest::tst_SuiteTest(const bool isXSLT, +tst_SuiteTest::tst_SuiteTest(const SuiteType suiteType, const bool alwaysRun) : m_existingBaseline(inputFile(QLatin1String("Baseline.xml"))) , m_candidateBaseline(inputFile(QLatin1String("CandidateBaseline.xml"))) , m_abortRun(!alwaysRun && !QFile::exists(QLatin1String("runTests"))) - , m_isXSLT(isXSLT) + , m_suiteType(suiteType) { } @@ -86,7 +86,16 @@ void tst_SuiteTest::runTestSuite() const QString errMsg; const QFileInfo fi(m_catalogPath); const QUrl catalogPath(QUrl::fromLocalFile(fi.absoluteFilePath())); - TestSuite *const ts = TestSuite::openCatalog(catalogPath, errMsg, true, m_isXSLT); + + TestSuite::SuiteType suiteType; + switch (m_suiteType) { + case XQuerySuite: suiteType = TestSuite::XQuerySuite; + case XsltSuite: suiteType = TestSuite::XsltSuite; + case XsdSuite: suiteType = TestSuite::XsdSuite; + default: break; + } + + TestSuite *const ts = TestSuite::openCatalog(catalogPath, errMsg, true, suiteType); QVERIFY2(ts, qPrintable(QString::fromLatin1("Failed to open the catalog, maybe it doesn't exist or is broken: %1").arg(errMsg))); diff --git a/tests/auto/xmlpatternsxqts/test/tst_suitetest.h b/tests/auto/xmlpatternsxqts/test/tst_suitetest.h index 922f645..05bf6cb 100644 --- a/tests/auto/xmlpatternsxqts/test/tst_suitetest.h +++ b/tests/auto/xmlpatternsxqts/test/tst_suitetest.h @@ -50,13 +50,21 @@ \class tst_SuiteTest \internal \since 4.5 - \brief Base class for tst_XmlPatternsXQTS and tst_XmlPatternsXSLTS. + \brief Base class for tst_XmlPatternsXQTS, tst_XmlPatternsXSLTS and tst_XmlPatternsXSDTS. */ class tst_SuiteTest : public QObject , private TestFundament { Q_OBJECT +public: + enum SuiteType + { + XQuerySuite, + XsltSuite, + XsdSuite + }; + protected: /** * @p isXSLT is @c true if the catalog opened is an @@ -65,7 +73,7 @@ protected: * @p alwaysRun is @c true if the test should always be run, * regardless of if the file runTests exists. */ - tst_SuiteTest(const bool isXSLT, + tst_SuiteTest(SuiteType type, const bool alwaysRun = false); /** @@ -91,7 +99,7 @@ private: const QString m_existingBaseline; const QString m_candidateBaseline; const bool m_abortRun; - const bool m_isXSLT; + const SuiteType m_suiteType; }; #endif diff --git a/tests/auto/xmlpatternsxqts/test/tst_xmlpatternsxqts.cpp b/tests/auto/xmlpatternsxqts/test/tst_xmlpatternsxqts.cpp index 6d9502d..1193372 100644 --- a/tests/auto/xmlpatternsxqts/test/tst_xmlpatternsxqts.cpp +++ b/tests/auto/xmlpatternsxqts/test/tst_xmlpatternsxqts.cpp @@ -61,7 +61,7 @@ public: virtual void catalogPath(QString &write) const; }; -tst_XmlPatternsXQTS::tst_XmlPatternsXQTS() : tst_SuiteTest(false) +tst_XmlPatternsXQTS::tst_XmlPatternsXQTS() : tst_SuiteTest(tst_SuiteTest::XQuerySuite) { } diff --git a/tests/auto/xmlpatternsxslts/tst_xmlpatternsxslts.cpp b/tests/auto/xmlpatternsxslts/tst_xmlpatternsxslts.cpp index 6f1d217..f9b1c76 100644 --- a/tests/auto/xmlpatternsxslts/tst_xmlpatternsxslts.cpp +++ b/tests/auto/xmlpatternsxslts/tst_xmlpatternsxslts.cpp @@ -61,7 +61,7 @@ protected: virtual void catalogPath(QString &write) const; }; -tst_XmlPatternsXSLTS::tst_XmlPatternsXSLTS() : tst_SuiteTest(true) +tst_XmlPatternsXSLTS::tst_XmlPatternsXSLTS() : tst_SuiteTest(tst_SuiteTest::XsltSuite) { } diff --git a/tools/tools.pro b/tools/tools.pro index 0a56cfb..e7f7b03 100644 --- a/tools/tools.pro +++ b/tools/tools.pro @@ -25,7 +25,7 @@ mac { SUBDIRS += kmap2qmap contains(QT_CONFIG, dbus):SUBDIRS += qdbus -!wince*:contains(QT_CONFIG, xmlpatterns): SUBDIRS += xmlpatterns +!wince*:contains(QT_CONFIG, xmlpatterns): SUBDIRS += xmlpatterns xmlpatternsvalidator embedded: SUBDIRS += makeqpf CONFIG+=ordered diff --git a/tools/xmlpatternsvalidator/main.cpp b/tools/xmlpatternsvalidator/main.cpp new file mode 100644 index 0000000..032afc0 --- /dev/null +++ b/tools/xmlpatternsvalidator/main.cpp @@ -0,0 +1,96 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the Patternist project on Trolltech Labs. +** +** $TROLLTECH_DUAL_LICENSE$ +** +****************************************************************************/ + +#include "main.h" + +#include +#include +#include +#include +#include + +QT_USE_NAMESPACE + +enum ExecutionMode +{ + InvalidMode, + SchemaOnlyMode, + SchemaAndInstanceMode, + InstanceOnlyMode +}; + +int main(int argc, char **argv) +{ + const QCoreApplication app(argc, argv); + QCoreApplication::setApplicationName(QLatin1String("xmlpatternsvalidator")); + + if (argc != 2 && argc != 3) { + qDebug() << QXmlPatternistCLI::tr("usage: xmlpatternsvalidator ( | | )"); + return 2; + } + + // parse command line arguments + ExecutionMode mode = InvalidMode; + + if (argc == 2) { + // either it is a schema or instance document + + QString url = QFile::decodeName(argv[1]); + if (url.toLower().endsWith(QLatin1String(".xsd"))) { + mode = SchemaOnlyMode; + } else { + // as we could validate all types of xml documents, don't check the extension here + mode = InstanceOnlyMode; + } + } else if (argc == 3) { + mode = SchemaAndInstanceMode; + } + + // do validation + QXmlSchema schema; + + if (mode == SchemaOnlyMode) { + const QString schemaUri = QFile::decodeName(argv[1]); + + schema.load(QUrl(schemaUri)); + + if (schema.isValid()) + return 0; + else + return 1; + } else if (mode == SchemaAndInstanceMode) { + const QString instanceUri = QFile::decodeName(argv[1]); + const QString schemaUri = QFile::decodeName(argv[2]); + + schema.load(QUrl(schemaUri)); + + if (!schema.isValid()) + return 1; + + QXmlSchemaValidator validator(schema); + if (validator.validate(QUrl(instanceUri))) + return 0; + else + return 1; + } else if (mode == InstanceOnlyMode) { + const QString instanceUri = QFile::decodeName(argv[1]); + + QXmlSchemaValidator validator(schema); + if (validator.validate(QUrl(instanceUri))) + return 0; + else + return 1; + } + + Q_ASSERT(false); + + return 1; +} diff --git a/tools/xmlpatternsvalidator/main.h b/tools/xmlpatternsvalidator/main.h new file mode 100644 index 0000000..477a45a --- /dev/null +++ b/tools/xmlpatternsvalidator/main.h @@ -0,0 +1,46 @@ +/**************************************************************************** + ** + ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). + ** Contact: Qt Software Information (qt-info@nokia.com) + ** + ** This file is part of the Patternist project on Trolltech Labs. * ** + ** $TROLLTECH_DUAL_LICENSE$ + ** + ** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE + ** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. + ** + ****************************************************************************/ + +// +// 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_main_h +#define Patternist_main_h + +#include + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +class QXmlPatternistCLI +{ +public: + Q_DECLARE_TR_FUNCTIONS(QXmlPatternistCLI) +private: + inline QXmlPatternistCLI(); + Q_DISABLE_COPY(QXmlPatternistCLI) +}; + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif diff --git a/tools/xmlpatternsvalidator/xmlpatternsvalidator.pro b/tools/xmlpatternsvalidator/xmlpatternsvalidator.pro new file mode 100644 index 0000000..dd5bd37 --- /dev/null +++ b/tools/xmlpatternsvalidator/xmlpatternsvalidator.pro @@ -0,0 +1,19 @@ +TEMPLATE = app +TARGET = xmlpatternsvalidator +DESTDIR = ../../bin +QT -= gui +QT += xmlpatterns + +target.path = $$[QT_INSTALL_BINS] +INSTALLS += target + +# This ensures we get stderr and stdout on Windows. +CONFIG += console + +# This ensures that this is a command-line program on OS X and not a GUI application. +CONFIG -= app_bundle + +SOURCES = main.cpp +HEADERS = main.h + +include(../src/common.pri) -- cgit v0.12 From 456463169c6d00b9938f0d975dbd7f398edea39d Mon Sep 17 00:00:00 2001 From: Tobias Koenig Date: Sat, 16 May 2009 12:30:25 +0200 Subject: Various api, documentation and code cleanups --- src/xmlpatterns/api/qxmlquery.cpp | 6 +- src/xmlpatterns/api/qxmlquery_p.h | 13 -- src/xmlpatterns/api/qxmlschema.cpp | 19 +- src/xmlpatterns/api/qxmlschema.h | 11 +- src/xmlpatterns/api/qxmlschema_p.cpp | 8 +- src/xmlpatterns/api/qxmlschema_p.h | 6 +- src/xmlpatterns/api/qxmlschemavalidator.cpp | 38 +++- src/xmlpatterns/api/qxmlschemavalidator.h | 13 +- src/xmlpatterns/api/qxmlschemavalidator_p.h | 5 +- src/xmlpatterns/schema/qnamespacesupport.cpp | 4 +- src/xmlpatterns/schema/qxsdparticlechecker.cpp | 6 +- src/xmlpatterns/schema/qxsdschemacontext.cpp | 2 +- src/xmlpatterns/schema/qxsdschemacontext_p.h | 4 +- src/xmlpatterns/schema/qxsdschemadebugger_p.h | 2 +- src/xmlpatterns/schema/qxsdschemahelper.cpp | 4 +- src/xmlpatterns/schema/qxsdschemahelper_p.h | 63 +++++-- src/xmlpatterns/schema/qxsdschemaparser.cpp | 46 +++-- src/xmlpatterns/schema/qxsdstatemachine.cpp | 16 +- src/xmlpatterns/schema/qxsdstatemachine_p.h | 6 + .../schema/qxsdvalidatedxmlnodemodel.cpp | 2 +- .../schema/qxsdvalidatedxmlnodemodel_p.h | 10 +- .../schema/qxsdvalidatinginstancereader.cpp | 15 +- .../schema/qxsdvalidatinginstancereader_p.h | 2 +- src/xmlpatterns/utils/qxpathhelper.cpp | 12 ++ src/xmlpatterns/utils/qxpathhelper_p.h | 5 + .../patternistheaders/tst_patternistheaders.cpp | 8 + tests/auto/qxmlschema/tst_qxmlschema.cpp | 195 ++++++++++++++++++--- .../tst_qxmlschemavalidator.cpp | 145 +++++++++++---- tools/xmlpatternsvalidator/main.cpp | 41 +++-- 29 files changed, 521 insertions(+), 186 deletions(-) diff --git a/src/xmlpatterns/api/qxmlquery.cpp b/src/xmlpatterns/api/qxmlquery.cpp index 423da3e..1cf0a2e 100644 --- a/src/xmlpatterns/api/qxmlquery.cpp +++ b/src/xmlpatterns/api/qxmlquery.cpp @@ -427,7 +427,7 @@ void QXmlQuery::setQuery(QIODevice *sourceCode, const QUrl &documentURI) return; } - d->queryURI = QXmlQueryPrivate::normalizeQueryURI(documentURI); + d->queryURI = QPatternist::XPathHelper::normalizeQueryURI(documentURI); d->expression(sourceCode); } @@ -475,12 +475,12 @@ void QXmlQuery::setQuery(const QUrl &queryURI, const QUrl &baseURI) { Q_ASSERT_X(queryURI.isValid(), Q_FUNC_INFO, "The passed URI must be valid."); - const QUrl canonicalURI(QXmlQueryPrivate::normalizeQueryURI(queryURI)); + const QUrl canonicalURI(QPatternist::XPathHelper::normalizeQueryURI(queryURI)); Q_ASSERT(canonicalURI.isValid()); Q_ASSERT(!canonicalURI.isRelative()); Q_ASSERT(baseURI.isValid() || baseURI.isEmpty()); - d->queryURI = QXmlQueryPrivate::normalizeQueryURI(baseURI.isEmpty() ? queryURI : baseURI); + d->queryURI = QPatternist::XPathHelper::normalizeQueryURI(baseURI.isEmpty() ? queryURI : baseURI); QPatternist::AutoPtr result; diff --git a/src/xmlpatterns/api/qxmlquery_p.h b/src/xmlpatterns/api/qxmlquery_p.h index 7f58f97..486d885 100644 --- a/src/xmlpatterns/api/qxmlquery_p.h +++ b/src/xmlpatterns/api/qxmlquery_p.h @@ -212,19 +212,6 @@ public: return m_resourceLoader; } - - static inline QUrl normalizeQueryURI(const QUrl &uri) - { - Q_ASSERT_X(uri.isEmpty() || uri.isValid(), Q_FUNC_INFO, - "The URI passed to QXmlQuery::setQuery() must be valid or empty."); - if(uri.isEmpty()) - return QUrl::fromLocalFile(QCoreApplication::applicationFilePath()); - else if(uri.isRelative()) - return QUrl::fromLocalFile(QCoreApplication::applicationFilePath()).resolved(uri); - else - return uri; - } - void setRequiredType(const QPatternist::SequenceType::Ptr &seqType) { Q_ASSERT(seqType); diff --git a/src/xmlpatterns/api/qxmlschema.cpp b/src/xmlpatterns/api/qxmlschema.cpp index 55b96cd..108212e 100644 --- a/src/xmlpatterns/api/qxmlschema.cpp +++ b/src/xmlpatterns/api/qxmlschema.cpp @@ -21,7 +21,7 @@ \brief The QXmlSchema class provides loading and validation of a W3C XML Schema. \reentrant - \since 4.X + \since 4.6 \ingroup xml-tools The QXmlSchema class loads, compiles and validates W3C XML Schema files @@ -31,7 +31,7 @@ /*! Constructs an invalid, empty schema that cannot be used until - setSchema() is called. + load() is called. */ QXmlSchema::QXmlSchema() : d(new QXmlSchemaPrivate(QXmlNamePool())) @@ -59,9 +59,10 @@ QXmlSchema::~QXmlSchema() Sets this QXmlSchema to a schema loaded from the \a source URI. */ -void QXmlSchema::load(const QUrl &source) +bool QXmlSchema::load(const QUrl &source) { d->load(source, QString()); + return d->isValid(); } /*! @@ -78,9 +79,10 @@ void QXmlSchema::load(const QUrl &source) a valid URI, behavior is undefined. \sa isValid() */ -void QXmlSchema::load(QIODevice *source, const QUrl &documentUri) +bool QXmlSchema::load(QIODevice *source, const QUrl &documentUri) { d->load(source, documentUri, QString()); + return d->isValid(); } /*! @@ -94,9 +96,10 @@ void QXmlSchema::load(QIODevice *source, const QUrl &documentUri) If \a documentUri is not a valid URI, behavior is undefined. \sa isValid() */ -void QXmlSchema::load(const QByteArray &data, const QUrl &documentUri) +bool QXmlSchema::load(const QByteArray &data, const QUrl &documentUri) { d->load(data, documentUri, QString()); + return d->isValid(); } /*! @@ -183,14 +186,14 @@ QAbstractMessageHandler *QXmlSchema::messageHandler() const \sa uriResolver() */ -void QXmlSchema::setUriResolver(QAbstractUriResolver *resolver) +void QXmlSchema::setUriResolver(const QAbstractUriResolver *resolver) { d->setUriResolver(resolver); } /*! Returns the schema's URI resolver. If no URI resolver has been set, - QtXmlPatterns will use the URIs in queries as they are. + QtXmlPatterns will use the URIs in schemas as they are. The URI resolver provides a level of abstraction, or \e{polymorphic URIs}. A resolver can rewrite \e{logical} URIs to physical ones, or @@ -202,7 +205,7 @@ void QXmlSchema::setUriResolver(QAbstractUriResolver *resolver) \sa setUriResolver() */ -QAbstractUriResolver *QXmlSchema::uriResolver() const +const QAbstractUriResolver *QXmlSchema::uriResolver() const { return d->uriResolver(); } diff --git a/src/xmlpatterns/api/qxmlschema.h b/src/xmlpatterns/api/qxmlschema.h index 225cce2..cf56b1e 100644 --- a/src/xmlpatterns/api/qxmlschema.h +++ b/src/xmlpatterns/api/qxmlschema.h @@ -13,6 +13,7 @@ #define QXMLSCHEMA_H #include +#include #include QT_BEGIN_HEADER @@ -37,9 +38,9 @@ class Q_XMLPATTERNS_EXPORT QXmlSchema QXmlSchema(const QXmlSchema &other); ~QXmlSchema(); - void load(const QUrl &source); - void load(QIODevice *source, const QUrl &documentUri); - void load(const QByteArray &data, const QUrl &documentUri); + bool load(const QUrl &source); + bool load(QIODevice *source, const QUrl &documentUri = QUrl()); + bool load(const QByteArray &data, const QUrl &documentUri = QUrl()); bool isValid() const; @@ -49,8 +50,8 @@ class Q_XMLPATTERNS_EXPORT QXmlSchema void setMessageHandler(QAbstractMessageHandler *handler); QAbstractMessageHandler *messageHandler() const; - void setUriResolver(QAbstractUriResolver *resolver); - QAbstractUriResolver *uriResolver() const; + void setUriResolver(const QAbstractUriResolver *resolver); + const QAbstractUriResolver *uriResolver() const; void setNetworkAccessManager(QNetworkAccessManager *networkmanager); QNetworkAccessManager *networkAccessManager() const; diff --git a/src/xmlpatterns/api/qxmlschema_p.cpp b/src/xmlpatterns/api/qxmlschema_p.cpp index ebcccee..21dc04a 100644 --- a/src/xmlpatterns/api/qxmlschema_p.cpp +++ b/src/xmlpatterns/api/qxmlschema_p.cpp @@ -61,7 +61,7 @@ QXmlSchemaPrivate::QXmlSchemaPrivate(const QXmlSchemaPrivate &other) void QXmlSchemaPrivate::load(const QUrl &source, const QString &targetNamespace) { - m_documentUri = source; + m_documentUri = QPatternist::XPathHelper::normalizeQueryURI(source); m_schemaContext->setMessageHandler(messageHandler()); m_schemaContext->setUriResolver(uriResolver()); @@ -98,7 +98,7 @@ void QXmlSchemaPrivate::load(QIODevice *source, const QUrl &documentUri, const Q return; } - m_documentUri = documentUri; + m_documentUri = QPatternist::XPathHelper::normalizeQueryURI(documentUri); m_schemaContext->setMessageHandler(messageHandler()); m_schemaContext->setUriResolver(uriResolver()); m_schemaContext->setNetworkAccessManager(networkAccessManager()); @@ -145,12 +145,12 @@ QAbstractMessageHandler *QXmlSchemaPrivate::messageHandler() const return m_messageHandler.data()->value; } -void QXmlSchemaPrivate::setUriResolver(QAbstractUriResolver *resolver) +void QXmlSchemaPrivate::setUriResolver(const QAbstractUriResolver *resolver) { m_uriResolver = resolver; } -QAbstractUriResolver *QXmlSchemaPrivate::uriResolver() const +const QAbstractUriResolver *QXmlSchemaPrivate::uriResolver() const { return m_uriResolver; } diff --git a/src/xmlpatterns/api/qxmlschema_p.h b/src/xmlpatterns/api/qxmlschema_p.h index e625f1e..efba256 100644 --- a/src/xmlpatterns/api/qxmlschema_p.h +++ b/src/xmlpatterns/api/qxmlschema_p.h @@ -54,14 +54,14 @@ class QXmlSchemaPrivate : public QSharedData QUrl documentUri() const; void setMessageHandler(QAbstractMessageHandler *handler); QAbstractMessageHandler *messageHandler() const; - void setUriResolver(QAbstractUriResolver *resolver); - QAbstractUriResolver *uriResolver() const; + void setUriResolver(const QAbstractUriResolver *resolver); + const QAbstractUriResolver *uriResolver() const; void setNetworkAccessManager(QNetworkAccessManager *networkmanager); QNetworkAccessManager *networkAccessManager() const; QXmlNamePool m_namePool; QAbstractMessageHandler* m_userMessageHandler; - QAbstractUriResolver* m_uriResolver; + const QAbstractUriResolver* m_uriResolver; QNetworkAccessManager* m_userNetworkAccessManager; QPatternist::ReferenceCountedValue::Ptr m_messageHandler; QPatternist::ReferenceCountedValue::Ptr m_networkAccessManager; diff --git a/src/xmlpatterns/api/qxmlschemavalidator.cpp b/src/xmlpatterns/api/qxmlschemavalidator.cpp index aa80537..fcde49c 100644 --- a/src/xmlpatterns/api/qxmlschemavalidator.cpp +++ b/src/xmlpatterns/api/qxmlschemavalidator.cpp @@ -27,7 +27,7 @@ \brief The QXmlSchemaValidator class validates XML instance documents against a W3C XML Schema. \reentrant - \since 4.X + \since 4.6 \ingroup xml-tools The QXmlSchemaValidator class loads, parses an XML instance document and validates it @@ -35,6 +35,16 @@ */ /*! + Constructs a schema validator. + The schema used for validation must be referenced in the XML instance document + via the xsi:schemaLocation attribute. + */ +QXmlSchemaValidator::QXmlSchemaValidator() + : d(new QXmlSchemaValidatorPrivate(QXmlSchema())) +{ +} + +/*! Constructs a schema validator that will use \a schema for validation. */ QXmlSchemaValidator::QXmlSchemaValidator(const QXmlSchema &schema) @@ -65,7 +75,7 @@ void QXmlSchemaValidator::setSchema(const QXmlSchema &schema) Returns \c true if the XML instance document is valid according the schema, \c false otherwise. */ -bool QXmlSchemaValidator::validate(const QByteArray &data, const QUrl &documentUri) +bool QXmlSchemaValidator::validate(const QByteArray &data, const QUrl &documentUri) const { QByteArray localData(data); @@ -81,7 +91,7 @@ bool QXmlSchemaValidator::validate(const QByteArray &data, const QUrl &documentU Returns \c true if the XML instance document is valid according the schema, \c false otherwise. */ -bool QXmlSchemaValidator::validate(const QUrl &source) +bool QXmlSchemaValidator::validate(const QUrl &source) const { d->m_context->setMessageHandler(messageHandler()); d->m_context->setUriResolver(uriResolver()); @@ -102,7 +112,7 @@ bool QXmlSchemaValidator::validate(const QUrl &source) Returns \c true if the XML instance document is valid according the schema, \c false otherwise. */ -bool QXmlSchemaValidator::validate(QIODevice *source, const QUrl &documentUri) +bool QXmlSchemaValidator::validate(QIODevice *source, const QUrl &documentUri) const { if (!source) { qWarning("A null QIODevice pointer cannot be passed."); @@ -114,6 +124,8 @@ bool QXmlSchemaValidator::validate(QIODevice *source, const QUrl &documentUri) return false; } + const QUrl normalizedUri = QPatternist::XPathHelper::normalizeQueryURI(documentUri); + d->m_context->setMessageHandler(messageHandler()); d->m_context->setUriResolver(uriResolver()); d->m_context->setNetworkAccessManager(networkAccessManager()); @@ -125,7 +137,7 @@ bool QXmlSchemaValidator::validate(QIODevice *source, const QUrl &documentUri) QPatternist::Item item; try { - item = loader.openDocument(source, documentUri, d->m_context); + item = loader.openDocument(source, normalizedUri, d->m_context); } catch (QPatternist::Exception exception) { return false; } @@ -135,7 +147,7 @@ bool QXmlSchemaValidator::validate(QIODevice *source, const QUrl &documentUri) QPatternist::XsdValidatedXmlNodeModel *validatedModel = new QPatternist::XsdValidatedXmlNodeModel(model); - QPatternist::XsdValidatingInstanceReader reader(validatedModel, documentUri, d->m_context); + QPatternist::XsdValidatingInstanceReader reader(validatedModel, normalizedUri, d->m_context); if (d->m_schema) reader.addSchema(d->m_schema, d->m_schemaDocumentUri); try { @@ -158,6 +170,14 @@ QXmlNamePool QXmlSchemaValidator::namePool() const } /*! + Returns the schema that is used for validation. + */ +QXmlSchema QXmlSchemaValidator::schema() const +{ + return d->m_originalSchema; +} + +/*! Changes the \l {QAbstractMessageHandler}{message handler} for this QXmlSchemaValidator to \a handler. The schema validator sends all parsing and validation messages to this message handler. QXmlSchemaValidator does not take @@ -215,14 +235,14 @@ QAbstractMessageHandler *QXmlSchemaValidator::messageHandler() const \sa uriResolver() */ -void QXmlSchemaValidator::setUriResolver(QAbstractUriResolver *resolver) +void QXmlSchemaValidator::setUriResolver(const QAbstractUriResolver *resolver) { d->m_uriResolver = resolver; } /*! Returns the schema's URI resolver. If no URI resolver has been set, - QtXmlPatterns will use the URIs in queries as they are. + QtXmlPatterns will use the URIs in instance documents as they are. The URI resolver provides a level of abstraction, or \e{polymorphic URIs}. A resolver can rewrite \e{logical} URIs to physical ones, or @@ -234,7 +254,7 @@ void QXmlSchemaValidator::setUriResolver(QAbstractUriResolver *resolver) \sa setUriResolver() */ -QAbstractUriResolver *QXmlSchemaValidator::uriResolver() const +const QAbstractUriResolver *QXmlSchemaValidator::uriResolver() const { return d->m_uriResolver; } diff --git a/src/xmlpatterns/api/qxmlschemavalidator.h b/src/xmlpatterns/api/qxmlschemavalidator.h index e643995..c82c522 100644 --- a/src/xmlpatterns/api/qxmlschemavalidator.h +++ b/src/xmlpatterns/api/qxmlschemavalidator.h @@ -12,6 +12,7 @@ #ifndef QXMLSCHEMAVALIDATOR_H #define QXMLSCHEMAVALIDATOR_H +#include #include QT_BEGIN_HEADER @@ -31,22 +32,24 @@ class QXmlSchemaValidatorPrivate; class Q_XMLPATTERNS_EXPORT QXmlSchemaValidator { public: + QXmlSchemaValidator(); QXmlSchemaValidator(const QXmlSchema &schema); ~QXmlSchemaValidator(); void setSchema(const QXmlSchema &schema); - bool validate(const QUrl &source); - bool validate(QIODevice *source, const QUrl &documentUri); - bool validate(const QByteArray &data, const QUrl &documentUri); + bool validate(const QUrl &source) const; + bool validate(QIODevice *source, const QUrl &documentUri = QUrl()) const; + bool validate(const QByteArray &data, const QUrl &documentUri = QUrl()) const; QXmlNamePool namePool() const; + QXmlSchema schema() const; void setMessageHandler(QAbstractMessageHandler *handler); QAbstractMessageHandler *messageHandler() const; - void setUriResolver(QAbstractUriResolver *resolver); - QAbstractUriResolver *uriResolver() const; + void setUriResolver(const QAbstractUriResolver *resolver); + const QAbstractUriResolver *uriResolver() const; void setNetworkAccessManager(QNetworkAccessManager *networkmanager); QNetworkAccessManager *networkAccessManager() const; diff --git a/src/xmlpatterns/api/qxmlschemavalidator_p.h b/src/xmlpatterns/api/qxmlschemavalidator_p.h index 0990f73..9910f6e 100644 --- a/src/xmlpatterns/api/qxmlschemavalidator_p.h +++ b/src/xmlpatterns/api/qxmlschemavalidator_p.h @@ -77,15 +77,18 @@ public: m_context = QPatternist::XsdSchemaContext::Ptr(new QPatternist::XsdSchemaContext(m_namePool.d)); m_context->m_schemaTypeFactory = schema.d->m_schemaContext->m_schemaTypeFactory; m_context->m_builtinTypesFacetList = schema.d->m_schemaContext->m_builtinTypesFacetList; + + m_originalSchema = schema; } QXmlNamePool m_namePool; QAbstractMessageHandler* m_userMessageHandler; - QAbstractUriResolver* m_uriResolver; + const QAbstractUriResolver* m_uriResolver; QNetworkAccessManager* m_userNetworkAccessManager; QPatternist::ReferenceCountedValue::Ptr m_messageHandler; QPatternist::ReferenceCountedValue::Ptr m_networkAccessManager; + QXmlSchema m_originalSchema; QPatternist::XsdSchemaContext::Ptr m_context; QPatternist::XsdSchema::Ptr m_schema; QUrl m_schemaDocumentUri; diff --git a/src/xmlpatterns/schema/qnamespacesupport.cpp b/src/xmlpatterns/schema/qnamespacesupport.cpp index 00698d6..349f451 100644 --- a/src/xmlpatterns/schema/qnamespacesupport.cpp +++ b/src/xmlpatterns/schema/qnamespacesupport.cpp @@ -33,9 +33,7 @@ NamespaceSupport::NamespaceSupport(const NamePool::Ptr &namePool) : m_namePool(namePool) { // the XML namespace - const QXmlName binding = namePool->allocateBinding(QLatin1String("xml"), - QLatin1String("http://www.w3.org/XML/1998/namespace")); - m_ns.insert(binding.prefix(), binding.namespaceURI()); + m_ns.insert(StandardPrefixes::xml, StandardNamespaces::xml); } void NamespaceSupport::setPrefix(const QXmlName::PrefixCode prefixCode, const QXmlName::NamespaceCode namespaceCode) diff --git a/src/xmlpatterns/schema/qxsdparticlechecker.cpp b/src/xmlpatterns/schema/qxsdparticlechecker.cpp index 1bdef00..7a09f8a 100644 --- a/src/xmlpatterns/schema/qxsdparticlechecker.cpp +++ b/src/xmlpatterns/schema/qxsdparticlechecker.cpp @@ -180,9 +180,9 @@ static bool derivedTermValid(const XsdTerm::Ptr &baseTerm, const XsdTerm::Ptr &d // check that the constraints of the derived element are more strict then the constraints of the base element const XsdElement::BlockingConstraints baseConstraints = element->disallowedSubstitutions(); const XsdElement::BlockingConstraints derivedConstraints = derivedElement->disallowedSubstitutions(); - if ((baseConstraints & XsdElement::RestrictionConstraint) && !(derivedConstraints & XsdElement::RestrictionConstraint) || - (baseConstraints & XsdElement::ExtensionConstraint) && !(derivedConstraints & XsdElement::ExtensionConstraint) || - (baseConstraints & XsdElement::SubstitutionConstraint) && !(derivedConstraints & XsdElement::SubstitutionConstraint)) { + if (((baseConstraints & XsdElement::RestrictionConstraint) && !(derivedConstraints & XsdElement::RestrictionConstraint)) || + ((baseConstraints & XsdElement::ExtensionConstraint) && !(derivedConstraints & XsdElement::ExtensionConstraint)) || + ((baseConstraints & XsdElement::SubstitutionConstraint) && !(derivedConstraints & XsdElement::SubstitutionConstraint))) { errorMsg = QtXmlPatterns::tr("block constraints of derived element %1 must not be more weaker than in the base element").arg(formatKeyword(derivedElement->displayName(namePool))); return false; } diff --git a/src/xmlpatterns/schema/qxsdschemacontext.cpp b/src/xmlpatterns/schema/qxsdschemacontext.cpp index 57736bd..65b2e52 100644 --- a/src/xmlpatterns/schema/qxsdschemacontext.cpp +++ b/src/xmlpatterns/schema/qxsdschemacontext.cpp @@ -67,7 +67,7 @@ QSourceLocation XsdSchemaContext::locationFor(const SourceLocationReflection *co return QSourceLocation(); } -void XsdSchemaContext::setUriResolver(QAbstractUriResolver *uriResolver) +void XsdSchemaContext::setUriResolver(const QAbstractUriResolver *uriResolver) { m_uriResolver = uriResolver; } diff --git a/src/xmlpatterns/schema/qxsdschemacontext_p.h b/src/xmlpatterns/schema/qxsdschemacontext_p.h index cf52028..c3a9f15 100644 --- a/src/xmlpatterns/schema/qxsdschemacontext_p.h +++ b/src/xmlpatterns/schema/qxsdschemacontext_p.h @@ -115,7 +115,7 @@ namespace QPatternist * Sets the uri @p resolver that is used for resolving URIs in the * schema parser. */ - void setUriResolver(QAbstractUriResolver *resolver); + void setUriResolver(const QAbstractUriResolver *resolver); /** * Returns the uri resolver that is used for resolving URIs in the @@ -145,7 +145,7 @@ namespace QPatternist NamePool::Ptr m_namePool; QNetworkAccessManager* m_networkAccessManager; QUrl m_baseURI; - QAbstractUriResolver* m_uriResolver; + const QAbstractUriResolver* m_uriResolver; QAbstractMessageHandler* m_messageHandler; }; } diff --git a/src/xmlpatterns/schema/qxsdschemadebugger_p.h b/src/xmlpatterns/schema/qxsdschemadebugger_p.h index 8c12f0f..8966963 100644 --- a/src/xmlpatterns/schema/qxsdschemadebugger_p.h +++ b/src/xmlpatterns/schema/qxsdschemadebugger_p.h @@ -85,7 +85,7 @@ namespace QPatternist void dumpSchema(const XsdSchema::Ptr &schema); private: - NamePool::Ptr m_namePool; + const NamePool::Ptr m_namePool; }; } diff --git a/src/xmlpatterns/schema/qxsdschemahelper.cpp b/src/xmlpatterns/schema/qxsdschemahelper.cpp index 752af89..ff169f7 100644 --- a/src/xmlpatterns/schema/qxsdschemahelper.cpp +++ b/src/xmlpatterns/schema/qxsdschemahelper.cpp @@ -409,7 +409,7 @@ bool XsdSchemaHelper::isValidlySubstitutable(const SchemaType::Ptr &type, const return false; } -bool XsdSchemaHelper::isSimpleDerivationOk(const SchemaType::Ptr &derivedType, const SchemaType::Ptr baseType, const SchemaType::DerivationConstraints &constraints) +bool XsdSchemaHelper::isSimpleDerivationOk(const SchemaType::Ptr &derivedType, const SchemaType::Ptr &baseType, const SchemaType::DerivationConstraints &constraints) { // @see http://www.w3.org/TR/xmlschema11-1/#cos-st-derived-ok @@ -453,7 +453,7 @@ bool XsdSchemaHelper::isSimpleDerivationOk(const SchemaType::Ptr &derivedType, c return false; } -bool XsdSchemaHelper::isComplexDerivationOk(const SchemaType::Ptr &derivedType, const SchemaType::Ptr baseType, const SchemaType::DerivationConstraints &constraints) +bool XsdSchemaHelper::isComplexDerivationOk(const SchemaType::Ptr &derivedType, const SchemaType::Ptr &baseType, const SchemaType::DerivationConstraints &constraints) { if (!derivedType) return false; diff --git a/src/xmlpatterns/schema/qxsdschemahelper_p.h b/src/xmlpatterns/schema/qxsdschemahelper_p.h index 1722b4c..918664e 100644 --- a/src/xmlpatterns/schema/qxsdschemahelper_p.h +++ b/src/xmlpatterns/schema/qxsdschemahelper_p.h @@ -55,12 +55,15 @@ namespace QPatternist /** * Checks whether the given @p nameSpace is allowed by the given namespace @p constraint. */ - static bool wildcardAllowsNamespaceName(const QString &nameSpace, const XsdWildcard::NamespaceConstraint::Ptr &constraint); + static bool wildcardAllowsNamespaceName(const QString &nameSpace, + const XsdWildcard::NamespaceConstraint::Ptr &constraint); /** * Checks whether the given @p name is allowed by the namespace constraint of the given @p wildcard. */ - static bool wildcardAllowsExpandedName(const QXmlName &name, const XsdWildcard::Ptr &wildcard, const NamePool::Ptr &namePool); + static bool wildcardAllowsExpandedName(const QXmlName &name, + const XsdWildcard::Ptr &wildcard, + const NamePool::Ptr &namePool); /** * Checks whether the @p wildcard is a subset of @p otherWildcard. @@ -75,25 +78,32 @@ namespace QPatternist /** * Returns the intersection of the given @p wildcard and @p otherWildcard. */ - static XsdWildcard::Ptr wildcardIntersection(const XsdWildcard::Ptr &wildcard, const XsdWildcard::Ptr &otherWildcard); + static XsdWildcard::Ptr wildcardIntersection(const XsdWildcard::Ptr &wildcard, + const XsdWildcard::Ptr &otherWildcard); /** * Returns whether the given @p type is validly substitutable for an @p otherType * under the given @p constraints. */ - static bool isValidlySubstitutable(const SchemaType::Ptr &type, const SchemaType::Ptr &otherType, const SchemaType::DerivationConstraints &constraints); + static bool isValidlySubstitutable(const SchemaType::Ptr &type, + const SchemaType::Ptr &otherType, + const SchemaType::DerivationConstraints &constraints); /** * Returns whether the simple @p derivedType can be derived from the simple @p baseType * under the given @p constraints. */ - static bool isSimpleDerivationOk(const SchemaType::Ptr &derivedType, const SchemaType::Ptr baseType, const SchemaType::DerivationConstraints &constraints); + static bool isSimpleDerivationOk(const SchemaType::Ptr &derivedType, + const SchemaType::Ptr &baseType, + const SchemaType::DerivationConstraints &constraints); /** * Returns whether the complex @p derivedType can be derived from the complex @p baseType * under the given @p constraints. */ - static bool isComplexDerivationOk(const SchemaType::Ptr &derivedType, const SchemaType::Ptr baseType, const SchemaType::DerivationConstraints &constraints); + static bool isComplexDerivationOk(const SchemaType::Ptr &derivedType, + const SchemaType::Ptr &baseType, + const SchemaType::DerivationConstraints &constraints); /** * This method takes the two string based operands @p operand1 and @p operand2 and converts them to instances of type @p type. @@ -111,41 +121,62 @@ namespace QPatternist * Returns whether the process content property of the @p derivedWildcard is valid * according to the process content property of its @p baseWildcard. */ - static bool checkWildcardProcessContents(const XsdWildcard::Ptr &baseWildcard, const XsdWildcard::Ptr &derivedWildcard); + static bool checkWildcardProcessContents(const XsdWildcard::Ptr &baseWildcard, + const XsdWildcard::Ptr &derivedWildcard); /** * Checks whether @[ member is a member of the substitution group with the given @p head. */ - static bool foundSubstitutionGroupTransitive(const XsdElement::Ptr &head, const XsdElement::Ptr &member, QSet &visitedElements); + static bool foundSubstitutionGroupTransitive(const XsdElement::Ptr &head, + const XsdElement::Ptr &member, + QSet &visitedElements); /** * A helper method that iterates over the type hierarchy from @p memberType up to @p headType and collects all * @p derivationSet and @p blockSet constraints that exists on the way there. */ - static void foundSubstitutionGroupTypeInheritance(const SchemaType::Ptr &headType, const SchemaType::Ptr &memberType, - QSet &derivationSet, NamedSchemaComponent::BlockingConstraints &blockSet); + static void foundSubstitutionGroupTypeInheritance(const SchemaType::Ptr &headType, + const SchemaType::Ptr &memberType, + QSet &derivationSet, + NamedSchemaComponent::BlockingConstraints &blockSet); /** * Checks if the @p member is transitive to @p head. */ - static bool substitutionGroupOkTransitive(const XsdElement::Ptr &head, const XsdElement::Ptr &member, const NamePool::Ptr &namePool); + static bool substitutionGroupOkTransitive(const XsdElement::Ptr &head, + const XsdElement::Ptr &member, + const NamePool::Ptr &namePool); /** * Checks if @p derivedAttributeGroup is a valid restriction for @p attributeGroup. */ - static bool isValidAttributeGroupRestriction(const XsdAttributeGroup::Ptr &derivedAttributeGroup, const XsdAttributeGroup::Ptr &attributeGroup, const XsdSchemaContext::Ptr &context, QString &errorMsg); + static bool isValidAttributeGroupRestriction(const XsdAttributeGroup::Ptr &derivedAttributeGroup, + const XsdAttributeGroup::Ptr &attributeGroup, + const XsdSchemaContext::Ptr &context, + QString &errorMsg); /** * Checks if @p derivedAttributeUses are a valid restriction for @p attributeUses. */ - static bool isValidAttributeUsesRestriction(const XsdAttributeUse::List &derivedAttributeUses, const XsdAttributeUse::List &attributeUses, - const XsdWildcard::Ptr &derivedWildcard, const XsdWildcard::Ptr &wildcard, const XsdSchemaContext::Ptr &context, QString &errorMsg); + static bool isValidAttributeUsesRestriction(const XsdAttributeUse::List &derivedAttributeUses, + const XsdAttributeUse::List &attributeUses, + const XsdWildcard::Ptr &derivedWildcard, + const XsdWildcard::Ptr &wildcard, + const XsdSchemaContext::Ptr &context, + QString &errorMsg); /** * Checks if @p derivedAttributeUses are a valid extension for @p attributeUses. */ - static bool isValidAttributeUsesExtension(const XsdAttributeUse::List &derivedAttributeUses, const XsdAttributeUse::List &attributeUses, - const XsdWildcard::Ptr &derivedWildcard, const XsdWildcard::Ptr &wildcard, const XsdSchemaContext::Ptr &context, QString &errorMsg); + static bool isValidAttributeUsesExtension(const XsdAttributeUse::List &derivedAttributeUses, + const XsdAttributeUse::List &attributeUses, + const XsdWildcard::Ptr &derivedWildcard, + const XsdWildcard::Ptr &wildcard, + const XsdSchemaContext::Ptr &context, + QString &errorMsg); + + private: + Q_DISABLE_COPY(XsdSchemaHelper) }; } diff --git a/src/xmlpatterns/schema/qxsdschemaparser.cpp b/src/xmlpatterns/schema/qxsdschemaparser.cpp index 9f1e75d..cabc12e 100644 --- a/src/xmlpatterns/schema/qxsdschemaparser.cpp +++ b/src/xmlpatterns/schema/qxsdschemaparser.cpp @@ -5,6 +5,7 @@ #include "qacceltreeresourceloader_p.h" #include "qautoptr_p.h" #include "qboolean_p.h" +#include "qcommonnamespaces_p.h" #include "qderivedinteger_p.h" #include "qderivedstring_p.h" #include "qqnamevalue_p.h" @@ -119,12 +120,28 @@ class TagValidationHandler void validate(XsdSchemaToken::NodeName token) { if (token == XsdSchemaToken::NoKeyword) { - m_parser->error(QtXmlPatterns::tr("can not process unknown element %1").arg(formatElement(m_parser->name().toString()))); + const QList tokens = m_machine.possibleTransitions(); + + QStringList elementNames; + for (int i = 0; i < tokens.count(); ++i) + elementNames.append(formatElement(XsdSchemaToken::toString(tokens.at(i)))); + + m_parser->error(QtXmlPatterns::tr("can not process unknown element %1, expected elements are: %2") + .arg(formatElement(m_parser->name().toString())) + .arg(elementNames.join(QLatin1String(", ")))); return; } if (!m_machine.proceed(token)) { - m_parser->error(QtXmlPatterns::tr("element %1 is not allowed in this scope").arg(formatElement(XsdSchemaToken::toString(token)))); + const QList tokens = m_machine.possibleTransitions(); + + QStringList elementNames; + for (int i = 0; i < tokens.count(); ++i) + elementNames.append(formatElement(XsdSchemaToken::toString(tokens.at(i)))); + + m_parser->error(QtXmlPatterns::tr("element %1 is not allowed in this scope, possible elements are: %2") + .arg(formatElement(XsdSchemaToken::toString(token))) + .arg(elementNames.join(QLatin1String(", ")))); return; } } @@ -132,7 +149,14 @@ class TagValidationHandler void finalize() const { if (!m_machine.inEndState()) { - m_parser->error(QtXmlPatterns::tr("child element is missing in that scope")); + const QList tokens = m_machine.possibleTransitions(); + + QStringList elementNames; + for (int i = 0; i < tokens.count(); ++i) + elementNames.append(formatElement(XsdSchemaToken::toString(tokens.at(i)))); + + m_parser->error(QtXmlPatterns::tr("child element is missing in that scope, possible child elements are: %1") + .arg(elementNames.join(QLatin1String(", ")))); } } @@ -425,8 +449,8 @@ void XsdSchemaParser::parseSchema(ParserType parserType) const QString version = readAttribute(QString::fromLatin1("version")); } - if (hasAttribute(QString::fromLatin1("http://www.w3.org/XML/1998/namespace"), QString::fromLatin1("lang"))) { - const QString value = readAttribute(QString::fromLatin1("lang"), QString::fromLatin1("http://www.w3.org/XML/1998/namespace")); + if (hasAttribute(CommonNamespaces::XML, QString::fromLatin1("lang"))) { + const QString value = readAttribute(QString::fromLatin1("lang"), CommonNamespaces::XML); const QRegExp exp(QString::fromLatin1("[a-zA-Z]{1,8}(-[a-zA-Z0-9]{1,8})*")); if (!exp.exactMatch(value)) { @@ -750,7 +774,7 @@ void XsdSchemaParser::parseRedefine() if (url.isRelative()) { Q_ASSERT(m_documentURI.isValid()); - url = m_documentURI.resolved(url); + url = m_documentURI.resolved(url); } // we parse the schema given in the redefine tag into its own context @@ -1176,8 +1200,8 @@ XsdDocumentation::Ptr XsdSchemaParser::parseDocumentation() } } - if (hasAttribute(QString::fromLatin1("http://www.w3.org/XML/1998/namespace"), QString::fromLatin1("lang"))) { - const QString value = readAttribute(QString::fromLatin1("lang"), QString::fromLatin1("http://www.w3.org/XML/1998/namespace")); + if (hasAttribute(CommonNamespaces::XML, QString::fromLatin1("lang"))) { + const QString value = readAttribute(QString::fromLatin1("lang"), CommonNamespaces::XML); const QRegExp exp(QString::fromLatin1("[a-zA-Z]{1,8}(-[a-zA-Z0-9]{1,8})*")); if (!exp.exactMatch(value)) { @@ -3948,7 +3972,7 @@ XsdAttribute::Ptr XsdSchemaParser::parseGlobalAttribute() error(QtXmlPatterns::tr("content of %1 attribute of %2 element must not be from namespace %3") .arg(formatAttribute("name")) .arg(formatElement("attribute")) - .arg(formatURI(QLatin1String("http://www.w3.org/2001/XMLSchema-instance")))); + .arg(formatURI(CommonNamespaces::XSI))); return attribute; } if (m_namePool->stringForLocalName(objectName.localName()) == QString::fromLatin1("xmlns")) { @@ -4170,7 +4194,7 @@ XsdAttributeUse::Ptr XsdSchemaParser::parseLocalAttribute(const NamedSchemaCompo error(QtXmlPatterns::tr("content of %1 attribute of %2 element must not be from namespace %3") .arg(formatAttribute("name")) .arg(formatElement("attribute")) - .arg(formatURI(QLatin1String("http://www.w3.org/2001/XMLSchema-instance")))); + .arg(formatURI(CommonNamespaces::XSI))); return attributeUse; } if (m_namePool->stringForLocalName(objectName.localName()) == QString::fromLatin1("xmlns")) { @@ -5858,7 +5882,7 @@ QString XsdSchemaParser::readXPathAttribute(const QString &attributeName, XPathT QXmlNamePool namePool(m_namePool.data()); - QXmlQuery::QueryLanguage language; + QXmlQuery::QueryLanguage language = QXmlQuery::XPath20; switch (type) { case XPath20: language = QXmlQuery::XPath20; break; case XPathSelector: language = QXmlQuery::XmlSchema11IdentityConstraintSelector; break; diff --git a/src/xmlpatterns/schema/qxsdstatemachine.cpp b/src/xmlpatterns/schema/qxsdstatemachine.cpp index e40e55b..4f36f22 100644 --- a/src/xmlpatterns/schema/qxsdstatemachine.cpp +++ b/src/xmlpatterns/schema/qxsdstatemachine.cpp @@ -114,6 +114,20 @@ bool XsdStateMachine::proceed(TransitionType transition) } template +QList XsdStateMachine::possibleTransitions() const +{ + // check that we are not in an invalid state + if (!m_transitions.contains(m_currentState)) { + return QList(); + } + + // fetch the transition entry for the current state + const QHash > &entry = m_transitions[m_currentState]; + + return entry.keys(); +} + +template template bool XsdStateMachine::proceed(InputType input) { @@ -259,7 +273,7 @@ typename XsdStateMachine::StateId XsdStateMachine it(nfaState); diff --git a/src/xmlpatterns/schema/qxsdstatemachine_p.h b/src/xmlpatterns/schema/qxsdstatemachine_p.h index 7988335..f0cf99d 100644 --- a/src/xmlpatterns/schema/qxsdstatemachine_p.h +++ b/src/xmlpatterns/schema/qxsdstatemachine_p.h @@ -113,6 +113,12 @@ namespace QPatternist bool proceed(TransitionType transition); /** + * Returns the list of transitions that are reachable from the current + * state. + */ + QList possibleTransitions() const; + + /** * Continues execution of the machine with the given @p input. * * @note To use this method, inputEqualsTransition must be implemented diff --git a/src/xmlpatterns/schema/qxsdvalidatedxmlnodemodel.cpp b/src/xmlpatterns/schema/qxsdvalidatedxmlnodemodel.cpp index 8e1645a..33bca4e 100644 --- a/src/xmlpatterns/schema/qxsdvalidatedxmlnodemodel.cpp +++ b/src/xmlpatterns/schema/qxsdvalidatedxmlnodemodel.cpp @@ -20,7 +20,7 @@ QT_BEGIN_NAMESPACE using namespace QPatternist; XsdValidatedXmlNodeModel::XsdValidatedXmlNodeModel(const QAbstractXmlNodeModel *model) - : m_internalModel(const_cast(model)) + : m_internalModel(model) { } diff --git a/src/xmlpatterns/schema/qxsdvalidatedxmlnodemodel_p.h b/src/xmlpatterns/schema/qxsdvalidatedxmlnodemodel_p.h index 579f41a..d52e369 100644 --- a/src/xmlpatterns/schema/qxsdvalidatedxmlnodemodel_p.h +++ b/src/xmlpatterns/schema/qxsdvalidatedxmlnodemodel_p.h @@ -134,11 +134,11 @@ namespace QPatternist virtual QVector attributes(const QXmlNodeModelIndex &element) const; private: - QAbstractXmlNodeModel::Ptr m_internalModel; - QHash m_assignedElements; - QHash m_assignedAttributes; - QHash m_assignedTypes; - QHash > m_idIdRefBindings; + QExplicitlySharedDataPointer m_internalModel; + QHash m_assignedElements; + QHash m_assignedAttributes; + QHash m_assignedTypes; + QHash > m_idIdRefBindings; }; } diff --git a/src/xmlpatterns/schema/qxsdvalidatinginstancereader.cpp b/src/xmlpatterns/schema/qxsdvalidatinginstancereader.cpp index 12fc477..8cb34d4 100644 --- a/src/xmlpatterns/schema/qxsdvalidatinginstancereader.cpp +++ b/src/xmlpatterns/schema/qxsdvalidatinginstancereader.cpp @@ -15,6 +15,7 @@ #include "qacceltreeresourceloader_p.h" #include "qbase64binary_p.h" #include "qboolean_p.h" +#include "qcommonnamespaces_p.h" #include "qderivedinteger_p.h" #include "qduration_p.h" #include "qgenericstaticcontext_p.h" @@ -64,14 +65,14 @@ namespace QPatternist } } -XsdValidatingInstanceReader::XsdValidatingInstanceReader(const XsdValidatedXmlNodeModel *model, const QUrl &documentUri, const XsdSchemaContext::Ptr &context) +XsdValidatingInstanceReader::XsdValidatingInstanceReader(XsdValidatedXmlNodeModel *model, const QUrl &documentUri, const XsdSchemaContext::Ptr &context) : XsdInstanceReader(model, context) - , m_model(const_cast(model)) + , m_model(model) , m_namePool(m_context->namePool()) - , m_xsiNilName(m_namePool->allocateQName(QLatin1String("http://www.w3.org/2001/XMLSchema-instance"), QLatin1String("nil"))) - , m_xsiTypeName(m_namePool->allocateQName(QLatin1String("http://www.w3.org/2001/XMLSchema-instance"), QLatin1String("type"))) - , m_xsiSchemaLocationName(m_namePool->allocateQName(QLatin1String("http://www.w3.org/2001/XMLSchema-instance"), QLatin1String("schemaLocation"))) - , m_xsiNoNamespaceSchemaLocationName(m_namePool->allocateQName(QLatin1String("http://www.w3.org/2001/XMLSchema-instance"), QLatin1String("noNamespaceSchemaLocation"))) + , m_xsiNilName(m_namePool->allocateQName(CommonNamespaces::XSI, QLatin1String("nil"))) + , m_xsiTypeName(m_namePool->allocateQName(CommonNamespaces::XSI, QLatin1String("type"))) + , m_xsiSchemaLocationName(m_namePool->allocateQName(CommonNamespaces::XSI, QLatin1String("schemaLocation"))) + , m_xsiNoNamespaceSchemaLocationName(m_namePool->allocateQName(CommonNamespaces::XSI, QLatin1String("noNamespaceSchemaLocation"))) , m_documentUri(documentUri) { m_idRefsType = m_context->schemaTypeFactory()->createSchemaType(m_namePool->allocateQName(CommonNamespaces::WXS, QLatin1String("IDREFS"))); @@ -152,7 +153,7 @@ bool XsdValidatingInstanceReader::read() void XsdValidatingInstanceReader::error(const QString &msg) const { - const_cast(m_context.data())->error(msg, XsdSchemaContext::XSDError, sourceLocation()); + m_context.data()->error(msg, XsdSchemaContext::XSDError, sourceLocation()); } bool XsdValidatingInstanceReader::loadSchema(const QString &targetNamespace, const QUrl &location) diff --git a/src/xmlpatterns/schema/qxsdvalidatinginstancereader_p.h b/src/xmlpatterns/schema/qxsdvalidatinginstancereader_p.h index 799ab44..28f3c3f 100644 --- a/src/xmlpatterns/schema/qxsdvalidatinginstancereader_p.h +++ b/src/xmlpatterns/schema/qxsdvalidatinginstancereader_p.h @@ -59,7 +59,7 @@ namespace QPatternist * @param documentUri The uri of the document the model is from. * @param context The context that is used to report errors etc. */ - XsdValidatingInstanceReader(const XsdValidatedXmlNodeModel *model, const QUrl &documentUri, const XsdSchemaContext::Ptr &context); + XsdValidatingInstanceReader(XsdValidatedXmlNodeModel *model, const QUrl &documentUri, const XsdSchemaContext::Ptr &context); /** * Adds a new @p schema to the pool of schemas that shall be used diff --git a/src/xmlpatterns/utils/qxpathhelper.cpp b/src/xmlpatterns/utils/qxpathhelper.cpp index 127e21f..5b32906 100644 --- a/src/xmlpatterns/utils/qxpathhelper.cpp +++ b/src/xmlpatterns/utils/qxpathhelper.cpp @@ -125,4 +125,16 @@ ItemType::Ptr XPathHelper::typeFromKind(const QXmlNodeModelIndex::NodeKind nodeK } } +QUrl XPathHelper::normalizeQueryURI(const QUrl &uri) +{ + Q_ASSERT_X(uri.isEmpty() || uri.isValid(), Q_FUNC_INFO, + "The URI passed to QXmlQuery::setQuery() must be valid or empty."); + if(uri.isEmpty()) + return QUrl::fromLocalFile(QCoreApplication::applicationFilePath()); + else if(uri.isRelative()) + return QUrl::fromLocalFile(QCoreApplication::applicationFilePath()).resolved(uri); + else + return uri; +} + QT_END_NAMESPACE diff --git a/src/xmlpatterns/utils/qxpathhelper_p.h b/src/xmlpatterns/utils/qxpathhelper_p.h index 7bf33e6..e36b8cb 100644 --- a/src/xmlpatterns/utils/qxpathhelper_p.h +++ b/src/xmlpatterns/utils/qxpathhelper_p.h @@ -128,6 +128,11 @@ namespace QPatternist static QPatternist::ItemTypePtr typeFromKind(const QXmlNodeModelIndex::NodeKind nodeKind); /** + * Normalizes an @p uri by resolving it to the application directory if empty. + */ + static QUrl normalizeQueryURI(const QUrl &uri); + + /** * @short Determines whether @p consists only of whitespace. Characters * considered whitespace are the ones for which QChar::isSpace() returns @c true for. * diff --git a/tests/auto/patternistheaders/tst_patternistheaders.cpp b/tests/auto/patternistheaders/tst_patternistheaders.cpp index ba7623e..3352a58 100644 --- a/tests/auto/patternistheaders/tst_patternistheaders.cpp +++ b/tests/auto/patternistheaders/tst_patternistheaders.cpp @@ -94,6 +94,10 @@ void tst_PatternistHeaders::run() const #include #include #include +#include +#include +#include +#include #include #include @@ -122,6 +126,10 @@ void tst_PatternistHeaders::run() const #include #include #include +#include +#include +#include +#include #include #include diff --git a/tests/auto/qxmlschema/tst_qxmlschema.cpp b/tests/auto/qxmlschema/tst_qxmlschema.cpp index 64012c1..7fc59bb 100644 --- a/tests/auto/qxmlschema/tst_qxmlschema.cpp +++ b/tests/auto/qxmlschema/tst_qxmlschema.cpp @@ -15,33 +15,8 @@ #include #include -class DummyMessageHandler : public QAbstractMessageHandler -{ - public: - DummyMessageHandler(QObject *parent = 0) - : QAbstractMessageHandler(parent) - { - } - - protected: - virtual void handleMessage(QtMsgType, const QString&, const QUrl&, const QSourceLocation&) - { - } -}; - -class DummyUriResolver : public QAbstractUriResolver -{ - public: - DummyUriResolver(QObject *parent = 0) - : QAbstractUriResolver(parent) - { - } - - virtual QUrl resolve(const QUrl&, const QUrl&) const - { - return QUrl(); - } -}; +#include "../qabstracturiresolver/TestURIResolver.h" +#include "../qxmlquery/MessageSilencer.h" /*! \class tst_QXmlSchema @@ -59,6 +34,17 @@ private Q_SLOTS: void defaultConstructor() const; void copyConstructor() const; void constructorQXmlNamePool() const; + void copyMutationTest() const; + + void isValid() const; + void documentUri() const; + + void loadSchemaUrlSuccess() const; + void loadSchemaUrlFail() const; + void loadSchemaDeviceSuccess() const; + void loadSchemaDeviceFail() const; + void loadSchemaDataSuccess() const; + void loadSchemaDataFail() const; void networkAccessManagerSignature() const; void networkAccessManagerDefaultValue() const; @@ -134,6 +120,150 @@ void tst_QXmlSchema::constructorQXmlNamePool() const QCOMPARE(name.prefix(np2), QString::fromLatin1("prefix")); } +void tst_QXmlSchema::copyMutationTest() const +{ + QXmlSchema schema1; + QXmlSchema schema2(schema1); + + // check that everything is equal + QVERIFY(schema2.messageHandler() == schema1.messageHandler()); + QVERIFY(schema2.uriResolver() == schema1.uriResolver()); + QVERIFY(schema2.networkAccessManager() == schema1.networkAccessManager()); + + MessageSilencer handler; + const TestURIResolver resolver; + QNetworkAccessManager manager; + + // modify schema1 + schema1.setMessageHandler(&handler); + schema1.setUriResolver(&resolver); + schema1.setNetworkAccessManager(&manager); + + // check that schema2 is not effected by the modifications of schema1 + QVERIFY(schema2.messageHandler() != schema1.messageHandler()); + QVERIFY(schema2.uriResolver() != schema1.uriResolver()); + QVERIFY(schema2.networkAccessManager() != schema1.networkAccessManager()); + + // modify schema1 further + const QByteArray data( "" + "" + "" ); + + const QUrl documentUri("http://www.qtsoftware.com/xmlschematest"); + schema1.load(data, documentUri); + + QVERIFY(schema2.isValid() != schema1.isValid()); +} + +void tst_QXmlSchema::isValid() const +{ + /* Check default value. */ + QXmlSchema schema; + QVERIFY(!schema.isValid()); +} + +void tst_QXmlSchema::documentUri() const +{ + const QByteArray data( "" + "" + "" ); + + const QUrl documentUri("http://www.qtsoftware.com/xmlschematest"); + QXmlSchema schema; + schema.load(data, documentUri); + + QCOMPARE(documentUri, schema.documentUri()); +} + +void tst_QXmlSchema::loadSchemaUrlSuccess() const +{ +/** + TODO: put valid schema file on given url and enable test + const QUrl url("http://notavailable/"); + + QXmlSchema schema; + QVERIFY(!schema.load(url)); +*/ +} + +void tst_QXmlSchema::loadSchemaUrlFail() const +{ + const QUrl url("http://notavailable/"); + + QXmlSchema schema; + QVERIFY(!schema.load(url)); +} + +void tst_QXmlSchema::loadSchemaDeviceSuccess() const +{ + QByteArray data( "" + "" + "" ); + + QBuffer buffer(&data); + buffer.open(QIODevice::ReadOnly); + + QXmlSchema schema; + QVERIFY(schema.load(&buffer)); +} + +void tst_QXmlSchema::loadSchemaDeviceFail() const +{ + QByteArray data( "" + "" + "" ); + + QBuffer buffer(&data); + // a closed device can not be loaded + + QXmlSchema schema; + QVERIFY(!schema.load(&buffer)); +} + +void tst_QXmlSchema::loadSchemaDataSuccess() const +{ + const QByteArray data( "" + "" + "" ); + QXmlSchema schema; + QVERIFY(schema.load(data)); +} + +void tst_QXmlSchema::loadSchemaDataFail() const +{ + // empty schema can not be loaded + const QByteArray data; + + QXmlSchema schema; + QVERIFY(!schema.load(data)); +} + + void tst_QXmlSchema::networkAccessManagerSignature() const { /* Const object. */ @@ -185,7 +315,7 @@ void tst_QXmlSchema::messageHandler() const { /* Test that we return the message handler that was set. */ { - DummyMessageHandler handler; + MessageSilencer handler; QXmlSchema schema; schema.setMessageHandler(&handler); @@ -200,6 +330,13 @@ void tst_QXmlSchema::uriResolverSignature() const /* The function should be const. */ schema.uriResolver(); + + /* Const object. */ + const TestURIResolver resolver; + + /* This should compile */ + QXmlSchema schema2; + schema2.setUriResolver(&resolver); } void tst_QXmlSchema::uriResolverDefaultValue() const @@ -215,7 +352,7 @@ void tst_QXmlSchema::uriResolver() const { /* Test that we return the uri resolver that was set. */ { - DummyUriResolver resolver; + TestURIResolver resolver; QXmlSchema schema; schema.setUriResolver(&resolver); diff --git a/tests/auto/qxmlschemavalidator/tst_qxmlschemavalidator.cpp b/tests/auto/qxmlschemavalidator/tst_qxmlschemavalidator.cpp index b021b08..3bbf506 100644 --- a/tests/auto/qxmlschemavalidator/tst_qxmlschemavalidator.cpp +++ b/tests/auto/qxmlschemavalidator/tst_qxmlschemavalidator.cpp @@ -16,33 +16,8 @@ #include #include -class DummyMessageHandler : public QAbstractMessageHandler -{ - public: - DummyMessageHandler(QObject *parent = 0) - : QAbstractMessageHandler(parent) - { - } - - protected: - virtual void handleMessage(QtMsgType, const QString&, const QUrl&, const QSourceLocation&) - { - } -}; - -class DummyUriResolver : public QAbstractUriResolver -{ - public: - DummyUriResolver(QObject *parent = 0) - : QAbstractUriResolver(parent) - { - } - - virtual QUrl resolve(const QUrl&, const QUrl&) const - { - return QUrl(); - } -}; +#include "../qabstracturiresolver/TestURIResolver.h" +#include "../qxmlquery/MessageSilencer.h" /*! \class tst_QXmlSchemaValidatorValidator @@ -60,6 +35,13 @@ private Q_SLOTS: void defaultConstructor() const; void propertyInitialization() const; + void loadInstanceUrlSuccess() const; + void loadInstanceUrlFail() const; + void loadInstanceDeviceSuccess() const; + void loadInstanceDeviceFail() const; + void loadInstanceDataSuccess() const; + void loadInstanceDataFail() const; + void networkAccessManagerSignature() const; void networkAccessManagerDefaultValue() const; void networkAccessManager() const; @@ -73,6 +55,26 @@ private Q_SLOTS: void uriResolver() const; }; +static QXmlSchema createValidSchema() +{ + const QByteArray data( "" + "" + " " + "" ); + + const QUrl documentUri("http://www.qtsoftware.com/xmlschematest"); + + QXmlSchema schema; + schema.load(data, documentUri); + + return schema; +} + void tst_QXmlSchemaValidator::defaultConstructor() const { /* Allocate instance in different orders. */ @@ -101,8 +103,8 @@ void tst_QXmlSchemaValidator::propertyInitialization() const { /* Verify that properties set in the schema are used as default values for the validator */ { - DummyMessageHandler handler; - DummyUriResolver resolver; + MessageSilencer handler; + TestURIResolver resolver; QNetworkAccessManager manager; QXmlSchema schema; @@ -117,6 +119,72 @@ void tst_QXmlSchemaValidator::propertyInitialization() const } } +void tst_QXmlSchemaValidator::loadInstanceUrlSuccess() const +{ +/* + TODO: put valid schema file on given url and enable test + const QXmlSchema schema(createValidSchema()); + const QUrl url("http://notavailable/"); + + QXmlSchemaValidator validator(schema); + QVERIFY(!validator.validate(url)); +*/ +} + +void tst_QXmlSchemaValidator::loadInstanceUrlFail() const +{ + const QXmlSchema schema(createValidSchema()); + const QUrl url("http://notavailable/"); + + QXmlSchemaValidator validator(schema); + QVERIFY(!validator.validate(url)); +} + +void tst_QXmlSchemaValidator::loadInstanceDeviceSuccess() const +{ + const QXmlSchema schema(createValidSchema()); + + QByteArray data( "Testme" ); + QBuffer buffer(&data); + buffer.open(QIODevice::ReadOnly); + + QXmlSchemaValidator validator(schema); + QVERIFY(validator.validate(&buffer)); +} + +void tst_QXmlSchemaValidator::loadInstanceDeviceFail() const +{ + const QXmlSchema schema(createValidSchema()); + + QByteArray data( "Testme" ); + QBuffer buffer(&data); + // a closed device can not be loaded + + QXmlSchemaValidator validator(schema); + QVERIFY(!validator.validate(&buffer)); +} + +void tst_QXmlSchemaValidator::loadInstanceDataSuccess() const +{ + const QXmlSchema schema(createValidSchema()); + + const QByteArray data( "Testme" ); + + QXmlSchemaValidator validator(schema); + QVERIFY(validator.validate(data)); +} + +void tst_QXmlSchemaValidator::loadInstanceDataFail() const +{ + const QXmlSchema schema(createValidSchema()); + + // empty instance can not be loaded + const QByteArray data; + + QXmlSchemaValidator validator(schema); + QVERIFY(!validator.validate(data)); +} + void tst_QXmlSchemaValidator::networkAccessManagerSignature() const { const QXmlSchema schema; @@ -202,7 +270,7 @@ void tst_QXmlSchemaValidator::messageHandlerDefaultValue() const { QXmlSchema schema; - DummyMessageHandler handler; + MessageSilencer handler; schema.setMessageHandler(&handler); const QXmlSchemaValidator validator(schema); @@ -214,7 +282,7 @@ void tst_QXmlSchemaValidator::messageHandler() const { /* Test that we return the message handler that was set. */ { - DummyMessageHandler handler; + MessageSilencer handler; const QXmlSchema schema; QXmlSchemaValidator validator(schema); @@ -225,7 +293,7 @@ void tst_QXmlSchemaValidator::messageHandler() const /* Test that we return the message handler that was set, even if the schema changed in between. */ { - DummyMessageHandler handler; + MessageSilencer handler; const QXmlSchema schema; QXmlSchemaValidator validator(schema); @@ -248,6 +316,13 @@ void tst_QXmlSchemaValidator::uriResolverSignature() const /* The function should be const. */ validator.uriResolver(); + + /* Const object. */ + const TestURIResolver resolver; + + /* This should compile */ + QXmlSchema schema2; + schema2.setUriResolver(&resolver); } void tst_QXmlSchemaValidator::uriResolverDefaultValue() const @@ -263,7 +338,7 @@ void tst_QXmlSchemaValidator::uriResolverDefaultValue() const { QXmlSchema schema; - DummyUriResolver resolver; + TestURIResolver resolver; schema.setUriResolver(&resolver); const QXmlSchemaValidator validator(schema); @@ -275,7 +350,7 @@ void tst_QXmlSchemaValidator::uriResolver() const { /* Test that we return the uri resolver that was set. */ { - DummyUriResolver resolver; + TestURIResolver resolver; const QXmlSchema schema; QXmlSchemaValidator validator(schema); @@ -286,7 +361,7 @@ void tst_QXmlSchemaValidator::uriResolver() const /* Test that we return the uri resolver that was set, even if the schema changed in between. */ { - DummyUriResolver resolver; + TestURIResolver resolver; const QXmlSchema schema; QXmlSchemaValidator validator(schema); diff --git a/tools/xmlpatternsvalidator/main.cpp b/tools/xmlpatternsvalidator/main.cpp index 032afc0..0ccbcfc 100644 --- a/tools/xmlpatternsvalidator/main.cpp +++ b/tools/xmlpatternsvalidator/main.cpp @@ -19,22 +19,29 @@ QT_USE_NAMESPACE -enum ExecutionMode -{ - InvalidMode, - SchemaOnlyMode, - SchemaAndInstanceMode, - InstanceOnlyMode -}; - int main(int argc, char **argv) { + enum ExitCode + { + Valid = 0, + Invalid, + ParseError + }; + + enum ExecutionMode + { + InvalidMode, + SchemaOnlyMode, + SchemaAndInstanceMode, + InstanceOnlyMode + }; + const QCoreApplication app(argc, argv); QCoreApplication::setApplicationName(QLatin1String("xmlpatternsvalidator")); if (argc != 2 && argc != 3) { qDebug() << QXmlPatternistCLI::tr("usage: xmlpatternsvalidator ( | | )"); - return 2; + return ParseError; } // parse command line arguments @@ -63,9 +70,9 @@ int main(int argc, char **argv) schema.load(QUrl(schemaUri)); if (schema.isValid()) - return 0; + return Valid; else - return 1; + return Invalid; } else if (mode == SchemaAndInstanceMode) { const QString instanceUri = QFile::decodeName(argv[1]); const QString schemaUri = QFile::decodeName(argv[2]); @@ -73,24 +80,24 @@ int main(int argc, char **argv) schema.load(QUrl(schemaUri)); if (!schema.isValid()) - return 1; + return Invalid; QXmlSchemaValidator validator(schema); if (validator.validate(QUrl(instanceUri))) - return 0; + return Valid; else - return 1; + return Invalid; } else if (mode == InstanceOnlyMode) { const QString instanceUri = QFile::decodeName(argv[1]); QXmlSchemaValidator validator(schema); if (validator.validate(QUrl(instanceUri))) - return 0; + return Valid; else - return 1; + return Invalid; } Q_ASSERT(false); - return 1; + return Invalid; } -- cgit v0.12 From 017fd8ebb129947603eeea5474a067d45a33eccb Mon Sep 17 00:00:00 2001 From: Tobias Koenig Date: Sat, 16 May 2009 20:45:26 +0200 Subject: Adapt license headers to LGPL --- examples/xmlpatterns/schema/main.cpp | 34 ++++++++++++++++++++-- examples/xmlpatterns/schema/mainwindow.cpp | 34 ++++++++++++++++++++-- examples/xmlpatterns/schema/mainwindow.h | 34 ++++++++++++++++++++-- src/xmlpatterns/api/qabstractxmlpullprovider.cpp | 34 ++++++++++++++++++++-- src/xmlpatterns/api/qabstractxmlpullprovider_p.h | 34 ++++++++++++++++++++-- src/xmlpatterns/api/qpullbridge.cpp | 34 ++++++++++++++++++++-- src/xmlpatterns/api/qpullbridge_p.h | 34 ++++++++++++++++++++-- src/xmlpatterns/api/qxmlschema.cpp | 34 ++++++++++++++++++++-- src/xmlpatterns/api/qxmlschema.h | 34 ++++++++++++++++++++-- src/xmlpatterns/api/qxmlschema_p.cpp | 34 ++++++++++++++++++++-- src/xmlpatterns/api/qxmlschema_p.h | 34 ++++++++++++++++++++-- src/xmlpatterns/api/qxmlschemavalidator.cpp | 34 ++++++++++++++++++++-- src/xmlpatterns/api/qxmlschemavalidator.h | 34 ++++++++++++++++++++-- src/xmlpatterns/api/qxmlschemavalidator_p.h | 34 ++++++++++++++++++++-- src/xmlpatterns/data/qcomparisonfactory.cpp | 34 ++++++++++++++++++++-- src/xmlpatterns/data/qcomparisonfactory_p.h | 34 ++++++++++++++++++++-- src/xmlpatterns/data/qvaluefactory.cpp | 34 ++++++++++++++++++++-- src/xmlpatterns/data/qvaluefactory_p.h | 34 ++++++++++++++++++++-- src/xmlpatterns/parser/qquerytransformparser_p.h | 34 ++++++++++++++++++++-- src/xmlpatterns/schema/qnamespacesupport.cpp | 34 ++++++++++++++++++++-- src/xmlpatterns/schema/qnamespacesupport_p.h | 34 ++++++++++++++++++++-- src/xmlpatterns/schema/qxsdalternative.cpp | 34 ++++++++++++++++++++-- src/xmlpatterns/schema/qxsdalternative_p.h | 34 ++++++++++++++++++++-- src/xmlpatterns/schema/qxsdannotated.cpp | 34 ++++++++++++++++++++-- src/xmlpatterns/schema/qxsdannotated_p.h | 34 ++++++++++++++++++++-- src/xmlpatterns/schema/qxsdannotation.cpp | 34 ++++++++++++++++++++-- src/xmlpatterns/schema/qxsdannotation_p.h | 34 ++++++++++++++++++++-- .../schema/qxsdapplicationinformation.cpp | 34 ++++++++++++++++++++-- .../schema/qxsdapplicationinformation_p.h | 34 ++++++++++++++++++++-- src/xmlpatterns/schema/qxsdassertion.cpp | 34 ++++++++++++++++++++-- src/xmlpatterns/schema/qxsdassertion_p.h | 34 ++++++++++++++++++++-- src/xmlpatterns/schema/qxsdattribute.cpp | 34 ++++++++++++++++++++-- src/xmlpatterns/schema/qxsdattribute_p.h | 34 ++++++++++++++++++++-- src/xmlpatterns/schema/qxsdattributegroup.cpp | 34 ++++++++++++++++++++-- src/xmlpatterns/schema/qxsdattributegroup_p.h | 34 ++++++++++++++++++++-- src/xmlpatterns/schema/qxsdattributereference.cpp | 34 ++++++++++++++++++++-- src/xmlpatterns/schema/qxsdattributereference_p.h | 34 ++++++++++++++++++++-- src/xmlpatterns/schema/qxsdattributeterm.cpp | 34 ++++++++++++++++++++-- src/xmlpatterns/schema/qxsdattributeterm_p.h | 34 ++++++++++++++++++++-- src/xmlpatterns/schema/qxsdattributeuse.cpp | 34 ++++++++++++++++++++-- src/xmlpatterns/schema/qxsdattributeuse_p.h | 34 ++++++++++++++++++++-- src/xmlpatterns/schema/qxsdcomplextype.cpp | 34 ++++++++++++++++++++-- src/xmlpatterns/schema/qxsdcomplextype_p.h | 34 ++++++++++++++++++++-- src/xmlpatterns/schema/qxsddocumentation.cpp | 34 ++++++++++++++++++++-- src/xmlpatterns/schema/qxsddocumentation_p.h | 34 ++++++++++++++++++++-- src/xmlpatterns/schema/qxsdelement.cpp | 34 ++++++++++++++++++++-- src/xmlpatterns/schema/qxsdelement_p.h | 34 ++++++++++++++++++++-- src/xmlpatterns/schema/qxsdfacet.cpp | 34 ++++++++++++++++++++-- src/xmlpatterns/schema/qxsdfacet_p.h | 34 ++++++++++++++++++++-- src/xmlpatterns/schema/qxsdidcache.cpp | 34 ++++++++++++++++++++-- src/xmlpatterns/schema/qxsdidcache_p.h | 34 ++++++++++++++++++++-- src/xmlpatterns/schema/qxsdidchelper.cpp | 34 ++++++++++++++++++++-- src/xmlpatterns/schema/qxsdidchelper_p.h | 34 ++++++++++++++++++++-- src/xmlpatterns/schema/qxsdidentityconstraint.cpp | 34 ++++++++++++++++++++-- src/xmlpatterns/schema/qxsdidentityconstraint_p.h | 34 ++++++++++++++++++++-- src/xmlpatterns/schema/qxsdinstancereader.cpp | 34 ++++++++++++++++++++-- src/xmlpatterns/schema/qxsdinstancereader_p.h | 34 ++++++++++++++++++++-- src/xmlpatterns/schema/qxsdmodelgroup.cpp | 34 ++++++++++++++++++++-- src/xmlpatterns/schema/qxsdmodelgroup_p.h | 34 ++++++++++++++++++++-- src/xmlpatterns/schema/qxsdnotation.cpp | 34 ++++++++++++++++++++-- src/xmlpatterns/schema/qxsdnotation_p.h | 34 ++++++++++++++++++++-- src/xmlpatterns/schema/qxsdparticle.cpp | 34 ++++++++++++++++++++-- src/xmlpatterns/schema/qxsdparticle_p.h | 34 ++++++++++++++++++++-- src/xmlpatterns/schema/qxsdparticlechecker.cpp | 34 ++++++++++++++++++++-- src/xmlpatterns/schema/qxsdparticlechecker_p.h | 34 ++++++++++++++++++++-- src/xmlpatterns/schema/qxsdreference.cpp | 34 ++++++++++++++++++++-- src/xmlpatterns/schema/qxsdreference_p.h | 34 ++++++++++++++++++++-- src/xmlpatterns/schema/qxsdschema.cpp | 34 ++++++++++++++++++++-- src/xmlpatterns/schema/qxsdschema_p.h | 34 ++++++++++++++++++++-- src/xmlpatterns/schema/qxsdschemachecker.cpp | 34 ++++++++++++++++++++-- .../schema/qxsdschemachecker_helper.cpp | 34 ++++++++++++++++++++-- src/xmlpatterns/schema/qxsdschemachecker_p.h | 34 ++++++++++++++++++++-- src/xmlpatterns/schema/qxsdschemacontext.cpp | 34 ++++++++++++++++++++-- src/xmlpatterns/schema/qxsdschemacontext_p.h | 34 ++++++++++++++++++++-- src/xmlpatterns/schema/qxsdschemadebugger.cpp | 34 ++++++++++++++++++++-- src/xmlpatterns/schema/qxsdschemadebugger_p.h | 34 ++++++++++++++++++++-- src/xmlpatterns/schema/qxsdschemahelper.cpp | 34 ++++++++++++++++++++-- src/xmlpatterns/schema/qxsdschemahelper_p.h | 34 ++++++++++++++++++++-- src/xmlpatterns/schema/qxsdschemamerger.cpp | 34 ++++++++++++++++++++-- src/xmlpatterns/schema/qxsdschemamerger_p.h | 34 ++++++++++++++++++++-- src/xmlpatterns/schema/qxsdschemaparser_p.h | 34 ++++++++++++++++++++-- src/xmlpatterns/schema/qxsdschemaparsercontext.cpp | 34 ++++++++++++++++++++-- src/xmlpatterns/schema/qxsdschemaparsercontext_p.h | 34 ++++++++++++++++++++-- src/xmlpatterns/schema/qxsdschemaresolver.cpp | 34 ++++++++++++++++++++-- src/xmlpatterns/schema/qxsdschemaresolver_p.h | 34 ++++++++++++++++++++-- src/xmlpatterns/schema/qxsdschematoken.cpp | 34 ++++++++++++++++++++-- src/xmlpatterns/schema/qxsdschematoken_p.h | 34 ++++++++++++++++++++-- src/xmlpatterns/schema/qxsdschematypesfactory.cpp | 34 ++++++++++++++++++++-- src/xmlpatterns/schema/qxsdschematypesfactory_p.h | 34 ++++++++++++++++++++-- src/xmlpatterns/schema/qxsdsimpletype.cpp | 34 ++++++++++++++++++++-- src/xmlpatterns/schema/qxsdsimpletype_p.h | 34 ++++++++++++++++++++-- src/xmlpatterns/schema/qxsdstatemachine.cpp | 34 ++++++++++++++++++++-- src/xmlpatterns/schema/qxsdstatemachine_p.h | 34 ++++++++++++++++++++-- src/xmlpatterns/schema/qxsdstatemachinebuilder.cpp | 34 ++++++++++++++++++++-- src/xmlpatterns/schema/qxsdstatemachinebuilder_p.h | 34 ++++++++++++++++++++-- src/xmlpatterns/schema/qxsdterm.cpp | 34 ++++++++++++++++++++-- src/xmlpatterns/schema/qxsdterm_p.h | 34 ++++++++++++++++++++-- src/xmlpatterns/schema/qxsdtypechecker.cpp | 34 ++++++++++++++++++++-- src/xmlpatterns/schema/qxsdtypechecker_p.h | 34 ++++++++++++++++++++-- src/xmlpatterns/schema/qxsduserschematype.cpp | 34 ++++++++++++++++++++-- src/xmlpatterns/schema/qxsduserschematype_p.h | 34 ++++++++++++++++++++-- .../schema/qxsdvalidatedxmlnodemodel.cpp | 34 ++++++++++++++++++++-- .../schema/qxsdvalidatedxmlnodemodel_p.h | 34 ++++++++++++++++++++-- .../schema/qxsdvalidatinginstancereader.cpp | 34 ++++++++++++++++++++-- .../schema/qxsdvalidatinginstancereader_p.h | 34 ++++++++++++++++++++-- src/xmlpatterns/schema/qxsdwildcard.cpp | 34 ++++++++++++++++++++-- src/xmlpatterns/schema/qxsdwildcard_p.h | 34 ++++++++++++++++++++-- src/xmlpatterns/schema/qxsdxpathexpression.cpp | 34 ++++++++++++++++++++-- src/xmlpatterns/schema/qxsdxpathexpression_p.h | 34 ++++++++++++++++++++-- src/xmlpatterns/schema/tokens.xml | 34 ++++++++++++++++++++-- src/xmlpatterns/type/qnamedschemacomponent.cpp | 34 ++++++++++++++++++++-- src/xmlpatterns/type/qnamedschemacomponent_p.h | 34 ++++++++++++++++++++-- tools/xmlpatternsvalidator/main.cpp | 32 +++++++++++++++++++- tools/xmlpatternsvalidator/main.h | 32 +++++++++++++++++++- 114 files changed, 3646 insertions(+), 226 deletions(-) diff --git a/examples/xmlpatterns/schema/main.cpp b/examples/xmlpatterns/schema/main.cpp index 9537a87..50e1139 100644 --- a/examples/xmlpatterns/schema/main.cpp +++ b/examples/xmlpatterns/schema/main.cpp @@ -3,9 +3,39 @@ ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). ** Contact: Qt Software Information (qt-info@nokia.com) ** -** This file is part of the $MODULE$ of the Qt Toolkit. +** This file is part of the examples of the Qt Toolkit. ** -** $TROLLTECH_DUAL_LICENSE$ +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ ** ****************************************************************************/ diff --git a/examples/xmlpatterns/schema/mainwindow.cpp b/examples/xmlpatterns/schema/mainwindow.cpp index 807a65b..6b43d7b 100644 --- a/examples/xmlpatterns/schema/mainwindow.cpp +++ b/examples/xmlpatterns/schema/mainwindow.cpp @@ -3,9 +3,39 @@ ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). ** Contact: Qt Software Information (qt-info@nokia.com) ** -** This file is part of the $MODULE$ of the Qt Toolkit. +** This file is part of the examples of the Qt Toolkit. ** -** $TROLLTECH_DUAL_LICENSE$ +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ ** ****************************************************************************/ diff --git a/examples/xmlpatterns/schema/mainwindow.h b/examples/xmlpatterns/schema/mainwindow.h index e5dc2df..5f56afc 100644 --- a/examples/xmlpatterns/schema/mainwindow.h +++ b/examples/xmlpatterns/schema/mainwindow.h @@ -3,9 +3,39 @@ ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). ** Contact: Qt Software Information (qt-info@nokia.com) ** -** This file is part of the $MODULE$ of the Qt Toolkit. +** This file is part of the examples of the Qt Toolkit. ** -** $TROLLTECH_DUAL_LICENSE$ +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ ** ****************************************************************************/ diff --git a/src/xmlpatterns/api/qabstractxmlpullprovider.cpp b/src/xmlpatterns/api/qabstractxmlpullprovider.cpp index a80604b..7a7d87d 100644 --- a/src/xmlpatterns/api/qabstractxmlpullprovider.cpp +++ b/src/xmlpatterns/api/qabstractxmlpullprovider.cpp @@ -3,9 +3,39 @@ ** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies). ** Contact: Qt Software Information (qt-info@nokia.com) ** -** This file is part of the $MODULE$ of the Qt Toolkit. +** This file is part of the QtXmlPatterns of the Qt Toolkit. ** -** $TROLLTECH_DUAL_LICENSE$ +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ ** ****************************************************************************/ diff --git a/src/xmlpatterns/api/qabstractxmlpullprovider_p.h b/src/xmlpatterns/api/qabstractxmlpullprovider_p.h index d05e649..99fb280 100644 --- a/src/xmlpatterns/api/qabstractxmlpullprovider_p.h +++ b/src/xmlpatterns/api/qabstractxmlpullprovider_p.h @@ -3,9 +3,39 @@ ** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies). ** Contact: Qt Software Information (qt-info@nokia.com) ** -** This file is part of the $MODULE$ of the Qt Toolkit. +** This file is part of the QtXmlPatterns of the Qt Toolkit. ** -** $TROLLTECH_DUAL_LICENSE$ +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ ** ****************************************************************************/ diff --git a/src/xmlpatterns/api/qpullbridge.cpp b/src/xmlpatterns/api/qpullbridge.cpp index f347339..1456b32 100644 --- a/src/xmlpatterns/api/qpullbridge.cpp +++ b/src/xmlpatterns/api/qpullbridge.cpp @@ -3,9 +3,39 @@ ** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies). ** Contact: Qt Software Information (qt-info@nokia.com) ** -** This file is part of the $MODULE$ of the Qt Toolkit. +** This file is part of the QtXmlPatterns of the Qt Toolkit. ** -** $TROLLTECH_DUAL_LICENSE$ +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ ** ****************************************************************************/ diff --git a/src/xmlpatterns/api/qpullbridge_p.h b/src/xmlpatterns/api/qpullbridge_p.h index 823d27b..14aa29a 100644 --- a/src/xmlpatterns/api/qpullbridge_p.h +++ b/src/xmlpatterns/api/qpullbridge_p.h @@ -3,9 +3,39 @@ ** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies). ** Contact: Qt Software Information (qt-info@nokia.com) ** -** This file is part of the $MODULE$ of the Qt Toolkit. +** This file is part of the QtXmlPatterns of the Qt Toolkit. ** -** $TROLLTECH_DUAL_LICENSE$ +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ ** ****************************************************************************/ diff --git a/src/xmlpatterns/api/qxmlschema.cpp b/src/xmlpatterns/api/qxmlschema.cpp index 108212e..aa5b77c 100644 --- a/src/xmlpatterns/api/qxmlschema.cpp +++ b/src/xmlpatterns/api/qxmlschema.cpp @@ -3,9 +3,39 @@ ** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies). ** Contact: Qt Software Information (qt-info@nokia.com) ** -** This file is part of the $MODULE$ of the Qt Toolkit. +** This file is part of the QtXmlPatterns of the Qt Toolkit. ** -** $TROLLTECH_DUAL_LICENSE$ +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ ** ****************************************************************************/ diff --git a/src/xmlpatterns/api/qxmlschema.h b/src/xmlpatterns/api/qxmlschema.h index cf56b1e..d057b2c 100644 --- a/src/xmlpatterns/api/qxmlschema.h +++ b/src/xmlpatterns/api/qxmlschema.h @@ -3,9 +3,39 @@ ** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies). ** Contact: Qt Software Information (qt-info@nokia.com) ** -** This file is part of the $MODULE$ of the Qt Toolkit. +** This file is part of the QtXmlPatterns of the Qt Toolkit. ** -** $TROLLTECH_DUAL_LICENSE$ +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ ** ****************************************************************************/ diff --git a/src/xmlpatterns/api/qxmlschema_p.cpp b/src/xmlpatterns/api/qxmlschema_p.cpp index 21dc04a..7b96f82 100644 --- a/src/xmlpatterns/api/qxmlschema_p.cpp +++ b/src/xmlpatterns/api/qxmlschema_p.cpp @@ -3,9 +3,39 @@ ** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies). ** Contact: Qt Software Information (qt-info@nokia.com) ** -** This file is part of the $MODULE$ of the Qt Toolkit. +** This file is part of the QtXmlPatterns of the Qt Toolkit. ** -** $TROLLTECH_DUAL_LICENSE$ +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ ** ****************************************************************************/ diff --git a/src/xmlpatterns/api/qxmlschema_p.h b/src/xmlpatterns/api/qxmlschema_p.h index efba256..b54d88f 100644 --- a/src/xmlpatterns/api/qxmlschema_p.h +++ b/src/xmlpatterns/api/qxmlschema_p.h @@ -3,9 +3,39 @@ ** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies). ** Contact: Qt Software Information (qt-info@nokia.com) ** -** This file is part of the $MODULE$ of the Qt Toolkit. +** This file is part of the QtXmlPatterns of the Qt Toolkit. ** -** $TROLLTECH_DUAL_LICENSE$ +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ ** ****************************************************************************/ diff --git a/src/xmlpatterns/api/qxmlschemavalidator.cpp b/src/xmlpatterns/api/qxmlschemavalidator.cpp index fcde49c..7a4ce03 100644 --- a/src/xmlpatterns/api/qxmlschemavalidator.cpp +++ b/src/xmlpatterns/api/qxmlschemavalidator.cpp @@ -3,9 +3,39 @@ ** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies). ** Contact: Qt Software Information (qt-info@nokia.com) ** -** This file is part of the $MODULE$ of the Qt Toolkit. +** This file is part of the QtXmlPatterns of the Qt Toolkit. ** -** $TROLLTECH_DUAL_LICENSE$ +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ ** ****************************************************************************/ diff --git a/src/xmlpatterns/api/qxmlschemavalidator.h b/src/xmlpatterns/api/qxmlschemavalidator.h index c82c522..e6683a5 100644 --- a/src/xmlpatterns/api/qxmlschemavalidator.h +++ b/src/xmlpatterns/api/qxmlschemavalidator.h @@ -3,9 +3,39 @@ ** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies). ** Contact: Qt Software Information (qt-info@nokia.com) ** -** This file is part of the $MODULE$ of the Qt Toolkit. +** This file is part of the QtXmlPatterns of the Qt Toolkit. ** -** $TROLLTECH_DUAL_LICENSE$ +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ ** ****************************************************************************/ diff --git a/src/xmlpatterns/api/qxmlschemavalidator_p.h b/src/xmlpatterns/api/qxmlschemavalidator_p.h index 9910f6e..fbf7b1c 100644 --- a/src/xmlpatterns/api/qxmlschemavalidator_p.h +++ b/src/xmlpatterns/api/qxmlschemavalidator_p.h @@ -3,9 +3,39 @@ ** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies). ** Contact: Qt Software Information (qt-info@nokia.com) ** -** This file is part of the $MODULE$ of the Qt Toolkit. +** This file is part of the QtXmlPatterns of the Qt Toolkit. ** -** $TROLLTECH_DUAL_LICENSE$ +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ ** ****************************************************************************/ diff --git a/src/xmlpatterns/data/qcomparisonfactory.cpp b/src/xmlpatterns/data/qcomparisonfactory.cpp index 7fe298b..79ff105 100644 --- a/src/xmlpatterns/data/qcomparisonfactory.cpp +++ b/src/xmlpatterns/data/qcomparisonfactory.cpp @@ -3,9 +3,39 @@ ** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies). ** Contact: Qt Software Information (qt-info@nokia.com) ** -** This file is part of the $MODULE$ of the Qt Toolkit. +** This file is part of the QtXmlPatterns of the Qt Toolkit. ** -** $TROLLTECH_DUAL_LICENSE$ +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ ** ****************************************************************************/ diff --git a/src/xmlpatterns/data/qcomparisonfactory_p.h b/src/xmlpatterns/data/qcomparisonfactory_p.h index 09fc50b..88c587e 100644 --- a/src/xmlpatterns/data/qcomparisonfactory_p.h +++ b/src/xmlpatterns/data/qcomparisonfactory_p.h @@ -3,9 +3,39 @@ ** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies). ** Contact: Qt Software Information (qt-info@nokia.com) ** -** This file is part of the $MODULE$ of the Qt Toolkit. +** This file is part of the QtXmlPatterns of the Qt Toolkit. ** -** $TROLLTECH_DUAL_LICENSE$ +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ ** ****************************************************************************/ diff --git a/src/xmlpatterns/data/qvaluefactory.cpp b/src/xmlpatterns/data/qvaluefactory.cpp index 04df29d..6c8fbec 100644 --- a/src/xmlpatterns/data/qvaluefactory.cpp +++ b/src/xmlpatterns/data/qvaluefactory.cpp @@ -3,9 +3,39 @@ ** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies). ** Contact: Qt Software Information (qt-info@nokia.com) ** -** This file is part of the $MODULE$ of the Qt Toolkit. +** This file is part of the QtXmlPatterns of the Qt Toolkit. ** -** $TROLLTECH_DUAL_LICENSE$ +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ ** ****************************************************************************/ diff --git a/src/xmlpatterns/data/qvaluefactory_p.h b/src/xmlpatterns/data/qvaluefactory_p.h index 80b6207..0efe247 100644 --- a/src/xmlpatterns/data/qvaluefactory_p.h +++ b/src/xmlpatterns/data/qvaluefactory_p.h @@ -3,9 +3,39 @@ ** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies). ** Contact: Qt Software Information (qt-info@nokia.com) ** -** This file is part of the $MODULE$ of the Qt Toolkit. +** This file is part of the QtXmlPatterns of the Qt Toolkit. ** -** $TROLLTECH_DUAL_LICENSE$ +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ ** ****************************************************************************/ diff --git a/src/xmlpatterns/parser/qquerytransformparser_p.h b/src/xmlpatterns/parser/qquerytransformparser_p.h index 759c39f..fb3ff72 100644 --- a/src/xmlpatterns/parser/qquerytransformparser_p.h +++ b/src/xmlpatterns/parser/qquerytransformparser_p.h @@ -54,9 +54,39 @@ ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). ** Contact: Qt Software Information (qt-info@nokia.com) ** -** This file is part of the $MODULE$ of the Qt Toolkit. +** This file is part of the QtXmlPatterns of the Qt Toolkit. ** -** $TROLLTECH_DUAL_LICENSE$ +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ ** ****************************************************************************/ diff --git a/src/xmlpatterns/schema/qnamespacesupport.cpp b/src/xmlpatterns/schema/qnamespacesupport.cpp index 349f451..dc76a6f 100644 --- a/src/xmlpatterns/schema/qnamespacesupport.cpp +++ b/src/xmlpatterns/schema/qnamespacesupport.cpp @@ -3,9 +3,39 @@ ** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies). ** Contact: Qt Software Information (qt-info@nokia.com) ** -** This file is part of the $MODULE$ of the Qt Toolkit. +** This file is part of the QtXmlPatterns of the Qt Toolkit. ** -** $TROLLTECH_DUAL_LICENSE$ +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ ** ****************************************************************************/ diff --git a/src/xmlpatterns/schema/qnamespacesupport_p.h b/src/xmlpatterns/schema/qnamespacesupport_p.h index d338eae..1f8f955 100644 --- a/src/xmlpatterns/schema/qnamespacesupport_p.h +++ b/src/xmlpatterns/schema/qnamespacesupport_p.h @@ -3,9 +3,39 @@ ** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies). ** Contact: Qt Software Information (qt-info@nokia.com) ** -** This file is part of the $MODULE$ of the Qt Toolkit. +** This file is part of the QtXmlPatterns of the Qt Toolkit. ** -** $TROLLTECH_DUAL_LICENSE$ +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ ** ****************************************************************************/ diff --git a/src/xmlpatterns/schema/qxsdalternative.cpp b/src/xmlpatterns/schema/qxsdalternative.cpp index f3f589a..6e4a7ab 100644 --- a/src/xmlpatterns/schema/qxsdalternative.cpp +++ b/src/xmlpatterns/schema/qxsdalternative.cpp @@ -3,9 +3,39 @@ ** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies). ** Contact: Qt Software Information (qt-info@nokia.com) ** -** This file is part of the $MODULE$ of the Qt Toolkit. +** This file is part of the QtXmlPatterns of the Qt Toolkit. ** -** $TROLLTECH_DUAL_LICENSE$ +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ ** ****************************************************************************/ diff --git a/src/xmlpatterns/schema/qxsdalternative_p.h b/src/xmlpatterns/schema/qxsdalternative_p.h index 451441e..2b1c75d 100644 --- a/src/xmlpatterns/schema/qxsdalternative_p.h +++ b/src/xmlpatterns/schema/qxsdalternative_p.h @@ -3,9 +3,39 @@ ** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies). ** Contact: Qt Software Information (qt-info@nokia.com) ** -** This file is part of the $MODULE$ of the Qt Toolkit. +** This file is part of the QtXmlPatterns of the Qt Toolkit. ** -** $TROLLTECH_DUAL_LICENSE$ +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ ** ****************************************************************************/ diff --git a/src/xmlpatterns/schema/qxsdannotated.cpp b/src/xmlpatterns/schema/qxsdannotated.cpp index a29b5c4..6674180 100644 --- a/src/xmlpatterns/schema/qxsdannotated.cpp +++ b/src/xmlpatterns/schema/qxsdannotated.cpp @@ -3,9 +3,39 @@ ** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies). ** Contact: Qt Software Information (qt-info@nokia.com) ** -** This file is part of the $MODULE$ of the Qt Toolkit. +** This file is part of the QtXmlPatterns of the Qt Toolkit. ** -** $TROLLTECH_DUAL_LICENSE$ +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ ** ****************************************************************************/ diff --git a/src/xmlpatterns/schema/qxsdannotated_p.h b/src/xmlpatterns/schema/qxsdannotated_p.h index 251b252..18f0612 100644 --- a/src/xmlpatterns/schema/qxsdannotated_p.h +++ b/src/xmlpatterns/schema/qxsdannotated_p.h @@ -3,9 +3,39 @@ ** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies). ** Contact: Qt Software Information (qt-info@nokia.com) ** -** This file is part of the $MODULE$ of the Qt Toolkit. +** This file is part of the QtXmlPatterns of the Qt Toolkit. ** -** $TROLLTECH_DUAL_LICENSE$ +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ ** ****************************************************************************/ diff --git a/src/xmlpatterns/schema/qxsdannotation.cpp b/src/xmlpatterns/schema/qxsdannotation.cpp index 0a9dc04..37ec09f 100644 --- a/src/xmlpatterns/schema/qxsdannotation.cpp +++ b/src/xmlpatterns/schema/qxsdannotation.cpp @@ -3,9 +3,39 @@ ** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies). ** Contact: Qt Software Information (qt-info@nokia.com) ** -** This file is part of the $MODULE$ of the Qt Toolkit. +** This file is part of the QtXmlPatterns of the Qt Toolkit. ** -** $TROLLTECH_DUAL_LICENSE$ +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ ** ****************************************************************************/ diff --git a/src/xmlpatterns/schema/qxsdannotation_p.h b/src/xmlpatterns/schema/qxsdannotation_p.h index 8c23bae..1f2cd14 100644 --- a/src/xmlpatterns/schema/qxsdannotation_p.h +++ b/src/xmlpatterns/schema/qxsdannotation_p.h @@ -3,9 +3,39 @@ ** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies). ** Contact: Qt Software Information (qt-info@nokia.com) ** -** This file is part of the $MODULE$ of the Qt Toolkit. +** This file is part of the QtXmlPatterns of the Qt Toolkit. ** -** $TROLLTECH_DUAL_LICENSE$ +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ ** ****************************************************************************/ diff --git a/src/xmlpatterns/schema/qxsdapplicationinformation.cpp b/src/xmlpatterns/schema/qxsdapplicationinformation.cpp index 5669220..3b4da24 100644 --- a/src/xmlpatterns/schema/qxsdapplicationinformation.cpp +++ b/src/xmlpatterns/schema/qxsdapplicationinformation.cpp @@ -3,9 +3,39 @@ ** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies). ** Contact: Qt Software Information (qt-info@nokia.com) ** -** This file is part of the $MODULE$ of the Qt Toolkit. +** This file is part of the QtXmlPatterns of the Qt Toolkit. ** -** $TROLLTECH_DUAL_LICENSE$ +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ ** ****************************************************************************/ diff --git a/src/xmlpatterns/schema/qxsdapplicationinformation_p.h b/src/xmlpatterns/schema/qxsdapplicationinformation_p.h index 30839d3..224b511 100644 --- a/src/xmlpatterns/schema/qxsdapplicationinformation_p.h +++ b/src/xmlpatterns/schema/qxsdapplicationinformation_p.h @@ -3,9 +3,39 @@ ** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies). ** Contact: Qt Software Information (qt-info@nokia.com) ** -** This file is part of the $MODULE$ of the Qt Toolkit. +** This file is part of the QtXmlPatterns of the Qt Toolkit. ** -** $TROLLTECH_DUAL_LICENSE$ +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ ** ****************************************************************************/ diff --git a/src/xmlpatterns/schema/qxsdassertion.cpp b/src/xmlpatterns/schema/qxsdassertion.cpp index f6cbf81..5a97385 100644 --- a/src/xmlpatterns/schema/qxsdassertion.cpp +++ b/src/xmlpatterns/schema/qxsdassertion.cpp @@ -3,9 +3,39 @@ ** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies). ** Contact: Qt Software Information (qt-info@nokia.com) ** -** This file is part of the $MODULE$ of the Qt Toolkit. +** This file is part of the QtXmlPatterns of the Qt Toolkit. ** -** $TROLLTECH_DUAL_LICENSE$ +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ ** ****************************************************************************/ diff --git a/src/xmlpatterns/schema/qxsdassertion_p.h b/src/xmlpatterns/schema/qxsdassertion_p.h index 0ae5ff6..58f6073 100644 --- a/src/xmlpatterns/schema/qxsdassertion_p.h +++ b/src/xmlpatterns/schema/qxsdassertion_p.h @@ -3,9 +3,39 @@ ** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies). ** Contact: Qt Software Information (qt-info@nokia.com) ** -** This file is part of the $MODULE$ of the Qt Toolkit. +** This file is part of the QtXmlPatterns of the Qt Toolkit. ** -** $TROLLTECH_DUAL_LICENSE$ +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ ** ****************************************************************************/ diff --git a/src/xmlpatterns/schema/qxsdattribute.cpp b/src/xmlpatterns/schema/qxsdattribute.cpp index 6cf60ec..bf640e7 100644 --- a/src/xmlpatterns/schema/qxsdattribute.cpp +++ b/src/xmlpatterns/schema/qxsdattribute.cpp @@ -3,9 +3,39 @@ ** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies). ** Contact: Qt Software Information (qt-info@nokia.com) ** -** This file is part of the $MODULE$ of the Qt Toolkit. +** This file is part of the QtXmlPatterns of the Qt Toolkit. ** -** $TROLLTECH_DUAL_LICENSE$ +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ ** ****************************************************************************/ diff --git a/src/xmlpatterns/schema/qxsdattribute_p.h b/src/xmlpatterns/schema/qxsdattribute_p.h index 46d7355..e0ff854 100644 --- a/src/xmlpatterns/schema/qxsdattribute_p.h +++ b/src/xmlpatterns/schema/qxsdattribute_p.h @@ -3,9 +3,39 @@ ** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies). ** Contact: Qt Software Information (qt-info@nokia.com) ** -** This file is part of the $MODULE$ of the Qt Toolkit. +** This file is part of the QtXmlPatterns of the Qt Toolkit. ** -** $TROLLTECH_DUAL_LICENSE$ +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ ** ****************************************************************************/ diff --git a/src/xmlpatterns/schema/qxsdattributegroup.cpp b/src/xmlpatterns/schema/qxsdattributegroup.cpp index 8f2a47e..b6549eb 100644 --- a/src/xmlpatterns/schema/qxsdattributegroup.cpp +++ b/src/xmlpatterns/schema/qxsdattributegroup.cpp @@ -3,9 +3,39 @@ ** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies). ** Contact: Qt Software Information (qt-info@nokia.com) ** -** This file is part of the $MODULE$ of the Qt Toolkit. +** This file is part of the QtXmlPatterns of the Qt Toolkit. ** -** $TROLLTECH_DUAL_LICENSE$ +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ ** ****************************************************************************/ diff --git a/src/xmlpatterns/schema/qxsdattributegroup_p.h b/src/xmlpatterns/schema/qxsdattributegroup_p.h index 7a3bd79..4fe9c37 100644 --- a/src/xmlpatterns/schema/qxsdattributegroup_p.h +++ b/src/xmlpatterns/schema/qxsdattributegroup_p.h @@ -3,9 +3,39 @@ ** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies). ** Contact: Qt Software Information (qt-info@nokia.com) ** -** This file is part of the $MODULE$ of the Qt Toolkit. +** This file is part of the QtXmlPatterns of the Qt Toolkit. ** -** $TROLLTECH_DUAL_LICENSE$ +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ ** ****************************************************************************/ diff --git a/src/xmlpatterns/schema/qxsdattributereference.cpp b/src/xmlpatterns/schema/qxsdattributereference.cpp index 3c36a4e..6e5809c 100644 --- a/src/xmlpatterns/schema/qxsdattributereference.cpp +++ b/src/xmlpatterns/schema/qxsdattributereference.cpp @@ -3,9 +3,39 @@ ** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies). ** Contact: Qt Software Information (qt-info@nokia.com) ** -** This file is part of the $MODULE$ of the Qt Toolkit. +** This file is part of the QtXmlPatterns of the Qt Toolkit. ** -** $TROLLTECH_DUAL_LICENSE$ +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ ** ****************************************************************************/ diff --git a/src/xmlpatterns/schema/qxsdattributereference_p.h b/src/xmlpatterns/schema/qxsdattributereference_p.h index be48b3a..6500109 100644 --- a/src/xmlpatterns/schema/qxsdattributereference_p.h +++ b/src/xmlpatterns/schema/qxsdattributereference_p.h @@ -3,9 +3,39 @@ ** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies). ** Contact: Qt Software Information (qt-info@nokia.com) ** -** This file is part of the $MODULE$ of the Qt Toolkit. +** This file is part of the QtXmlPatterns of the Qt Toolkit. ** -** $TROLLTECH_DUAL_LICENSE$ +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ ** ****************************************************************************/ diff --git a/src/xmlpatterns/schema/qxsdattributeterm.cpp b/src/xmlpatterns/schema/qxsdattributeterm.cpp index a9c3898..6463e35 100644 --- a/src/xmlpatterns/schema/qxsdattributeterm.cpp +++ b/src/xmlpatterns/schema/qxsdattributeterm.cpp @@ -3,9 +3,39 @@ ** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies). ** Contact: Qt Software Information (qt-info@nokia.com) ** -** This file is part of the $MODULE$ of the Qt Toolkit. +** This file is part of the QtXmlPatterns of the Qt Toolkit. ** -** $TROLLTECH_DUAL_LICENSE$ +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ ** ****************************************************************************/ diff --git a/src/xmlpatterns/schema/qxsdattributeterm_p.h b/src/xmlpatterns/schema/qxsdattributeterm_p.h index 507df32..6e49cfc 100644 --- a/src/xmlpatterns/schema/qxsdattributeterm_p.h +++ b/src/xmlpatterns/schema/qxsdattributeterm_p.h @@ -3,9 +3,39 @@ ** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies). ** Contact: Qt Software Information (qt-info@nokia.com) ** -** This file is part of the $MODULE$ of the Qt Toolkit. +** This file is part of the QtXmlPatterns of the Qt Toolkit. ** -** $TROLLTECH_DUAL_LICENSE$ +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ ** ****************************************************************************/ diff --git a/src/xmlpatterns/schema/qxsdattributeuse.cpp b/src/xmlpatterns/schema/qxsdattributeuse.cpp index 96d81bc..0f7ed9f 100644 --- a/src/xmlpatterns/schema/qxsdattributeuse.cpp +++ b/src/xmlpatterns/schema/qxsdattributeuse.cpp @@ -3,9 +3,39 @@ ** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies). ** Contact: Qt Software Information (qt-info@nokia.com) ** -** This file is part of the $MODULE$ of the Qt Toolkit. +** This file is part of the QtXmlPatterns of the Qt Toolkit. ** -** $TROLLTECH_DUAL_LICENSE$ +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ ** ****************************************************************************/ diff --git a/src/xmlpatterns/schema/qxsdattributeuse_p.h b/src/xmlpatterns/schema/qxsdattributeuse_p.h index 86021e1..bf2eac5 100644 --- a/src/xmlpatterns/schema/qxsdattributeuse_p.h +++ b/src/xmlpatterns/schema/qxsdattributeuse_p.h @@ -3,9 +3,39 @@ ** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies). ** Contact: Qt Software Information (qt-info@nokia.com) ** -** This file is part of the $MODULE$ of the Qt Toolkit. +** This file is part of the QtXmlPatterns of the Qt Toolkit. ** -** $TROLLTECH_DUAL_LICENSE$ +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ ** ****************************************************************************/ diff --git a/src/xmlpatterns/schema/qxsdcomplextype.cpp b/src/xmlpatterns/schema/qxsdcomplextype.cpp index ddc9110..6f5a240 100644 --- a/src/xmlpatterns/schema/qxsdcomplextype.cpp +++ b/src/xmlpatterns/schema/qxsdcomplextype.cpp @@ -3,9 +3,39 @@ ** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies). ** Contact: Qt Software Information (qt-info@nokia.com) ** -** This file is part of the $MODULE$ of the Qt Toolkit. +** This file is part of the QtXmlPatterns of the Qt Toolkit. ** -** $TROLLTECH_DUAL_LICENSE$ +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ ** ****************************************************************************/ diff --git a/src/xmlpatterns/schema/qxsdcomplextype_p.h b/src/xmlpatterns/schema/qxsdcomplextype_p.h index 078c8f0..4333d24 100644 --- a/src/xmlpatterns/schema/qxsdcomplextype_p.h +++ b/src/xmlpatterns/schema/qxsdcomplextype_p.h @@ -3,9 +3,39 @@ ** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies). ** Contact: Qt Software Information (qt-info@nokia.com) ** -** This file is part of the $MODULE$ of the Qt Toolkit. +** This file is part of the QtXmlPatterns of the Qt Toolkit. ** -** $TROLLTECH_DUAL_LICENSE$ +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ ** ****************************************************************************/ diff --git a/src/xmlpatterns/schema/qxsddocumentation.cpp b/src/xmlpatterns/schema/qxsddocumentation.cpp index 4994143..b2490f6 100644 --- a/src/xmlpatterns/schema/qxsddocumentation.cpp +++ b/src/xmlpatterns/schema/qxsddocumentation.cpp @@ -3,9 +3,39 @@ ** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies). ** Contact: Qt Software Information (qt-info@nokia.com) ** -** This file is part of the $MODULE$ of the Qt Toolkit. +** This file is part of the QtXmlPatterns of the Qt Toolkit. ** -** $TROLLTECH_DUAL_LICENSE$ +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ ** ****************************************************************************/ diff --git a/src/xmlpatterns/schema/qxsddocumentation_p.h b/src/xmlpatterns/schema/qxsddocumentation_p.h index c44a2bb..35463da 100644 --- a/src/xmlpatterns/schema/qxsddocumentation_p.h +++ b/src/xmlpatterns/schema/qxsddocumentation_p.h @@ -3,9 +3,39 @@ ** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies). ** Contact: Qt Software Information (qt-info@nokia.com) ** -** This file is part of the $MODULE$ of the Qt Toolkit. +** This file is part of the QtXmlPatterns of the Qt Toolkit. ** -** $TROLLTECH_DUAL_LICENSE$ +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ ** ****************************************************************************/ diff --git a/src/xmlpatterns/schema/qxsdelement.cpp b/src/xmlpatterns/schema/qxsdelement.cpp index 2b8ccab..c344799 100644 --- a/src/xmlpatterns/schema/qxsdelement.cpp +++ b/src/xmlpatterns/schema/qxsdelement.cpp @@ -3,9 +3,39 @@ ** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies). ** Contact: Qt Software Information (qt-info@nokia.com) ** -** This file is part of the $MODULE$ of the Qt Toolkit. +** This file is part of the QtXmlPatterns of the Qt Toolkit. ** -** $TROLLTECH_DUAL_LICENSE$ +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ ** ****************************************************************************/ diff --git a/src/xmlpatterns/schema/qxsdelement_p.h b/src/xmlpatterns/schema/qxsdelement_p.h index e571687..70ecb7e 100644 --- a/src/xmlpatterns/schema/qxsdelement_p.h +++ b/src/xmlpatterns/schema/qxsdelement_p.h @@ -3,9 +3,39 @@ ** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies). ** Contact: Qt Software Information (qt-info@nokia.com) ** -** This file is part of the $MODULE$ of the Qt Toolkit. +** This file is part of the QtXmlPatterns of the Qt Toolkit. ** -** $TROLLTECH_DUAL_LICENSE$ +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ ** ****************************************************************************/ diff --git a/src/xmlpatterns/schema/qxsdfacet.cpp b/src/xmlpatterns/schema/qxsdfacet.cpp index 513eee8..b49d530 100644 --- a/src/xmlpatterns/schema/qxsdfacet.cpp +++ b/src/xmlpatterns/schema/qxsdfacet.cpp @@ -3,9 +3,39 @@ ** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies). ** Contact: Qt Software Information (qt-info@nokia.com) ** -** This file is part of the $MODULE$ of the Qt Toolkit. +** This file is part of the QtXmlPatterns of the Qt Toolkit. ** -** $TROLLTECH_DUAL_LICENSE$ +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ ** ****************************************************************************/ diff --git a/src/xmlpatterns/schema/qxsdfacet_p.h b/src/xmlpatterns/schema/qxsdfacet_p.h index f1f8110..fe845d0 100644 --- a/src/xmlpatterns/schema/qxsdfacet_p.h +++ b/src/xmlpatterns/schema/qxsdfacet_p.h @@ -3,9 +3,39 @@ ** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies). ** Contact: Qt Software Information (qt-info@nokia.com) ** -** This file is part of the $MODULE$ of the Qt Toolkit. +** This file is part of the QtXmlPatterns of the Qt Toolkit. ** -** $TROLLTECH_DUAL_LICENSE$ +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ ** ****************************************************************************/ diff --git a/src/xmlpatterns/schema/qxsdidcache.cpp b/src/xmlpatterns/schema/qxsdidcache.cpp index d4a7b64..2d4adc9 100644 --- a/src/xmlpatterns/schema/qxsdidcache.cpp +++ b/src/xmlpatterns/schema/qxsdidcache.cpp @@ -3,9 +3,39 @@ ** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies). ** Contact: Qt Software Information (qt-info@nokia.com) ** -** This file is part of the $MODULE$ of the Qt Toolkit. +** This file is part of the QtXmlPatterns of the Qt Toolkit. ** -** $TROLLTECH_DUAL_LICENSE$ +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ ** ****************************************************************************/ diff --git a/src/xmlpatterns/schema/qxsdidcache_p.h b/src/xmlpatterns/schema/qxsdidcache_p.h index b1d3c0f..c81e4dc 100644 --- a/src/xmlpatterns/schema/qxsdidcache_p.h +++ b/src/xmlpatterns/schema/qxsdidcache_p.h @@ -3,9 +3,39 @@ ** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies). ** Contact: Qt Software Information (qt-info@nokia.com) ** -** This file is part of the $MODULE$ of the Qt Toolkit. +** This file is part of the QtXmlPatterns of the Qt Toolkit. ** -** $TROLLTECH_DUAL_LICENSE$ +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ ** ****************************************************************************/ diff --git a/src/xmlpatterns/schema/qxsdidchelper.cpp b/src/xmlpatterns/schema/qxsdidchelper.cpp index 70980cb..0442f26 100644 --- a/src/xmlpatterns/schema/qxsdidchelper.cpp +++ b/src/xmlpatterns/schema/qxsdidchelper.cpp @@ -3,9 +3,39 @@ ** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies). ** Contact: Qt Software Information (qt-info@nokia.com) ** -** This file is part of the $MODULE$ of the Qt Toolkit. +** This file is part of the QtXmlPatterns of the Qt Toolkit. ** -** $TROLLTECH_DUAL_LICENSE$ +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ ** ****************************************************************************/ diff --git a/src/xmlpatterns/schema/qxsdidchelper_p.h b/src/xmlpatterns/schema/qxsdidchelper_p.h index 3034292..d25d713 100644 --- a/src/xmlpatterns/schema/qxsdidchelper_p.h +++ b/src/xmlpatterns/schema/qxsdidchelper_p.h @@ -3,9 +3,39 @@ ** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies). ** Contact: Qt Software Information (qt-info@nokia.com) ** -** This file is part of the $MODULE$ of the Qt Toolkit. +** This file is part of the QtXmlPatterns of the Qt Toolkit. ** -** $TROLLTECH_DUAL_LICENSE$ +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ ** ****************************************************************************/ diff --git a/src/xmlpatterns/schema/qxsdidentityconstraint.cpp b/src/xmlpatterns/schema/qxsdidentityconstraint.cpp index e72a005..eec1235 100644 --- a/src/xmlpatterns/schema/qxsdidentityconstraint.cpp +++ b/src/xmlpatterns/schema/qxsdidentityconstraint.cpp @@ -3,9 +3,39 @@ ** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies). ** Contact: Qt Software Information (qt-info@nokia.com) ** -** This file is part of the $MODULE$ of the Qt Toolkit. +** This file is part of the QtXmlPatterns of the Qt Toolkit. ** -** $TROLLTECH_DUAL_LICENSE$ +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ ** ****************************************************************************/ diff --git a/src/xmlpatterns/schema/qxsdidentityconstraint_p.h b/src/xmlpatterns/schema/qxsdidentityconstraint_p.h index 6870b1e..712ea98 100644 --- a/src/xmlpatterns/schema/qxsdidentityconstraint_p.h +++ b/src/xmlpatterns/schema/qxsdidentityconstraint_p.h @@ -3,9 +3,39 @@ ** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies). ** Contact: Qt Software Information (qt-info@nokia.com) ** -** This file is part of the $MODULE$ of the Qt Toolkit. +** This file is part of the QtXmlPatterns of the Qt Toolkit. ** -** $TROLLTECH_DUAL_LICENSE$ +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ ** ****************************************************************************/ diff --git a/src/xmlpatterns/schema/qxsdinstancereader.cpp b/src/xmlpatterns/schema/qxsdinstancereader.cpp index 81c40c9..9d2dc60 100644 --- a/src/xmlpatterns/schema/qxsdinstancereader.cpp +++ b/src/xmlpatterns/schema/qxsdinstancereader.cpp @@ -3,9 +3,39 @@ ** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies). ** Contact: Qt Software Information (qt-info@nokia.com) ** -** This file is part of the $MODULE$ of the Qt Toolkit. +** This file is part of the QtXmlPatterns of the Qt Toolkit. ** -** $TROLLTECH_DUAL_LICENSE$ +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ ** ****************************************************************************/ diff --git a/src/xmlpatterns/schema/qxsdinstancereader_p.h b/src/xmlpatterns/schema/qxsdinstancereader_p.h index 9df02d6..1896ad9 100644 --- a/src/xmlpatterns/schema/qxsdinstancereader_p.h +++ b/src/xmlpatterns/schema/qxsdinstancereader_p.h @@ -3,9 +3,39 @@ ** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies). ** Contact: Qt Software Information (qt-info@nokia.com) ** -** This file is part of the $MODULE$ of the Qt Toolkit. +** This file is part of the QtXmlPatterns of the Qt Toolkit. ** -** $TROLLTECH_DUAL_LICENSE$ +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ ** ****************************************************************************/ diff --git a/src/xmlpatterns/schema/qxsdmodelgroup.cpp b/src/xmlpatterns/schema/qxsdmodelgroup.cpp index 1245822..a791284 100644 --- a/src/xmlpatterns/schema/qxsdmodelgroup.cpp +++ b/src/xmlpatterns/schema/qxsdmodelgroup.cpp @@ -3,9 +3,39 @@ ** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies). ** Contact: Qt Software Information (qt-info@nokia.com) ** -** This file is part of the $MODULE$ of the Qt Toolkit. +** This file is part of the QtXmlPatterns of the Qt Toolkit. ** -** $TROLLTECH_DUAL_LICENSE$ +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ ** ****************************************************************************/ diff --git a/src/xmlpatterns/schema/qxsdmodelgroup_p.h b/src/xmlpatterns/schema/qxsdmodelgroup_p.h index b7b59ac..eae46b0 100644 --- a/src/xmlpatterns/schema/qxsdmodelgroup_p.h +++ b/src/xmlpatterns/schema/qxsdmodelgroup_p.h @@ -3,9 +3,39 @@ ** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies). ** Contact: Qt Software Information (qt-info@nokia.com) ** -** This file is part of the $MODULE$ of the Qt Toolkit. +** This file is part of the QtXmlPatterns of the Qt Toolkit. ** -** $TROLLTECH_DUAL_LICENSE$ +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ ** ****************************************************************************/ diff --git a/src/xmlpatterns/schema/qxsdnotation.cpp b/src/xmlpatterns/schema/qxsdnotation.cpp index cfa0cd3..6c1d7c0 100644 --- a/src/xmlpatterns/schema/qxsdnotation.cpp +++ b/src/xmlpatterns/schema/qxsdnotation.cpp @@ -3,9 +3,39 @@ ** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies). ** Contact: Qt Software Information (qt-info@nokia.com) ** -** This file is part of the $MODULE$ of the Qt Toolkit. +** This file is part of the QtXmlPatterns of the Qt Toolkit. ** -** $TROLLTECH_DUAL_LICENSE$ +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ ** ****************************************************************************/ diff --git a/src/xmlpatterns/schema/qxsdnotation_p.h b/src/xmlpatterns/schema/qxsdnotation_p.h index dc1d597..6af3f0c 100644 --- a/src/xmlpatterns/schema/qxsdnotation_p.h +++ b/src/xmlpatterns/schema/qxsdnotation_p.h @@ -3,9 +3,39 @@ ** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies). ** Contact: Qt Software Information (qt-info@nokia.com) ** -** This file is part of the $MODULE$ of the Qt Toolkit. +** This file is part of the QtXmlPatterns of the Qt Toolkit. ** -** $TROLLTECH_DUAL_LICENSE$ +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ ** ****************************************************************************/ diff --git a/src/xmlpatterns/schema/qxsdparticle.cpp b/src/xmlpatterns/schema/qxsdparticle.cpp index a2671fa..3e5be44 100644 --- a/src/xmlpatterns/schema/qxsdparticle.cpp +++ b/src/xmlpatterns/schema/qxsdparticle.cpp @@ -3,9 +3,39 @@ ** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies). ** Contact: Qt Software Information (qt-info@nokia.com) ** -** This file is part of the $MODULE$ of the Qt Toolkit. +** This file is part of the QtXmlPatterns of the Qt Toolkit. ** -** $TROLLTECH_DUAL_LICENSE$ +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ ** ****************************************************************************/ diff --git a/src/xmlpatterns/schema/qxsdparticle_p.h b/src/xmlpatterns/schema/qxsdparticle_p.h index 61e3eb3..491cb47 100644 --- a/src/xmlpatterns/schema/qxsdparticle_p.h +++ b/src/xmlpatterns/schema/qxsdparticle_p.h @@ -3,9 +3,39 @@ ** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies). ** Contact: Qt Software Information (qt-info@nokia.com) ** -** This file is part of the $MODULE$ of the Qt Toolkit. +** This file is part of the QtXmlPatterns of the Qt Toolkit. ** -** $TROLLTECH_DUAL_LICENSE$ +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ ** ****************************************************************************/ diff --git a/src/xmlpatterns/schema/qxsdparticlechecker.cpp b/src/xmlpatterns/schema/qxsdparticlechecker.cpp index 7a09f8a..fa26b8b 100644 --- a/src/xmlpatterns/schema/qxsdparticlechecker.cpp +++ b/src/xmlpatterns/schema/qxsdparticlechecker.cpp @@ -3,9 +3,39 @@ ** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies). ** Contact: Qt Software Information (qt-info@nokia.com) ** -** This file is part of the $MODULE$ of the Qt Toolkit. +** This file is part of the QtXmlPatterns of the Qt Toolkit. ** -** $TROLLTECH_DUAL_LICENSE$ +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ ** ****************************************************************************/ diff --git a/src/xmlpatterns/schema/qxsdparticlechecker_p.h b/src/xmlpatterns/schema/qxsdparticlechecker_p.h index 16a8d95..739eca0 100644 --- a/src/xmlpatterns/schema/qxsdparticlechecker_p.h +++ b/src/xmlpatterns/schema/qxsdparticlechecker_p.h @@ -3,9 +3,39 @@ ** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies). ** Contact: Qt Software Information (qt-info@nokia.com) ** -** This file is part of the $MODULE$ of the Qt Toolkit. +** This file is part of the QtXmlPatterns of the Qt Toolkit. ** -** $TROLLTECH_DUAL_LICENSE$ +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ ** ****************************************************************************/ diff --git a/src/xmlpatterns/schema/qxsdreference.cpp b/src/xmlpatterns/schema/qxsdreference.cpp index 0a934dd..e7fc409 100644 --- a/src/xmlpatterns/schema/qxsdreference.cpp +++ b/src/xmlpatterns/schema/qxsdreference.cpp @@ -3,9 +3,39 @@ ** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies). ** Contact: Qt Software Information (qt-info@nokia.com) ** -** This file is part of the $MODULE$ of the Qt Toolkit. +** This file is part of the QtXmlPatterns of the Qt Toolkit. ** -** $TROLLTECH_DUAL_LICENSE$ +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ ** ****************************************************************************/ diff --git a/src/xmlpatterns/schema/qxsdreference_p.h b/src/xmlpatterns/schema/qxsdreference_p.h index afcca25..d6a1693 100644 --- a/src/xmlpatterns/schema/qxsdreference_p.h +++ b/src/xmlpatterns/schema/qxsdreference_p.h @@ -3,9 +3,39 @@ ** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies). ** Contact: Qt Software Information (qt-info@nokia.com) ** -** This file is part of the $MODULE$ of the Qt Toolkit. +** This file is part of the QtXmlPatterns of the Qt Toolkit. ** -** $TROLLTECH_DUAL_LICENSE$ +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ ** ****************************************************************************/ diff --git a/src/xmlpatterns/schema/qxsdschema.cpp b/src/xmlpatterns/schema/qxsdschema.cpp index 260b06b..b9b9e99 100644 --- a/src/xmlpatterns/schema/qxsdschema.cpp +++ b/src/xmlpatterns/schema/qxsdschema.cpp @@ -3,9 +3,39 @@ ** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies). ** Contact: Qt Software Information (qt-info@nokia.com) ** -** This file is part of the $MODULE$ of the Qt Toolkit. +** This file is part of the QtXmlPatterns of the Qt Toolkit. ** -** $TROLLTECH_DUAL_LICENSE$ +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ ** ****************************************************************************/ diff --git a/src/xmlpatterns/schema/qxsdschema_p.h b/src/xmlpatterns/schema/qxsdschema_p.h index b41a2d5..9954f56 100644 --- a/src/xmlpatterns/schema/qxsdschema_p.h +++ b/src/xmlpatterns/schema/qxsdschema_p.h @@ -3,9 +3,39 @@ ** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies). ** Contact: Qt Software Information (qt-info@nokia.com) ** -** This file is part of the $MODULE$ of the Qt Toolkit. +** This file is part of the QtXmlPatterns of the Qt Toolkit. ** -** $TROLLTECH_DUAL_LICENSE$ +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ ** ****************************************************************************/ diff --git a/src/xmlpatterns/schema/qxsdschemachecker.cpp b/src/xmlpatterns/schema/qxsdschemachecker.cpp index 2a64327..42cfff6 100644 --- a/src/xmlpatterns/schema/qxsdschemachecker.cpp +++ b/src/xmlpatterns/schema/qxsdschemachecker.cpp @@ -3,9 +3,39 @@ ** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies). ** Contact: Qt Software Information (qt-info@nokia.com) ** -** This file is part of the $MODULE$ of the Qt Toolkit. +** This file is part of the QtXmlPatterns of the Qt Toolkit. ** -** $TROLLTECH_DUAL_LICENSE$ +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ ** ****************************************************************************/ diff --git a/src/xmlpatterns/schema/qxsdschemachecker_helper.cpp b/src/xmlpatterns/schema/qxsdschemachecker_helper.cpp index 98c4c63..850b17b 100644 --- a/src/xmlpatterns/schema/qxsdschemachecker_helper.cpp +++ b/src/xmlpatterns/schema/qxsdschemachecker_helper.cpp @@ -3,9 +3,39 @@ ** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies). ** Contact: Qt Software Information (qt-info@nokia.com) ** -** This file is part of the $MODULE$ of the Qt Toolkit. +** This file is part of the QtXmlPatterns of the Qt Toolkit. ** -** $TROLLTECH_DUAL_LICENSE$ +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ ** ****************************************************************************/ diff --git a/src/xmlpatterns/schema/qxsdschemachecker_p.h b/src/xmlpatterns/schema/qxsdschemachecker_p.h index 65fb87f..1ec85f9 100644 --- a/src/xmlpatterns/schema/qxsdschemachecker_p.h +++ b/src/xmlpatterns/schema/qxsdschemachecker_p.h @@ -3,9 +3,39 @@ ** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies). ** Contact: Qt Software Information (qt-info@nokia.com) ** -** This file is part of the $MODULE$ of the Qt Toolkit. +** This file is part of the QtXmlPatterns of the Qt Toolkit. ** -** $TROLLTECH_DUAL_LICENSE$ +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ ** ****************************************************************************/ diff --git a/src/xmlpatterns/schema/qxsdschemacontext.cpp b/src/xmlpatterns/schema/qxsdschemacontext.cpp index 65b2e52..4648864 100644 --- a/src/xmlpatterns/schema/qxsdschemacontext.cpp +++ b/src/xmlpatterns/schema/qxsdschemacontext.cpp @@ -3,9 +3,39 @@ ** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies). ** Contact: Qt Software Information (qt-info@nokia.com) ** -** This file is part of the $MODULE$ of the Qt Toolkit. +** This file is part of the QtXmlPatterns of the Qt Toolkit. ** -** $TROLLTECH_DUAL_LICENSE$ +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ ** ****************************************************************************/ diff --git a/src/xmlpatterns/schema/qxsdschemacontext_p.h b/src/xmlpatterns/schema/qxsdschemacontext_p.h index c3a9f15..3aad656 100644 --- a/src/xmlpatterns/schema/qxsdschemacontext_p.h +++ b/src/xmlpatterns/schema/qxsdschemacontext_p.h @@ -3,9 +3,39 @@ ** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies). ** Contact: Qt Software Information (qt-info@nokia.com) ** -** This file is part of the $MODULE$ of the Qt Toolkit. +** This file is part of the QtXmlPatterns of the Qt Toolkit. ** -** $TROLLTECH_DUAL_LICENSE$ +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ ** ****************************************************************************/ diff --git a/src/xmlpatterns/schema/qxsdschemadebugger.cpp b/src/xmlpatterns/schema/qxsdschemadebugger.cpp index 850192c..629333c 100644 --- a/src/xmlpatterns/schema/qxsdschemadebugger.cpp +++ b/src/xmlpatterns/schema/qxsdschemadebugger.cpp @@ -3,9 +3,39 @@ ** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies). ** Contact: Qt Software Information (qt-info@nokia.com) ** -** This file is part of the $MODULE$ of the Qt Toolkit. +** This file is part of the QtXmlPatterns of the Qt Toolkit. ** -** $TROLLTECH_DUAL_LICENSE$ +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ ** ****************************************************************************/ diff --git a/src/xmlpatterns/schema/qxsdschemadebugger_p.h b/src/xmlpatterns/schema/qxsdschemadebugger_p.h index 8966963..a88f432 100644 --- a/src/xmlpatterns/schema/qxsdschemadebugger_p.h +++ b/src/xmlpatterns/schema/qxsdschemadebugger_p.h @@ -3,9 +3,39 @@ ** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies). ** Contact: Qt Software Information (qt-info@nokia.com) ** -** This file is part of the $MODULE$ of the Qt Toolkit. +** This file is part of the QtXmlPatterns of the Qt Toolkit. ** -** $TROLLTECH_DUAL_LICENSE$ +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ ** ****************************************************************************/ diff --git a/src/xmlpatterns/schema/qxsdschemahelper.cpp b/src/xmlpatterns/schema/qxsdschemahelper.cpp index ff169f7..f31ebd6 100644 --- a/src/xmlpatterns/schema/qxsdschemahelper.cpp +++ b/src/xmlpatterns/schema/qxsdschemahelper.cpp @@ -3,9 +3,39 @@ ** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies). ** Contact: Qt Software Information (qt-info@nokia.com) ** -** This file is part of the $MODULE$ of the Qt Toolkit. +** This file is part of the QtXmlPatterns of the Qt Toolkit. ** -** $TROLLTECH_DUAL_LICENSE$ +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ ** ****************************************************************************/ diff --git a/src/xmlpatterns/schema/qxsdschemahelper_p.h b/src/xmlpatterns/schema/qxsdschemahelper_p.h index 918664e..1335691 100644 --- a/src/xmlpatterns/schema/qxsdschemahelper_p.h +++ b/src/xmlpatterns/schema/qxsdschemahelper_p.h @@ -3,9 +3,39 @@ ** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies). ** Contact: Qt Software Information (qt-info@nokia.com) ** -** This file is part of the $MODULE$ of the Qt Toolkit. +** This file is part of the QtXmlPatterns of the Qt Toolkit. ** -** $TROLLTECH_DUAL_LICENSE$ +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ ** ****************************************************************************/ diff --git a/src/xmlpatterns/schema/qxsdschemamerger.cpp b/src/xmlpatterns/schema/qxsdschemamerger.cpp index a924c9c..a0f22a2 100644 --- a/src/xmlpatterns/schema/qxsdschemamerger.cpp +++ b/src/xmlpatterns/schema/qxsdschemamerger.cpp @@ -3,9 +3,39 @@ ** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies). ** Contact: Qt Software Information (qt-info@nokia.com) ** -** This file is part of the $MODULE$ of the Qt Toolkit. +** This file is part of the QtXmlPatterns of the Qt Toolkit. ** -** $TROLLTECH_DUAL_LICENSE$ +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ ** ****************************************************************************/ diff --git a/src/xmlpatterns/schema/qxsdschemamerger_p.h b/src/xmlpatterns/schema/qxsdschemamerger_p.h index 54cc0f2..8154689 100644 --- a/src/xmlpatterns/schema/qxsdschemamerger_p.h +++ b/src/xmlpatterns/schema/qxsdschemamerger_p.h @@ -3,9 +3,39 @@ ** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies). ** Contact: Qt Software Information (qt-info@nokia.com) ** -** This file is part of the $MODULE$ of the Qt Toolkit. +** This file is part of the QtXmlPatterns of the Qt Toolkit. ** -** $TROLLTECH_DUAL_LICENSE$ +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ ** ****************************************************************************/ diff --git a/src/xmlpatterns/schema/qxsdschemaparser_p.h b/src/xmlpatterns/schema/qxsdschemaparser_p.h index 960fb86..c52702b 100644 --- a/src/xmlpatterns/schema/qxsdschemaparser_p.h +++ b/src/xmlpatterns/schema/qxsdschemaparser_p.h @@ -3,9 +3,39 @@ ** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies). ** Contact: Qt Software Information (qt-info@nokia.com) ** -** This file is part of the $MODULE$ of the Qt Toolkit. +** This file is part of the QtXmlPatterns of the Qt Toolkit. ** -** $TROLLTECH_DUAL_LICENSE$ +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ ** ****************************************************************************/ diff --git a/src/xmlpatterns/schema/qxsdschemaparsercontext.cpp b/src/xmlpatterns/schema/qxsdschemaparsercontext.cpp index 896619e..e4dc348 100644 --- a/src/xmlpatterns/schema/qxsdschemaparsercontext.cpp +++ b/src/xmlpatterns/schema/qxsdschemaparsercontext.cpp @@ -3,9 +3,39 @@ ** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies). ** Contact: Qt Software Information (qt-info@nokia.com) ** -** This file is part of the $MODULE$ of the Qt Toolkit. +** This file is part of the QtXmlPatterns of the Qt Toolkit. ** -** $TROLLTECH_DUAL_LICENSE$ +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ ** ****************************************************************************/ diff --git a/src/xmlpatterns/schema/qxsdschemaparsercontext_p.h b/src/xmlpatterns/schema/qxsdschemaparsercontext_p.h index 616aff3..f95f571 100644 --- a/src/xmlpatterns/schema/qxsdschemaparsercontext_p.h +++ b/src/xmlpatterns/schema/qxsdschemaparsercontext_p.h @@ -3,9 +3,39 @@ ** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies). ** Contact: Qt Software Information (qt-info@nokia.com) ** -** This file is part of the $MODULE$ of the Qt Toolkit. +** This file is part of the QtXmlPatterns of the Qt Toolkit. ** -** $TROLLTECH_DUAL_LICENSE$ +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ ** ****************************************************************************/ diff --git a/src/xmlpatterns/schema/qxsdschemaresolver.cpp b/src/xmlpatterns/schema/qxsdschemaresolver.cpp index 4c6910f..46d0c69 100644 --- a/src/xmlpatterns/schema/qxsdschemaresolver.cpp +++ b/src/xmlpatterns/schema/qxsdschemaresolver.cpp @@ -3,9 +3,39 @@ ** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies). ** Contact: Qt Software Information (qt-info@nokia.com) ** -** This file is part of the $MODULE$ of the Qt Toolkit. +** This file is part of the QtXmlPatterns of the Qt Toolkit. ** -** $TROLLTECH_DUAL_LICENSE$ +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ ** ****************************************************************************/ diff --git a/src/xmlpatterns/schema/qxsdschemaresolver_p.h b/src/xmlpatterns/schema/qxsdschemaresolver_p.h index 1222619..79d2a2d 100644 --- a/src/xmlpatterns/schema/qxsdschemaresolver_p.h +++ b/src/xmlpatterns/schema/qxsdschemaresolver_p.h @@ -3,9 +3,39 @@ ** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies). ** Contact: Qt Software Information (qt-info@nokia.com) ** -** This file is part of the $MODULE$ of the Qt Toolkit. +** This file is part of the QtXmlPatterns of the Qt Toolkit. ** -** $TROLLTECH_DUAL_LICENSE$ +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ ** ****************************************************************************/ diff --git a/src/xmlpatterns/schema/qxsdschematoken.cpp b/src/xmlpatterns/schema/qxsdschematoken.cpp index b527de6..e383b16 100644 --- a/src/xmlpatterns/schema/qxsdschematoken.cpp +++ b/src/xmlpatterns/schema/qxsdschematoken.cpp @@ -3,9 +3,39 @@ ** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies). ** Contact: Qt Software Information (qt-info@nokia.com) ** -** This file is part of the $MODULE$ of the Qt Toolkit. +** This file is part of the QtXmlPatterns of the Qt Toolkit. ** -** $TROLLTECH_DUAL_LICENSE$ +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ ** ****************************************************************************/ diff --git a/src/xmlpatterns/schema/qxsdschematoken_p.h b/src/xmlpatterns/schema/qxsdschematoken_p.h index 8cb1e76..58d1f4d 100644 --- a/src/xmlpatterns/schema/qxsdschematoken_p.h +++ b/src/xmlpatterns/schema/qxsdschematoken_p.h @@ -3,9 +3,39 @@ ** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies). ** Contact: Qt Software Information (qt-info@nokia.com) ** -** This file is part of the $MODULE$ of the Qt Toolkit. +** This file is part of the QtXmlPatterns of the Qt Toolkit. ** -** $TROLLTECH_DUAL_LICENSE$ +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ ** ****************************************************************************/ diff --git a/src/xmlpatterns/schema/qxsdschematypesfactory.cpp b/src/xmlpatterns/schema/qxsdschematypesfactory.cpp index 6cac0ff..b8f92a6 100644 --- a/src/xmlpatterns/schema/qxsdschematypesfactory.cpp +++ b/src/xmlpatterns/schema/qxsdschematypesfactory.cpp @@ -3,9 +3,39 @@ ** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies). ** Contact: Qt Software Information (qt-info@nokia.com) ** -** This file is part of the $MODULE$ of the Qt Toolkit. +** This file is part of the QtXmlPatterns of the Qt Toolkit. ** -** $TROLLTECH_DUAL_LICENSE$ +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ ** ****************************************************************************/ diff --git a/src/xmlpatterns/schema/qxsdschematypesfactory_p.h b/src/xmlpatterns/schema/qxsdschematypesfactory_p.h index 4fcd5fb..874a701 100644 --- a/src/xmlpatterns/schema/qxsdschematypesfactory_p.h +++ b/src/xmlpatterns/schema/qxsdschematypesfactory_p.h @@ -3,9 +3,39 @@ ** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies). ** Contact: Qt Software Information (qt-info@nokia.com) ** -** This file is part of the $MODULE$ of the Qt Toolkit. +** This file is part of the QtXmlPatterns of the Qt Toolkit. ** -** $TROLLTECH_DUAL_LICENSE$ +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ ** ****************************************************************************/ diff --git a/src/xmlpatterns/schema/qxsdsimpletype.cpp b/src/xmlpatterns/schema/qxsdsimpletype.cpp index 2e5b7f5..0365e5e 100644 --- a/src/xmlpatterns/schema/qxsdsimpletype.cpp +++ b/src/xmlpatterns/schema/qxsdsimpletype.cpp @@ -3,9 +3,39 @@ ** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies). ** Contact: Qt Software Information (qt-info@nokia.com) ** -** This file is part of the $MODULE$ of the Qt Toolkit. +** This file is part of the QtXmlPatterns of the Qt Toolkit. ** -** $TROLLTECH_DUAL_LICENSE$ +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ ** ****************************************************************************/ diff --git a/src/xmlpatterns/schema/qxsdsimpletype_p.h b/src/xmlpatterns/schema/qxsdsimpletype_p.h index 9ba34b6..d9f84c7 100644 --- a/src/xmlpatterns/schema/qxsdsimpletype_p.h +++ b/src/xmlpatterns/schema/qxsdsimpletype_p.h @@ -3,9 +3,39 @@ ** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies). ** Contact: Qt Software Information (qt-info@nokia.com) ** -** This file is part of the $MODULE$ of the Qt Toolkit. +** This file is part of the QtXmlPatterns of the Qt Toolkit. ** -** $TROLLTECH_DUAL_LICENSE$ +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ ** ****************************************************************************/ diff --git a/src/xmlpatterns/schema/qxsdstatemachine.cpp b/src/xmlpatterns/schema/qxsdstatemachine.cpp index 4f36f22..0672e1a 100644 --- a/src/xmlpatterns/schema/qxsdstatemachine.cpp +++ b/src/xmlpatterns/schema/qxsdstatemachine.cpp @@ -3,9 +3,39 @@ ** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies). ** Contact: Qt Software Information (qt-info@nokia.com) ** -** This file is part of the $MODULE$ of the Qt Toolkit. +** This file is part of the QtXmlPatterns of the Qt Toolkit. ** -** $TROLLTECH_DUAL_LICENSE$ +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ ** ****************************************************************************/ diff --git a/src/xmlpatterns/schema/qxsdstatemachine_p.h b/src/xmlpatterns/schema/qxsdstatemachine_p.h index f0cf99d..81fb853 100644 --- a/src/xmlpatterns/schema/qxsdstatemachine_p.h +++ b/src/xmlpatterns/schema/qxsdstatemachine_p.h @@ -3,9 +3,39 @@ ** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies). ** Contact: Qt Software Information (qt-info@nokia.com) ** -** This file is part of the $MODULE$ of the Qt Toolkit. +** This file is part of the QtXmlPatterns of the Qt Toolkit. ** -** $TROLLTECH_DUAL_LICENSE$ +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ ** ****************************************************************************/ diff --git a/src/xmlpatterns/schema/qxsdstatemachinebuilder.cpp b/src/xmlpatterns/schema/qxsdstatemachinebuilder.cpp index 866e010..a9e1d98 100644 --- a/src/xmlpatterns/schema/qxsdstatemachinebuilder.cpp +++ b/src/xmlpatterns/schema/qxsdstatemachinebuilder.cpp @@ -3,9 +3,39 @@ ** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies). ** Contact: Qt Software Information (qt-info@nokia.com) ** -** This file is part of the $MODULE$ of the Qt Toolkit. +** This file is part of the QtXmlPatterns of the Qt Toolkit. ** -** $TROLLTECH_DUAL_LICENSE$ +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ ** ****************************************************************************/ diff --git a/src/xmlpatterns/schema/qxsdstatemachinebuilder_p.h b/src/xmlpatterns/schema/qxsdstatemachinebuilder_p.h index 011153a..82eeea8 100644 --- a/src/xmlpatterns/schema/qxsdstatemachinebuilder_p.h +++ b/src/xmlpatterns/schema/qxsdstatemachinebuilder_p.h @@ -3,9 +3,39 @@ ** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies). ** Contact: Qt Software Information (qt-info@nokia.com) ** -** This file is part of the $MODULE$ of the Qt Toolkit. +** This file is part of the QtXmlPatterns of the Qt Toolkit. ** -** $TROLLTECH_DUAL_LICENSE$ +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ ** ****************************************************************************/ diff --git a/src/xmlpatterns/schema/qxsdterm.cpp b/src/xmlpatterns/schema/qxsdterm.cpp index 1dbe34b..92ea006 100644 --- a/src/xmlpatterns/schema/qxsdterm.cpp +++ b/src/xmlpatterns/schema/qxsdterm.cpp @@ -3,9 +3,39 @@ ** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies). ** Contact: Qt Software Information (qt-info@nokia.com) ** -** This file is part of the $MODULE$ of the Qt Toolkit. +** This file is part of the QtXmlPatterns of the Qt Toolkit. ** -** $TROLLTECH_DUAL_LICENSE$ +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ ** ****************************************************************************/ diff --git a/src/xmlpatterns/schema/qxsdterm_p.h b/src/xmlpatterns/schema/qxsdterm_p.h index f45d791..278b74d 100644 --- a/src/xmlpatterns/schema/qxsdterm_p.h +++ b/src/xmlpatterns/schema/qxsdterm_p.h @@ -3,9 +3,39 @@ ** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies). ** Contact: Qt Software Information (qt-info@nokia.com) ** -** This file is part of the $MODULE$ of the Qt Toolkit. +** This file is part of the QtXmlPatterns of the Qt Toolkit. ** -** $TROLLTECH_DUAL_LICENSE$ +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ ** ****************************************************************************/ diff --git a/src/xmlpatterns/schema/qxsdtypechecker.cpp b/src/xmlpatterns/schema/qxsdtypechecker.cpp index ab971a9..aabfcf6 100644 --- a/src/xmlpatterns/schema/qxsdtypechecker.cpp +++ b/src/xmlpatterns/schema/qxsdtypechecker.cpp @@ -3,9 +3,39 @@ ** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies). ** Contact: Qt Software Information (qt-info@nokia.com) ** -** This file is part of the $MODULE$ of the Qt Toolkit. +** This file is part of the QtXmlPatterns of the Qt Toolkit. ** -** $TROLLTECH_DUAL_LICENSE$ +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ ** ****************************************************************************/ diff --git a/src/xmlpatterns/schema/qxsdtypechecker_p.h b/src/xmlpatterns/schema/qxsdtypechecker_p.h index 2af20db..4b3f7c2 100644 --- a/src/xmlpatterns/schema/qxsdtypechecker_p.h +++ b/src/xmlpatterns/schema/qxsdtypechecker_p.h @@ -3,9 +3,39 @@ ** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies). ** Contact: Qt Software Information (qt-info@nokia.com) ** -** This file is part of the $MODULE$ of the Qt Toolkit. +** This file is part of the QtXmlPatterns of the Qt Toolkit. ** -** $TROLLTECH_DUAL_LICENSE$ +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ ** ****************************************************************************/ diff --git a/src/xmlpatterns/schema/qxsduserschematype.cpp b/src/xmlpatterns/schema/qxsduserschematype.cpp index b8bf7e7..a985ba4 100644 --- a/src/xmlpatterns/schema/qxsduserschematype.cpp +++ b/src/xmlpatterns/schema/qxsduserschematype.cpp @@ -3,9 +3,39 @@ ** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies). ** Contact: Qt Software Information (qt-info@nokia.com) ** -** This file is part of the $MODULE$ of the Qt Toolkit. +** This file is part of the QtXmlPatterns of the Qt Toolkit. ** -** $TROLLTECH_DUAL_LICENSE$ +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ ** ****************************************************************************/ diff --git a/src/xmlpatterns/schema/qxsduserschematype_p.h b/src/xmlpatterns/schema/qxsduserschematype_p.h index ab70f91..842fb00 100644 --- a/src/xmlpatterns/schema/qxsduserschematype_p.h +++ b/src/xmlpatterns/schema/qxsduserschematype_p.h @@ -3,9 +3,39 @@ ** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies). ** Contact: Qt Software Information (qt-info@nokia.com) ** -** This file is part of the $MODULE$ of the Qt Toolkit. +** This file is part of the QtXmlPatterns of the Qt Toolkit. ** -** $TROLLTECH_DUAL_LICENSE$ +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ ** ****************************************************************************/ diff --git a/src/xmlpatterns/schema/qxsdvalidatedxmlnodemodel.cpp b/src/xmlpatterns/schema/qxsdvalidatedxmlnodemodel.cpp index 33bca4e..e7a1503 100644 --- a/src/xmlpatterns/schema/qxsdvalidatedxmlnodemodel.cpp +++ b/src/xmlpatterns/schema/qxsdvalidatedxmlnodemodel.cpp @@ -3,9 +3,39 @@ ** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies). ** Contact: Qt Software Information (qt-info@nokia.com) ** -** This file is part of the $MODULE$ of the Qt Toolkit. +** This file is part of the QtXmlPatterns of the Qt Toolkit. ** -** $TROLLTECH_DUAL_LICENSE$ +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ ** ****************************************************************************/ diff --git a/src/xmlpatterns/schema/qxsdvalidatedxmlnodemodel_p.h b/src/xmlpatterns/schema/qxsdvalidatedxmlnodemodel_p.h index d52e369..77fc8f4 100644 --- a/src/xmlpatterns/schema/qxsdvalidatedxmlnodemodel_p.h +++ b/src/xmlpatterns/schema/qxsdvalidatedxmlnodemodel_p.h @@ -3,9 +3,39 @@ ** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies). ** Contact: Qt Software Information (qt-info@nokia.com) ** -** This file is part of the $MODULE$ of the Qt Toolkit. +** This file is part of the QtXmlPatterns of the Qt Toolkit. ** -** $TROLLTECH_DUAL_LICENSE$ +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ ** ****************************************************************************/ diff --git a/src/xmlpatterns/schema/qxsdvalidatinginstancereader.cpp b/src/xmlpatterns/schema/qxsdvalidatinginstancereader.cpp index 8cb34d4..1505152 100644 --- a/src/xmlpatterns/schema/qxsdvalidatinginstancereader.cpp +++ b/src/xmlpatterns/schema/qxsdvalidatinginstancereader.cpp @@ -3,9 +3,39 @@ ** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies). ** Contact: Qt Software Information (qt-info@nokia.com) ** -** This file is part of the $MODULE$ of the Qt Toolkit. +** This file is part of the QtXmlPatterns of the Qt Toolkit. ** -** $TROLLTECH_DUAL_LICENSE$ +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ ** ****************************************************************************/ diff --git a/src/xmlpatterns/schema/qxsdvalidatinginstancereader_p.h b/src/xmlpatterns/schema/qxsdvalidatinginstancereader_p.h index 28f3c3f..0402e99 100644 --- a/src/xmlpatterns/schema/qxsdvalidatinginstancereader_p.h +++ b/src/xmlpatterns/schema/qxsdvalidatinginstancereader_p.h @@ -3,9 +3,39 @@ ** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies). ** Contact: Qt Software Information (qt-info@nokia.com) ** -** This file is part of the $MODULE$ of the Qt Toolkit. +** This file is part of the QtXmlPatterns of the Qt Toolkit. ** -** $TROLLTECH_DUAL_LICENSE$ +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ ** ****************************************************************************/ diff --git a/src/xmlpatterns/schema/qxsdwildcard.cpp b/src/xmlpatterns/schema/qxsdwildcard.cpp index 6efb996..55eb4ba 100644 --- a/src/xmlpatterns/schema/qxsdwildcard.cpp +++ b/src/xmlpatterns/schema/qxsdwildcard.cpp @@ -3,9 +3,39 @@ ** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies). ** Contact: Qt Software Information (qt-info@nokia.com) ** -** This file is part of the $MODULE$ of the Qt Toolkit. +** This file is part of the QtXmlPatterns of the Qt Toolkit. ** -** $TROLLTECH_DUAL_LICENSE$ +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ ** ****************************************************************************/ diff --git a/src/xmlpatterns/schema/qxsdwildcard_p.h b/src/xmlpatterns/schema/qxsdwildcard_p.h index 8fbecb3..15fc159 100644 --- a/src/xmlpatterns/schema/qxsdwildcard_p.h +++ b/src/xmlpatterns/schema/qxsdwildcard_p.h @@ -3,9 +3,39 @@ ** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies). ** Contact: Qt Software Information (qt-info@nokia.com) ** -** This file is part of the $MODULE$ of the Qt Toolkit. +** This file is part of the QtXmlPatterns of the Qt Toolkit. ** -** $TROLLTECH_DUAL_LICENSE$ +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ ** ****************************************************************************/ diff --git a/src/xmlpatterns/schema/qxsdxpathexpression.cpp b/src/xmlpatterns/schema/qxsdxpathexpression.cpp index ba9d0a4..64bd687 100644 --- a/src/xmlpatterns/schema/qxsdxpathexpression.cpp +++ b/src/xmlpatterns/schema/qxsdxpathexpression.cpp @@ -3,9 +3,39 @@ ** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies). ** Contact: Qt Software Information (qt-info@nokia.com) ** -** This file is part of the $MODULE$ of the Qt Toolkit. +** This file is part of the QtXmlPatterns of the Qt Toolkit. ** -** $TROLLTECH_DUAL_LICENSE$ +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ ** ****************************************************************************/ diff --git a/src/xmlpatterns/schema/qxsdxpathexpression_p.h b/src/xmlpatterns/schema/qxsdxpathexpression_p.h index e57f7b7..e4f5427 100644 --- a/src/xmlpatterns/schema/qxsdxpathexpression_p.h +++ b/src/xmlpatterns/schema/qxsdxpathexpression_p.h @@ -3,9 +3,39 @@ ** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies). ** Contact: Qt Software Information (qt-info@nokia.com) ** -** This file is part of the $MODULE$ of the Qt Toolkit. +** This file is part of the QtXmlPatterns of the Qt Toolkit. ** -** $TROLLTECH_DUAL_LICENSE$ +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ ** ****************************************************************************/ diff --git a/src/xmlpatterns/schema/tokens.xml b/src/xmlpatterns/schema/tokens.xml index 7ec9752..6736ad75 100644 --- a/src/xmlpatterns/schema/tokens.xml +++ b/src/xmlpatterns/schema/tokens.xml @@ -112,9 +112,39 @@ ** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies). ** Contact: Qt Software Information (qt-info@nokia.com) ** -** This file is part of the $MODULE$ of the Qt Toolkit. +** This file is part of the QtXmlPatterns of the Qt Toolkit. ** -** $TROLLTECH_DUAL_LICENSE$ +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ ** ****************************************************************************/ diff --git a/src/xmlpatterns/type/qnamedschemacomponent.cpp b/src/xmlpatterns/type/qnamedschemacomponent.cpp index e45b9b6..71b7519 100644 --- a/src/xmlpatterns/type/qnamedschemacomponent.cpp +++ b/src/xmlpatterns/type/qnamedschemacomponent.cpp @@ -3,9 +3,39 @@ ** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies). ** Contact: Qt Software Information (qt-info@nokia.com) ** -** This file is part of the $MODULE$ of the Qt Toolkit. +** This file is part of the QtXmlPatterns of the Qt Toolkit. ** -** $TROLLTECH_DUAL_LICENSE$ +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ ** ****************************************************************************/ diff --git a/src/xmlpatterns/type/qnamedschemacomponent_p.h b/src/xmlpatterns/type/qnamedschemacomponent_p.h index bc3121b..70da093 100644 --- a/src/xmlpatterns/type/qnamedschemacomponent_p.h +++ b/src/xmlpatterns/type/qnamedschemacomponent_p.h @@ -3,9 +3,39 @@ ** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies). ** Contact: Qt Software Information (qt-info@nokia.com) ** -** This file is part of the $MODULE$ of the Qt Toolkit. +** This file is part of the QtXmlPatterns of the Qt Toolkit. ** -** $TROLLTECH_DUAL_LICENSE$ +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ ** ****************************************************************************/ diff --git a/tools/xmlpatternsvalidator/main.cpp b/tools/xmlpatternsvalidator/main.cpp index 0ccbcfc..d53c783 100644 --- a/tools/xmlpatternsvalidator/main.cpp +++ b/tools/xmlpatternsvalidator/main.cpp @@ -5,7 +5,37 @@ ** ** This file is part of the Patternist project on Trolltech Labs. ** -** $TROLLTECH_DUAL_LICENSE$ +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ ** ****************************************************************************/ diff --git a/tools/xmlpatternsvalidator/main.h b/tools/xmlpatternsvalidator/main.h index 477a45a..85a4561 100644 --- a/tools/xmlpatternsvalidator/main.h +++ b/tools/xmlpatternsvalidator/main.h @@ -4,7 +4,37 @@ ** Contact: Qt Software Information (qt-info@nokia.com) ** ** This file is part of the Patternist project on Trolltech Labs. * ** - ** $TROLLTECH_DUAL_LICENSE$ + ** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ ** ** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE ** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. -- cgit v0.12 From fa26e5759c645c9ed9c81a86dba72881dd1d776c Mon Sep 17 00:00:00 2001 From: Tobias Koenig Date: Tue, 19 May 2009 16:17:18 +0200 Subject: Add missing example files --- examples/xmlpatterns/schema/files/contact.xsd | 25 ++++++++++++++ .../xmlpatterns/schema/files/invalid_contact.xml | 11 ++++++ .../xmlpatterns/schema/files/invalid_order.xml | 13 +++++++ .../xmlpatterns/schema/files/invalid_recipe.xml | 14 ++++++++ examples/xmlpatterns/schema/files/order.xsd | 23 +++++++++++++ examples/xmlpatterns/schema/files/recipe.xsd | 40 ++++++++++++++++++++++ .../xmlpatterns/schema/files/valid_contact.xml | 11 ++++++ examples/xmlpatterns/schema/files/valid_order.xml | 18 ++++++++++ examples/xmlpatterns/schema/files/valid_recipe.xml | 13 +++++++ 9 files changed, 168 insertions(+) create mode 100644 examples/xmlpatterns/schema/files/contact.xsd create mode 100644 examples/xmlpatterns/schema/files/invalid_contact.xml create mode 100644 examples/xmlpatterns/schema/files/invalid_order.xml create mode 100644 examples/xmlpatterns/schema/files/invalid_recipe.xml create mode 100644 examples/xmlpatterns/schema/files/order.xsd create mode 100644 examples/xmlpatterns/schema/files/recipe.xsd create mode 100644 examples/xmlpatterns/schema/files/valid_contact.xml create mode 100644 examples/xmlpatterns/schema/files/valid_order.xml create mode 100644 examples/xmlpatterns/schema/files/valid_recipe.xml diff --git a/examples/xmlpatterns/schema/files/contact.xsd b/examples/xmlpatterns/schema/files/contact.xsd new file mode 100644 index 0000000..3e1b570 --- /dev/null +++ b/examples/xmlpatterns/schema/files/contact.xsd @@ -0,0 +1,25 @@ + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/examples/xmlpatterns/schema/files/invalid_contact.xml b/examples/xmlpatterns/schema/files/invalid_contact.xml new file mode 100644 index 0000000..42f1edd --- /dev/null +++ b/examples/xmlpatterns/schema/files/invalid_contact.xml @@ -0,0 +1,11 @@ + + John + Doe + Prof. + + Sandakerveien 116 + N-0550 + Oslo + Norway + + diff --git a/examples/xmlpatterns/schema/files/invalid_order.xml b/examples/xmlpatterns/schema/files/invalid_order.xml new file mode 100644 index 0000000..8ffc5fd --- /dev/null +++ b/examples/xmlpatterns/schema/files/invalid_order.xml @@ -0,0 +1,13 @@ + + 234219 +
+ 21692 + 3 +
+
+ 24749 + 9 +
+ 2009-01-23 + yes +
diff --git a/examples/xmlpatterns/schema/files/invalid_recipe.xml b/examples/xmlpatterns/schema/files/invalid_recipe.xml new file mode 100644 index 0000000..4d75af6 --- /dev/null +++ b/examples/xmlpatterns/schema/files/invalid_recipe.xml @@ -0,0 +1,14 @@ + + Cheese on Toast + + + diff --git a/examples/xmlpatterns/schema/files/order.xsd b/examples/xmlpatterns/schema/files/order.xsd new file mode 100644 index 0000000..405cafe --- /dev/null +++ b/examples/xmlpatterns/schema/files/order.xsd @@ -0,0 +1,23 @@ + + + + + + + + + + + + + + + + + + + + + + + diff --git a/examples/xmlpatterns/schema/files/recipe.xsd b/examples/xmlpatterns/schema/files/recipe.xsd new file mode 100644 index 0000000..bbbafd9 --- /dev/null +++ b/examples/xmlpatterns/schema/files/recipe.xsd @@ -0,0 +1,40 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/examples/xmlpatterns/schema/files/valid_contact.xml b/examples/xmlpatterns/schema/files/valid_contact.xml new file mode 100644 index 0000000..53c04d4 --- /dev/null +++ b/examples/xmlpatterns/schema/files/valid_contact.xml @@ -0,0 +1,11 @@ + + John + Doe + 1977-12-25 + + Sandakerveien 116 + N-0550 + Oslo + Norway + + diff --git a/examples/xmlpatterns/schema/files/valid_order.xml b/examples/xmlpatterns/schema/files/valid_order.xml new file mode 100644 index 0000000..f83c36c --- /dev/null +++ b/examples/xmlpatterns/schema/files/valid_order.xml @@ -0,0 +1,18 @@ + + 194223 +
+ 22242 + 5 +
+
+ 32372 + 12 + without stripes +
+
+ 23649 + 2 +
+ 2009-01-23 + true +
diff --git a/examples/xmlpatterns/schema/files/valid_recipe.xml b/examples/xmlpatterns/schema/files/valid_recipe.xml new file mode 100644 index 0000000..f6499ba --- /dev/null +++ b/examples/xmlpatterns/schema/files/valid_recipe.xml @@ -0,0 +1,13 @@ + + Cheese on Toast + + + -- cgit v0.12 From adad01b142a0839a9c6e59275844f0c38924c25d Mon Sep 17 00:00:00 2001 From: Tobias Koenig Date: Tue, 19 May 2009 16:18:07 +0200 Subject: Remove unneeded qDebug statement --- src/xmlpatterns/schema/qxsdschemaparser.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/src/xmlpatterns/schema/qxsdschemaparser.cpp b/src/xmlpatterns/schema/qxsdschemaparser.cpp index cabc12e..3cd21af 100644 --- a/src/xmlpatterns/schema/qxsdschemaparser.cpp +++ b/src/xmlpatterns/schema/qxsdschemaparser.cpp @@ -251,7 +251,6 @@ void XsdSchemaParser::setTargetNamespaceExtended(const QString &targetNamespace) void XsdSchemaParser::setDocumentURI(const QUrl &uri) { - qDebug("%s", qPrintable(uri.toString())); m_documentURI = uri; // prevent to get included/imported/redefined twice -- cgit v0.12 From 317ab44d0c99fbc8b0a9f4136a107ad5d17e4539 Mon Sep 17 00:00:00 2001 From: Tobias Koenig Date: Tue, 19 May 2009 18:24:22 +0200 Subject: Extend auto tests for namepool checks --- tests/auto/qxmlschema/tst_qxmlschema.cpp | 4 ++ .../tst_qxmlschemavalidator.cpp | 62 ++++++++++++++++++++++ 2 files changed, 66 insertions(+) diff --git a/tests/auto/qxmlschema/tst_qxmlschema.cpp b/tests/auto/qxmlschema/tst_qxmlschema.cpp index 7fc59bb..33978e8 100644 --- a/tests/auto/qxmlschema/tst_qxmlschema.cpp +++ b/tests/auto/qxmlschema/tst_qxmlschema.cpp @@ -118,6 +118,10 @@ void tst_QXmlSchema::constructorQXmlNamePool() const QCOMPARE(name.namespaceUri(np2), QString::fromLatin1("http://example.com/")); QCOMPARE(name.localName(np2), QString::fromLatin1("localName")); QCOMPARE(name.prefix(np2), QString::fromLatin1("prefix")); + + // make sure namePool() is const + const QXmlSchema constSchema; + np = constSchema.namePool(); } void tst_QXmlSchema::copyMutationTest() const diff --git a/tests/auto/qxmlschemavalidator/tst_qxmlschemavalidator.cpp b/tests/auto/qxmlschemavalidator/tst_qxmlschemavalidator.cpp index 3bbf506..0f15bc8 100644 --- a/tests/auto/qxmlschemavalidator/tst_qxmlschemavalidator.cpp +++ b/tests/auto/qxmlschemavalidator/tst_qxmlschemavalidator.cpp @@ -33,7 +33,9 @@ class tst_QXmlSchemaValidator : public QObject private Q_SLOTS: void defaultConstructor() const; + void constructorQXmlNamePool() const; void propertyInitialization() const; + void resetSchemaNamePool() const; void loadInstanceUrlSuccess() const; void loadInstanceUrlFail() const; @@ -119,6 +121,66 @@ void tst_QXmlSchemaValidator::propertyInitialization() const } } +void tst_QXmlSchemaValidator::constructorQXmlNamePool() const +{ + // test that the name pool from the schema is used by + // the schema validator as well + QXmlSchema schema; + + QXmlNamePool np = schema.namePool(); + + const QXmlName name(np, QLatin1String("localName"), + QLatin1String("http://example.com/"), + QLatin1String("prefix")); + + QXmlSchemaValidator validator(schema); + + QXmlNamePool np2(validator.namePool()); + QCOMPARE(name.namespaceUri(np2), QString::fromLatin1("http://example.com/")); + QCOMPARE(name.localName(np2), QString::fromLatin1("localName")); + QCOMPARE(name.prefix(np2), QString::fromLatin1("prefix")); + + // make sure namePool() is const + const QXmlSchemaValidator constValidator(schema); + np = constValidator.namePool(); +} + +void tst_QXmlSchemaValidator::resetSchemaNamePool() const +{ + QXmlSchema schema1; + QXmlNamePool np1 = schema1.namePool(); + + const QXmlName name1(np1, QLatin1String("localName"), + QLatin1String("http://example.com/"), + QLatin1String("prefix")); + + QXmlSchemaValidator validator(schema1); + + { + QXmlNamePool compNamePool(validator.namePool()); + QCOMPARE(name1.namespaceUri(compNamePool), QString::fromLatin1("http://example.com/")); + QCOMPARE(name1.localName(compNamePool), QString::fromLatin1("localName")); + QCOMPARE(name1.prefix(compNamePool), QString::fromLatin1("prefix")); + } + + QXmlSchema schema2; + QXmlNamePool np2 = schema2.namePool(); + + const QXmlName name2(np2, QLatin1String("remoteName"), + QLatin1String("http://trolltech.com/"), + QLatin1String("suffix")); + + // make sure that after re-setting the schema, the new namepool is used + validator.setSchema(schema2); + + { + QXmlNamePool compNamePool(validator.namePool()); + QCOMPARE(name2.namespaceUri(compNamePool), QString::fromLatin1("http://trolltech.com/")); + QCOMPARE(name2.localName(compNamePool), QString::fromLatin1("remoteName")); + QCOMPARE(name2.prefix(compNamePool), QString::fromLatin1("suffix")); + } +} + void tst_QXmlSchemaValidator::loadInstanceUrlSuccess() const { /* -- cgit v0.12 From ab5833178307fa9370868f61ff4cc7b18eb51fc0 Mon Sep 17 00:00:00 2001 From: Tobias Koenig Date: Tue, 19 May 2009 18:59:30 +0200 Subject: Forward errors from QXmlStreamReader to XsdSchemaParser (missed this commit on the first merge, autotest works again) --- src/xmlpatterns/schema/qxsdschemaparser.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/xmlpatterns/schema/qxsdschemaparser.cpp b/src/xmlpatterns/schema/qxsdschemaparser.cpp index 3cd21af..b74964d 100644 --- a/src/xmlpatterns/schema/qxsdschemaparser.cpp +++ b/src/xmlpatterns/schema/qxsdschemaparser.cpp @@ -290,6 +290,9 @@ bool XsdSchemaParser::parse(ParserType parserType) m_schemaResolver->addComponentLocationHash(m_componentLocationHash); m_schemaResolver->setDefaultOpenContent(m_defaultOpenContent, m_defaultOpenContentAppliesToEmpty); + if (QXmlStreamReader::error() != QXmlStreamReader::NoError) + error(errorString()); + return true; } -- cgit v0.12 From 9519f3ee67c8ab2de8d1ab5e584f8d3adb8875bd Mon Sep 17 00:00:00 2001 From: Tobias Koenig Date: Tue, 19 May 2009 20:04:10 +0200 Subject: Document xml schema enum in QRegExp --- src/corelib/tools/qregexp.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/corelib/tools/qregexp.cpp b/src/corelib/tools/qregexp.cpp index f69a99f..664dfc0 100644 --- a/src/corelib/tools/qregexp.cpp +++ b/src/corelib/tools/qregexp.cpp @@ -3700,6 +3700,9 @@ static void invalidateEngine(QRegExpPrivate *priv) equivalent to using the RegExp pattern on a string in which all metacharacters are escaped using escape(). + \value W3CXmlSchema11 The pattern is a regular expression as + defined by the W3C XML Schema 1.1 specification. + \sa setPatternSyntax() */ -- cgit v0.12 From f66a475a236649c94a47f668ba3461bdc325c308 Mon Sep 17 00:00:00 2001 From: Tobias Koenig Date: Tue, 19 May 2009 20:09:09 +0200 Subject: First version of documentation for schema example --- doc/src/examples.qdoc | 1 + doc/src/examples/schema.qdoc | 58 +++++++++++++++++++++++++++++ doc/src/images/schema-example.png | Bin 0 -> 84320 bytes examples/xmlpatterns/schema/mainwindow.cpp | 19 ++++++---- examples/xmlpatterns/schema/schema.ui | 2 +- src/xmlpatterns/api/qxmlschema.cpp | 10 +++++ 6 files changed, 81 insertions(+), 9 deletions(-) create mode 100644 doc/src/examples/schema.qdoc create mode 100644 doc/src/images/schema-example.png diff --git a/doc/src/examples.qdoc b/doc/src/examples.qdoc index 29c6c0b..a0e9b23 100644 --- a/doc/src/examples.qdoc +++ b/doc/src/examples.qdoc @@ -398,6 +398,7 @@ \o \l{xmlpatterns/qobjectxmlmodel}{QObject XML Model Example} \o \l{xmlpatterns/xquery/globalVariables}{C++ Source Code Analyzer Example} \o \l{xmlpatterns/trafficinfo}{Traffic Info}\raisedaster + \o \l{xmlpatterns/schema}{XML Schema Validation}\raisedaster \endlist \section1 Inter-Process Communication diff --git a/doc/src/examples/schema.qdoc b/doc/src/examples/schema.qdoc new file mode 100644 index 0000000..2287796 --- /dev/null +++ b/doc/src/examples/schema.qdoc @@ -0,0 +1,58 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/*! + \example xmlpatterns/schema + \title XML Schema Validation Example + + This example shows how to use QtXmlPatterns to validate XML with + a W3C XML Schema. + + \section1 Introduction + + The example application shows different XML schema definitions and + for every definition two XML instance documents, one that is valid + according to the schema and one that is not. + The user can select the valid or invalid instance document, change + it and validate it again. + + \image schema-example.png +*/ diff --git a/doc/src/images/schema-example.png b/doc/src/images/schema-example.png new file mode 100644 index 0000000..5e95bf5 Binary files /dev/null and b/doc/src/images/schema-example.png differ diff --git a/examples/xmlpatterns/schema/mainwindow.cpp b/examples/xmlpatterns/schema/mainwindow.cpp index 6b43d7b..98276a3 100644 --- a/examples/xmlpatterns/schema/mainwindow.cpp +++ b/examples/xmlpatterns/schema/mainwindow.cpp @@ -69,7 +69,8 @@ class MessageHandler : public QAbstractMessageHandler } protected: - virtual void handleMessage(QtMsgType type, const QString &description, const QUrl &identifier, const QSourceLocation &sourceLocation) + virtual void handleMessage(QtMsgType type, const QString &description, + const QUrl &identifier, const QSourceLocation &sourceLocation) { Q_UNUSED(type); Q_UNUSED(identifier); @@ -127,7 +128,7 @@ void MainWindow::schemaSelected(int index) QFile schemaFile(QString(":/schema_%1.xsd").arg(index)); schemaFile.open(QIODevice::ReadOnly); - const QString schemaText(QString::fromLatin1(schemaFile.readAll())); + const QString schemaText(QString::fromUtf8(schemaFile.readAll())); schemaView->setPlainText(schemaText); validate(); @@ -137,7 +138,7 @@ void MainWindow::instanceSelected(int index) { QFile instanceFile(QString(":/instance_%1.xml").arg((2*schemaSelection->currentIndex()) + index)); instanceFile.open(QIODevice::ReadOnly); - const QString instanceText(QString::fromLatin1(instanceFile.readAll())); + const QString instanceText(QString::fromUtf8(instanceFile.readAll())); instanceEdit->setPlainText(instanceText); validate(); @@ -145,22 +146,22 @@ void MainWindow::instanceSelected(int index) void MainWindow::validate() { - const QByteArray schemaData = schemaView->toPlainText().toLatin1(); - const QByteArray instanceData = instanceEdit->toPlainText().toLatin1(); + const QByteArray schemaData = schemaView->toPlainText().toUtf8(); + const QByteArray instanceData = instanceEdit->toPlainText().toUtf8(); MessageHandler messageHandler; QXmlSchema schema; schema.setMessageHandler(&messageHandler); - schema.load(schemaData, QUrl("http://dummySchemaUrl/")); + schema.load(schemaData); bool errorOccurred = false; if (!schema.isValid()) { errorOccurred = true; } else { QXmlSchemaValidator validator(schema); - if (!validator.validate(instanceData, QUrl("http://dummyInstanceUrl"))) + if (!validator.validate(instanceData)) errorOccurred = true; } @@ -171,7 +172,9 @@ void MainWindow::validate() validationStatus->setText(tr("validation successful")); } - QString styleSheet = QString("QLabel {background: %1; padding: 3px}").arg(errorOccurred ? QColor(Qt::red).lighter(160).name() : QColor(Qt::green).lighter(160).name()); + const QString styleSheet = QString("QLabel {background: %1; padding: 3px}") + .arg(errorOccurred ? QColor(Qt::red).lighter(160).name() : + QColor(Qt::green).lighter(160).name()); validationStatus->setStyleSheet(styleSheet); } diff --git a/examples/xmlpatterns/schema/schema.ui b/examples/xmlpatterns/schema/schema.ui index af7020a..b67f444 100644 --- a/examples/xmlpatterns/schema/schema.ui +++ b/examples/xmlpatterns/schema/schema.ui @@ -11,7 +11,7 @@ - MainWindow + XML Schema Validation diff --git a/src/xmlpatterns/api/qxmlschema.cpp b/src/xmlpatterns/api/qxmlschema.cpp index aa5b77c..8e14f3f 100644 --- a/src/xmlpatterns/api/qxmlschema.cpp +++ b/src/xmlpatterns/api/qxmlschema.cpp @@ -88,6 +88,9 @@ QXmlSchema::~QXmlSchema() /*! Sets this QXmlSchema to a schema loaded from the \a source URI. + + If the schema \l {isValid()} {is invalid}, \c{false} is returned + and the behavior is undefined. */ bool QXmlSchema::load(const QUrl &source) { @@ -107,6 +110,10 @@ bool QXmlSchema::load(const QUrl &source) If \a source is \c null or not readable, or if \a documentUri is not a valid URI, behavior is undefined. + + If the schema \l {isValid()} {is invalid}, \c{false} is returned + and the behavior is undefined. + \sa isValid() */ bool QXmlSchema::load(QIODevice *source, const QUrl &documentUri) @@ -125,6 +132,9 @@ bool QXmlSchema::load(QIODevice *source, const QUrl &documentUri) If \a documentUri is not a valid URI, behavior is undefined. \sa isValid() + + If the schema \l {isValid()} {is invalid}, \c{false} is returned + and the behavior is undefined. */ bool QXmlSchema::load(const QByteArray &data, const QUrl &documentUri) { -- cgit v0.12 From 676d97d56a96c46cd9b9a2d6ba5d5f535f974d42 Mon Sep 17 00:00:00 2001 From: Tobias Koenig Date: Wed, 20 May 2009 21:11:14 +0200 Subject: Complete documentation of schema example and reference it from api docs --- doc/src/examples/schema.qdoc | 85 +++++++++++++++++++++++++++++ examples/xmlpatterns/schema/mainwindow.cpp | 10 ++++ src/xmlpatterns/api/qxmlschema.cpp | 2 + src/xmlpatterns/api/qxmlschemavalidator.cpp | 2 + 4 files changed, 99 insertions(+) diff --git a/doc/src/examples/schema.qdoc b/doc/src/examples/schema.qdoc index 2287796..80d158b 100644 --- a/doc/src/examples/schema.qdoc +++ b/doc/src/examples/schema.qdoc @@ -46,6 +46,8 @@ This example shows how to use QtXmlPatterns to validate XML with a W3C XML Schema. + \tableofcontents + \section1 Introduction The example application shows different XML schema definitions and @@ -54,5 +56,88 @@ The user can select the valid or invalid instance document, change it and validate it again. + \section2 The User Interface + + The UI for this example was created using \l{Qt Designer Manual} {Qt + Designer}: + \image schema-example.png + + The UI consists of three parts, at the top the XML schema \l{QComboBox} {selection} + and the schema \l{QTextBrowser} {viewer}, below the XML instance \l{QComboBox} {selection} + and the instance \l{QTextEdit} {editor} and at the bottom the validation status \l{QLabel} {label} + next to the validation \l{QPushButton} {button}. + + \section2 Validating XML Instance Documents + + You can select one of the three predefined XML schemas and for each schema + an valid or invalid instance document. A click on the 'Validate' button will + validate the content of the XML instance editor against the schema from the + XML schema viewer. As you can modify the content of the instance editor, different + instances can be tested and validation error messages analysed. + + \section1 Code Walk-Through + + The example's main() function creates the standard instance of + QApplication. Then it creates an instance of the mainwindow class, shows it, + and starts the Qt event loop: + + \snippet examples/xmlpatterns/schema/main.cpp 0 + + \section2 The UI Class: MainWindow + + The example's UI is a conventional Qt GUI application inheriting + QMainWindow and the class generated by \l{Qt Designer Manual} {Qt + Designer}: + + \snippet examples/xmlpatterns/schema/mainwindow.h 0 + + The constructor fills the schema and instance \l{QComboBox} selections with the predefined + schemas and instances and connects their \l{QComboBox::currentIndexChanged()} {currentIndexChanged()} + signals to the window's \c{schemaSelected()} resp. \c{instanceSelected()} slot. + Furthermore the signal-slot connections for the validation \l{QPushButton} {button} + and the instance \l{QTextEdit} {editor} are set up. + + The call to \c{schemaSelected(0)} and \c{instanceSelected(0)} will trigger the validation + of the initial Contact Schema example. + + \snippet examples/xmlpatterns/schema/mainwindow.cpp 0 + + In the \c{schemaSelected()} slot the content of the instance \l{QComboBox} {selection} + is adapted to the selected schema and the corresponding schema is loaded from the + \l{The Qt Resource System} {resource file} and displayed in the schema \l{QTextBrowser} {viewer}. + At the end of the method a revalidation is triggered. + + \snippet examples/xmlpatterns/schema/mainwindow.cpp 1 + + In the \c{instanceSelected()} slot the selected instance is loaded from the + \l{The Qt Resource System} {resource file} and loaded into the instance \l{QTextEdit} {editor} + an the revalidation is triggered again. + + \snippet examples/xmlpatterns/schema/mainwindow.cpp 2 + + The \c{validate()} slot does the actual work in this example. + At first it stores the content of the schema \l{QTextBrowser} {viewer} and the + \l{QTextEdit} {editor} into temporary \l{QByteArray} {variables}. + Then it instanciates a \c{MessageHandler} object which inherits from + \l{QAbstractMessageHandler} {QAbstractMessageHandler} and is a convenience + class to store error messages from the XmlPatterns system. + + \snippet examples/xmlpatterns/schema/mainwindow.cpp 4 + + After the \l{QXmlSchema} {QXmlSchema} is instanciated and the message handler set + on it, the \l{QXmlSchema::load()} {load()} method is called with the schema data as argument. + If the schema is invalid or a parsing error has occured, \l{QXmlSchema::isValid()} {isValid()} + returns \c{false} and the error is flagged in \c{errorOccurred}. + If the loading was successful, a \l{QXmlSchemaValidator} {QXmlSchemaValidator} is + instanciated and the schema passed in the constructor. + A call to \l{QXmlSchemaValidator::validate()} {validate()} will validate the passed + XML instance data against the XML schema. The return value of that method signals + whether the validation was successful. + Depending on the success the status \l{QLabel} {label} is set to 'validation successful' + or the error message stored in the \c{MessageHandler} + + The rest of the code does only some fancy coloring and eyecandy. + + \snippet examples/xmlpatterns/schema/mainwindow.cpp 3 */ diff --git a/examples/xmlpatterns/schema/mainwindow.cpp b/examples/xmlpatterns/schema/mainwindow.cpp index 98276a3..bee7407 100644 --- a/examples/xmlpatterns/schema/mainwindow.cpp +++ b/examples/xmlpatterns/schema/mainwindow.cpp @@ -45,6 +45,7 @@ #include "mainwindow.h" #include "xmlsyntaxhighlighter.h" +//! [4] class MessageHandler : public QAbstractMessageHandler { public: @@ -85,7 +86,9 @@ class MessageHandler : public QAbstractMessageHandler QString m_description; QSourceLocation m_sourceLocation; }; +//! [4] +//! [0] MainWindow::MainWindow() { setupUi(this); @@ -110,7 +113,9 @@ MainWindow::MainWindow() schemaSelected(0); instanceSelected(0); } +//! [0] +//! [1] void MainWindow::schemaSelected(int index) { instanceSelection->clear(); @@ -133,7 +138,9 @@ void MainWindow::schemaSelected(int index) validate(); } +//! [1] +//! [2] void MainWindow::instanceSelected(int index) { QFile instanceFile(QString(":/instance_%1.xml").arg((2*schemaSelection->currentIndex()) + index)); @@ -143,7 +150,9 @@ void MainWindow::instanceSelected(int index) validate(); } +//! [2] +//! [3] void MainWindow::validate() { const QByteArray schemaData = schemaView->toPlainText().toUtf8(); @@ -177,6 +186,7 @@ void MainWindow::validate() QColor(Qt::green).lighter(160).name()); validationStatus->setStyleSheet(styleSheet); } +//! [3] void MainWindow::textChanged() { diff --git a/src/xmlpatterns/api/qxmlschema.cpp b/src/xmlpatterns/api/qxmlschema.cpp index 8e14f3f..62b6a0e 100644 --- a/src/xmlpatterns/api/qxmlschema.cpp +++ b/src/xmlpatterns/api/qxmlschema.cpp @@ -57,6 +57,8 @@ The QXmlSchema class loads, compiles and validates W3C XML Schema files that can be used further for validation of XML instance documents via \l{QXmlSchemaValidator}. + + \sa QXmlSchemaValidator, {xmlpatterns/schema}{XML Schema Validation Example} */ /*! diff --git a/src/xmlpatterns/api/qxmlschemavalidator.cpp b/src/xmlpatterns/api/qxmlschemavalidator.cpp index 7a4ce03..a69b081 100644 --- a/src/xmlpatterns/api/qxmlschemavalidator.cpp +++ b/src/xmlpatterns/api/qxmlschemavalidator.cpp @@ -62,6 +62,8 @@ The QXmlSchemaValidator class loads, parses an XML instance document and validates it against a W3C XML Schema that has been compiled with \l{QXmlSchema}. + + \sa QXmlSchema, {xmlpatterns/schema}{XML Schema Validation Example} */ /*! -- cgit v0.12 From be0285b193d23fcf28ad84a73895ad15ece18e4c Mon Sep 17 00:00:00 2001 From: Tobias Koenig Date: Thu, 21 May 2009 12:25:00 +0200 Subject: Added code snippets for QXmlSchema and referenced them from api docs --- doc/src/snippets/qxmlschema/main.cpp | 118 +++++++++++++++++++++++++++++ doc/src/snippets/qxmlschema/qxmlschema.pro | 3 + doc/src/snippets/snippets.pro | 1 + src/xmlpatterns/api/qxmlschema.cpp | 16 ++++ 4 files changed, 138 insertions(+) create mode 100644 doc/src/snippets/qxmlschema/main.cpp create mode 100644 doc/src/snippets/qxmlschema/qxmlschema.pro diff --git a/doc/src/snippets/qxmlschema/main.cpp b/doc/src/snippets/qxmlschema/main.cpp new file mode 100644 index 0000000..9e72f40 --- /dev/null +++ b/doc/src/snippets/qxmlschema/main.cpp @@ -0,0 +1,118 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include +#include + +class Schema +{ + public: + void loadFromUrl() const; + void loadFromFile() const; + void loadFromData() const; +}; + +void Schema::loadFromUrl() const +{ +//! [0] + QUrl url("http://www.schema-example.org/myschema.xsd"); + + QXmlSchema schema; + if (schema.load(url) == true) + qDebug() << "schema is valid"; + else + qDebug() << "schema is invalid"; +//! [0] +} + +void Schema::loadFromFile() const +{ +//! [1] + QFile file("myschema.xsd"); + file.open(QIODevice::ReadOnly); + + QXmlSchema schema; + schema.load(&file, QUrl::fromLocalFile(file.fileName())); + + if (schema.isValid()) + qDebug() << "schema is valid"; + else + qDebug() << "schema is invalid"; +//! [1] +} + +void Schema::loadFromData() const +{ +//! [2] + QByteArray data( "" + "" + "" ); + + QBuffer buffer(&data); + buffer.open(QIODevice::ReadOnly); + + QXmlSchema schema; + schema.load(&buffer); + + if (schema.isValid()) + qDebug() << "schema is valid"; + else + qDebug() << "schema is invalid"; +//! [2] +} + +int main(int argc, char **argv) +{ + QCoreApplication app(argc, argv); + + Schema schema; + + schema.loadFromUrl(); + schema.loadFromFile(); + schema.loadFromData(); + + return 0; +} diff --git a/doc/src/snippets/qxmlschema/qxmlschema.pro b/doc/src/snippets/qxmlschema/qxmlschema.pro new file mode 100644 index 0000000..7e8782a --- /dev/null +++ b/doc/src/snippets/qxmlschema/qxmlschema.pro @@ -0,0 +1,3 @@ +SOURCES += main.cpp + +QT += xmlpatterns diff --git a/doc/src/snippets/snippets.pro b/doc/src/snippets/snippets.pro index 50e33b3..e7219a6 100644 --- a/doc/src/snippets/snippets.pro +++ b/doc/src/snippets/snippets.pro @@ -73,6 +73,7 @@ SUBDIRS = brush \ quiloader \ qx11embedcontainer \ qx11embedwidget \ + qxmlschema \ reading-selections \ scribe-overview \ separations \ diff --git a/src/xmlpatterns/api/qxmlschema.cpp b/src/xmlpatterns/api/qxmlschema.cpp index 62b6a0e..ec370ca 100644 --- a/src/xmlpatterns/api/qxmlschema.cpp +++ b/src/xmlpatterns/api/qxmlschema.cpp @@ -93,6 +93,12 @@ QXmlSchema::~QXmlSchema() If the schema \l {isValid()} {is invalid}, \c{false} is returned and the behavior is undefined. + + Example: + + \snippet doc/src/snippets/qxmlschema/main.cpp 0 + + \sa isValid() */ bool QXmlSchema::load(const QUrl &source) { @@ -116,6 +122,10 @@ bool QXmlSchema::load(const QUrl &source) If the schema \l {isValid()} {is invalid}, \c{false} is returned and the behavior is undefined. + Example: + + \snippet doc/src/snippets/qxmlschema/main.cpp 1 + \sa isValid() */ bool QXmlSchema::load(QIODevice *source, const QUrl &documentUri) @@ -137,6 +147,12 @@ bool QXmlSchema::load(QIODevice *source, const QUrl &documentUri) If the schema \l {isValid()} {is invalid}, \c{false} is returned and the behavior is undefined. + + Example: + + \snippet doc/src/snippets/qxmlschema/main.cpp 2 + + \sa isValid() */ bool QXmlSchema::load(const QByteArray &data, const QUrl &documentUri) { -- cgit v0.12 From b24611f14453e6b870e25bdc3edcd4f6447ae87e Mon Sep 17 00:00:00 2001 From: Tobias Koenig Date: Thu, 21 May 2009 15:16:40 +0200 Subject: Added code snippets for QXmlSchemaValidator and referenced them from api docs --- doc/src/snippets/qxmlschemavalidator/main.cpp | 137 +++++++++++++++++++++ .../qxmlschemavalidator/qxmlschemavalidator.pro | 3 + doc/src/snippets/snippets.pro | 1 + src/xmlpatterns/api/qxmlschemavalidator.cpp | 12 ++ 4 files changed, 153 insertions(+) create mode 100644 doc/src/snippets/qxmlschemavalidator/main.cpp create mode 100644 doc/src/snippets/qxmlschemavalidator/qxmlschemavalidator.pro diff --git a/doc/src/snippets/qxmlschemavalidator/main.cpp b/doc/src/snippets/qxmlschemavalidator/main.cpp new file mode 100644 index 0000000..13cd45f --- /dev/null +++ b/doc/src/snippets/qxmlschemavalidator/main.cpp @@ -0,0 +1,137 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include +#include + +class SchemaValidator +{ + public: + void validateFromUrl() const; + void validateFromFile() const; + void validateFromData() const; + + private: + QXmlSchema getSchema() const; +}; + +void SchemaValidator::validateFromUrl() const +{ +//! [0] + const QXmlSchema schema = getSchema(); + + const QUrl url("http://www.schema-example.org/test.xml"); + + QXmlSchemaValidator validator(schema); + if (validator.validate(url)) + qDebug() << "instance document is valid"; + else + qDebug() << "instance document is invalid"; +//! [0] +} + +void SchemaValidator::validateFromFile() const +{ +//! [1] + const QXmlSchema schema = getSchema(); + + QFile file("test.xml"); + file.open(QIODevice::ReadOnly); + + QXmlSchemaValidator validator(schema); + if (validator.validate(&file, QUrl::fromLocalFile(file.fileName()))) + qDebug() << "instance document is valid"; + else + qDebug() << "instance document is invalid"; +//! [1] +} + +void SchemaValidator::validateFromData() const +{ +//! [2] + const QXmlSchema schema = getSchema(); + + QByteArray data("" + ""); + + QBuffer buffer(&data); + buffer.open(QIODevice::ReadOnly); + + QXmlSchemaValidator validator(schema); + if (validator.validate(&buffer)) + qDebug() << "instance document is valid"; + else + qDebug() << "instance document is invalid"; +//! [2] +} + +QXmlSchema SchemaValidator::getSchema() const +{ + QByteArray data("" + "" + ""); + + QBuffer buffer(&data); + buffer.open(QIODevice::ReadOnly); + + QXmlSchema schema; + schema.load(&buffer); + + return schema; +} + +int main(int argc, char **argv) +{ + QCoreApplication app(argc, argv); + + SchemaValidator validator; + + validator.validateFromUrl(); + validator.validateFromFile(); + validator.validateFromData(); + + return 0; +} diff --git a/doc/src/snippets/qxmlschemavalidator/qxmlschemavalidator.pro b/doc/src/snippets/qxmlschemavalidator/qxmlschemavalidator.pro new file mode 100644 index 0000000..7e8782a --- /dev/null +++ b/doc/src/snippets/qxmlschemavalidator/qxmlschemavalidator.pro @@ -0,0 +1,3 @@ +SOURCES += main.cpp + +QT += xmlpatterns diff --git a/doc/src/snippets/snippets.pro b/doc/src/snippets/snippets.pro index e7219a6..e3e7eca 100644 --- a/doc/src/snippets/snippets.pro +++ b/doc/src/snippets/snippets.pro @@ -74,6 +74,7 @@ SUBDIRS = brush \ qx11embedcontainer \ qx11embedwidget \ qxmlschema \ + qxmlschemavalidator \ reading-selections \ scribe-overview \ separations \ diff --git a/src/xmlpatterns/api/qxmlschemavalidator.cpp b/src/xmlpatterns/api/qxmlschemavalidator.cpp index a69b081..b72b1ef 100644 --- a/src/xmlpatterns/api/qxmlschemavalidator.cpp +++ b/src/xmlpatterns/api/qxmlschemavalidator.cpp @@ -106,6 +106,10 @@ void QXmlSchemaValidator::setSchema(const QXmlSchema &schema) Returns \c true if the XML instance document is valid according the schema, \c false otherwise. + + Example: + + \snippet doc/src/snippets/qxmlschemavalidator/main.cpp 2 */ bool QXmlSchemaValidator::validate(const QByteArray &data, const QUrl &documentUri) const { @@ -122,6 +126,10 @@ bool QXmlSchemaValidator::validate(const QByteArray &data, const QUrl &documentU Returns \c true if the XML instance document is valid according the schema, \c false otherwise. + + Example: + + \snippet doc/src/snippets/qxmlschemavalidator/main.cpp 0 */ bool QXmlSchemaValidator::validate(const QUrl &source) const { @@ -143,6 +151,10 @@ bool QXmlSchemaValidator::validate(const QUrl &source) const Returns \c true if the XML instance document is valid according the schema, \c false otherwise. + + Example: + + \snippet doc/src/snippets/qxmlschemavalidator/main.cpp 1 */ bool QXmlSchemaValidator::validate(QIODevice *source, const QUrl &documentUri) const { -- cgit v0.12 From 4785ed9b76104c272476f62780dde086e21b20ce Mon Sep 17 00:00:00 2001 From: Tobias Koenig Date: Sun, 31 May 2009 13:28:18 +0200 Subject: Add conformance section to qtxmlpatterns doc and extended api docs --- doc/src/qtxmlpatterns.qdoc | 21 +++++++++++++++++++++ src/xmlpatterns/api/qxmlschemavalidator.cpp | 8 +++++++- 2 files changed, 28 insertions(+), 1 deletion(-) diff --git a/doc/src/qtxmlpatterns.qdoc b/doc/src/qtxmlpatterns.qdoc index cb260fc..a48d713 100644 --- a/doc/src/qtxmlpatterns.qdoc +++ b/doc/src/qtxmlpatterns.qdoc @@ -839,6 +839,27 @@ with the \c fn:id() function. See \l{http://www.w3.org/TR/xml-id/}{xml:id Version 1.0} for details. + \section2 XML Schema 1.0 + + The QtXmlPatterns implementation of XML Schema validation supports + the schema specification version 1.0 in large parts. Known problems + of the implementation and areas where conformancy may be questionable + are: + + \list + \o Large \c minOccurs or \c maxOccurs values or deeply nested ones + require huge amount of memory which might cause the system to freeze. + Such a schema should be rewritten to use \c unbounded as value instead + of large numbers. This restriction will hopefully be fixed in a later release. + \o Comparison of really small or large floating point values might lead to + wrong results in some cases. However such numbers should not be relevant + for day-to-day usage. + \o Regular expression support is currently not conformant but follows + Qt's QRegExp standard syntax. + \o Identity constraint checks can not use the values of default or fixed + attribute definitions. + \endlist + \section2 Resource Loading When QtXmlPatterns loads an XML resource, e.g., using the diff --git a/src/xmlpatterns/api/qxmlschemavalidator.cpp b/src/xmlpatterns/api/qxmlschemavalidator.cpp index b72b1ef..dc8e55d 100644 --- a/src/xmlpatterns/api/qxmlschemavalidator.cpp +++ b/src/xmlpatterns/api/qxmlschemavalidator.cpp @@ -69,7 +69,7 @@ /*! Constructs a schema validator. The schema used for validation must be referenced in the XML instance document - via the xsi:schemaLocation attribute. + via the \c xsi:schemaLocation or \c xsi:noNamespaceSchemaLocation attribute. */ QXmlSchemaValidator::QXmlSchemaValidator() : d(new QXmlSchemaValidatorPrivate(QXmlSchema())) @@ -78,6 +78,9 @@ QXmlSchemaValidator::QXmlSchemaValidator() /*! Constructs a schema validator that will use \a schema for validation. + If an empty \l {QXmlSchema} schema is passed to the validator, the schema used + for validation must be referenced in the XML instance document + via the \c xsi:schemaLocation or \c xsi:noNamespaceSchemaLocation attribute. */ QXmlSchemaValidator::QXmlSchemaValidator(const QXmlSchema &schema) : d(new QXmlSchemaValidatorPrivate(schema)) @@ -94,6 +97,9 @@ QXmlSchemaValidator::~QXmlSchemaValidator() /*! Sets the \a schema that shall be used for further validation. + If the schema is empty, the schema used for validation must be referenced + in the XML instance document via the \c xsi:schemaLocation or + \c xsi:noNamespaceSchemaLocation attribute. */ void QXmlSchemaValidator::setSchema(const QXmlSchema &schema) { -- cgit v0.12 From f7741b78c90abcb272345810d55e446a7f390032 Mon Sep 17 00:00:00 2001 From: Tobias Koenig Date: Wed, 3 Jun 2009 17:40:41 +0200 Subject: Fixed typo in apidocs and extended example code --- doc/src/snippets/qxmlschemavalidator/main.cpp | 23 +++++++++++++++++++++++ src/xmlpatterns/api/qxmlschema.cpp | 5 +++++ src/xmlpatterns/api/qxmlschemavalidator.cpp | 12 +++++++++--- 3 files changed, 37 insertions(+), 3 deletions(-) diff --git a/doc/src/snippets/qxmlschemavalidator/main.cpp b/doc/src/snippets/qxmlschemavalidator/main.cpp index 13cd45f..0803380 100644 --- a/doc/src/snippets/qxmlschemavalidator/main.cpp +++ b/doc/src/snippets/qxmlschemavalidator/main.cpp @@ -48,6 +48,7 @@ class SchemaValidator void validateFromUrl() const; void validateFromFile() const; void validateFromData() const; + void validateComplete() const; private: QXmlSchema getSchema() const; @@ -123,6 +124,27 @@ QXmlSchema SchemaValidator::getSchema() const return schema; } +void SchemaValidator::validateComplete() const +{ +//! [3] + QUrl schemaUrl("file:///home/user/schema.xsd"); + + QXmlSchema schema; + schema.load(schemaUrl); + + if (schema.isValid()) { + QFile file("test.xml"); + file.open(QIODevice::ReadOnly); + + QXmlSchemaValidator validator(schema); + if (validator.validate(&file, QUrl::fromLocalFile(file.fileName()))) + qDebug() << "instance document is valid"; + else + qDebug() << "instance document is invalid"; + } +//! [3] +} + int main(int argc, char **argv) { QCoreApplication app(argc, argv); @@ -132,6 +154,7 @@ int main(int argc, char **argv) validator.validateFromUrl(); validator.validateFromFile(); validator.validateFromData(); + validator.validateComplete(); return 0; } diff --git a/src/xmlpatterns/api/qxmlschema.cpp b/src/xmlpatterns/api/qxmlschema.cpp index ec370ca..c6dc9b2 100644 --- a/src/xmlpatterns/api/qxmlschema.cpp +++ b/src/xmlpatterns/api/qxmlschema.cpp @@ -58,6 +58,11 @@ that can be used further for validation of XML instance documents via \l{QXmlSchemaValidator}. + The following example shows how to load a XML Schema file from the network + and test whether it is a valid schema document: + + \snippet doc/src/snippets/qxmlschema/main.cpp 0 + \sa QXmlSchemaValidator, {xmlpatterns/schema}{XML Schema Validation Example} */ diff --git a/src/xmlpatterns/api/qxmlschemavalidator.cpp b/src/xmlpatterns/api/qxmlschemavalidator.cpp index dc8e55d..d5596c5 100644 --- a/src/xmlpatterns/api/qxmlschemavalidator.cpp +++ b/src/xmlpatterns/api/qxmlschemavalidator.cpp @@ -63,6 +63,12 @@ The QXmlSchemaValidator class loads, parses an XML instance document and validates it against a W3C XML Schema that has been compiled with \l{QXmlSchema}. + The following example shows how to load a XML Schema from a local + file, check whether it is a valid schema document and use it for validation + of an XML instance document: + + \snippet doc/src/snippets/qxmlschemavalidator/main.cpp 3 + \sa QXmlSchema, {xmlpatterns/schema}{XML Schema Validation Example} */ @@ -110,7 +116,7 @@ void QXmlSchemaValidator::setSchema(const QXmlSchema &schema) Validates the XML instance document read from \a data with the given \a documentUri against the schema. - Returns \c true if the XML instance document is valid according the + Returns \c true if the XML instance document is valid according to the schema, \c false otherwise. Example: @@ -130,7 +136,7 @@ bool QXmlSchemaValidator::validate(const QByteArray &data, const QUrl &documentU /*! Validates the XML instance document read from \a source against the schema. - Returns \c true if the XML instance document is valid according the + Returns \c true if the XML instance document is valid according to the schema, \c false otherwise. Example: @@ -155,7 +161,7 @@ bool QXmlSchemaValidator::validate(const QUrl &source) const Validates the XML instance document read from \a source with the given \a documentUri against the schema. - Returns \c true if the XML instance document is valid according the + Returns \c true if the XML instance document is valid according to the schema, \c false otherwise. Example: -- cgit v0.12 From 3ded2e1ea5a74a6fc0d3938fa732f886aa275ca2 Mon Sep 17 00:00:00 2001 From: Tobias Koenig Date: Fri, 10 Jul 2009 20:27:42 +0200 Subject: Remove builtin xml schema file until legal issues are clarified --- src/xmlpatterns/schema/builtinschemas.qrc | 1 - src/xmlpatterns/schema/schemas/xml.xsd | 145 ------------------------------ 2 files changed, 146 deletions(-) delete mode 100644 src/xmlpatterns/schema/schemas/xml.xsd diff --git a/src/xmlpatterns/schema/builtinschemas.qrc b/src/xmlpatterns/schema/builtinschemas.qrc index fb43d78..4ca9cd5 100644 --- a/src/xmlpatterns/schema/builtinschemas.qrc +++ b/src/xmlpatterns/schema/builtinschemas.qrc @@ -1,5 +1,4 @@ - schemas/xml.xsd diff --git a/src/xmlpatterns/schema/schemas/xml.xsd b/src/xmlpatterns/schema/schemas/xml.xsd deleted file mode 100644 index eeb9db5..0000000 --- a/src/xmlpatterns/schema/schemas/xml.xsd +++ /dev/null @@ -1,145 +0,0 @@ - - - - - - See http://www.w3.org/XML/1998/namespace.html and - http://www.w3.org/TR/REC-xml for information about this namespace. - - This schema document describes the XML namespace, in a form - suitable for import by other schema documents. - - Note that local names in this namespace are intended to be defined - only by the World Wide Web Consortium or its subgroups. The - following names are currently defined in this namespace and should - not be used with conflicting semantics by any Working Group, - specification, or document instance: - - base (as an attribute name): denotes an attribute whose value - provides a URI to be used as the base for interpreting any - relative URIs in the scope of the element on which it - appears; its value is inherited. This name is reserved - by virtue of its definition in the XML Base specification. - - id (as an attribute name): denotes an attribute whose value - should be interpreted as if declared to be of type ID. - This name is reserved by virtue of its definition in the - xml:id specification. - - lang (as an attribute name): denotes an attribute whose value - is a language code for the natural language of the content of - any element; its value is inherited. This name is reserved - by virtue of its definition in the XML specification. - - space (as an attribute name): denotes an attribute whose - value is a keyword indicating what whitespace processing - discipline is intended for the content of the element; its - value is inherited. This name is reserved by virtue of its - definition in the XML specification. - - Father (in any context at all): denotes Jon Bosak, the chair of - the original XML Working Group. This name is reserved by - the following decision of the W3C XML Plenary and - XML Coordination groups: - - In appreciation for his vision, leadership and dedication - the W3C XML Plenary on this 10th day of February, 2000 - reserves for Jon Bosak in perpetuity the XML name - xml:Father - - - - - This schema defines attributes and an attribute group - suitable for use by - schemas wishing to allow xml:base, xml:lang, xml:space or xml:id - attributes on elements they define. - - To enable this, such a schema must import this schema - for the XML namespace, e.g. as follows: - <schema . . .> - . . . - <import namespace="http://www.w3.org/XML/1998/namespace" - schemaLocation="http://www.w3.org/2001/xml.xsd"/> - - Subsequently, qualified reference to any of the attributes - or the group defined below will have the desired effect, e.g. - - <type . . .> - . . . - <attributeGroup ref="xml:specialAttrs"/> - - will define a type which will schema-validate an instance - element with any of those attributes - - - - In keeping with the XML Schema WG's standard versioning - policy, this schema document will persist at - http://www.w3.org/2007/08/xml.xsd. - At the date of issue it can also be found at - http://www.w3.org/2001/xml.xsd. - The schema document at that URI may however change in the future, - in order to remain compatible with the latest version of XML Schema - itself, or with the XML namespace itself. In other words, if the XML - Schema or XML namespaces change, the version of this document at - http://www.w3.org/2001/xml.xsd will change - accordingly; the version at - http://www.w3.org/2007/08/xml.xsd will not change. - - - - - - Attempting to install the relevant ISO 2- and 3-letter - codes as the enumerated possible values is probably never - going to be a realistic possibility. See - RFC 3066 at http://www.ietf.org/rfc/rfc3066.txt and the IANA registry - at http://www.iana.org/assignments/lang-tag-apps.htm for - further information. - - The union allows for the 'un-declaration' of xml:lang with - the empty string. - - - - - - - - - - - - - - - - - - - - - - - - See http://www.w3.org/TR/xmlbase/ for - information about this attribute. - - - - - - See http://www.w3.org/TR/xml-id/ for - information about this attribute. - - - - - - - - - - - -- cgit v0.12 From 808a6b824fe194d958f5ed1a0fd4f03362ced767 Mon Sep 17 00:00:00 2001 From: Tobias Koenig Date: Mon, 13 Jul 2009 18:27:05 +0200 Subject: Revert "Remove builtin xml schema file until legal issues are clarified" This reverts commit 3ded2e1ea5a74a6fc0d3938fa732f886aa275ca2. --- src/xmlpatterns/schema/builtinschemas.qrc | 1 + src/xmlpatterns/schema/schemas/xml.xsd | 145 ++++++++++++++++++++++++++++++ 2 files changed, 146 insertions(+) create mode 100644 src/xmlpatterns/schema/schemas/xml.xsd diff --git a/src/xmlpatterns/schema/builtinschemas.qrc b/src/xmlpatterns/schema/builtinschemas.qrc index 4ca9cd5..fb43d78 100644 --- a/src/xmlpatterns/schema/builtinschemas.qrc +++ b/src/xmlpatterns/schema/builtinschemas.qrc @@ -1,4 +1,5 @@ + schemas/xml.xsd diff --git a/src/xmlpatterns/schema/schemas/xml.xsd b/src/xmlpatterns/schema/schemas/xml.xsd new file mode 100644 index 0000000..eeb9db5 --- /dev/null +++ b/src/xmlpatterns/schema/schemas/xml.xsd @@ -0,0 +1,145 @@ + + + + + + See http://www.w3.org/XML/1998/namespace.html and + http://www.w3.org/TR/REC-xml for information about this namespace. + + This schema document describes the XML namespace, in a form + suitable for import by other schema documents. + + Note that local names in this namespace are intended to be defined + only by the World Wide Web Consortium or its subgroups. The + following names are currently defined in this namespace and should + not be used with conflicting semantics by any Working Group, + specification, or document instance: + + base (as an attribute name): denotes an attribute whose value + provides a URI to be used as the base for interpreting any + relative URIs in the scope of the element on which it + appears; its value is inherited. This name is reserved + by virtue of its definition in the XML Base specification. + + id (as an attribute name): denotes an attribute whose value + should be interpreted as if declared to be of type ID. + This name is reserved by virtue of its definition in the + xml:id specification. + + lang (as an attribute name): denotes an attribute whose value + is a language code for the natural language of the content of + any element; its value is inherited. This name is reserved + by virtue of its definition in the XML specification. + + space (as an attribute name): denotes an attribute whose + value is a keyword indicating what whitespace processing + discipline is intended for the content of the element; its + value is inherited. This name is reserved by virtue of its + definition in the XML specification. + + Father (in any context at all): denotes Jon Bosak, the chair of + the original XML Working Group. This name is reserved by + the following decision of the W3C XML Plenary and + XML Coordination groups: + + In appreciation for his vision, leadership and dedication + the W3C XML Plenary on this 10th day of February, 2000 + reserves for Jon Bosak in perpetuity the XML name + xml:Father + + + + + This schema defines attributes and an attribute group + suitable for use by + schemas wishing to allow xml:base, xml:lang, xml:space or xml:id + attributes on elements they define. + + To enable this, such a schema must import this schema + for the XML namespace, e.g. as follows: + <schema . . .> + . . . + <import namespace="http://www.w3.org/XML/1998/namespace" + schemaLocation="http://www.w3.org/2001/xml.xsd"/> + + Subsequently, qualified reference to any of the attributes + or the group defined below will have the desired effect, e.g. + + <type . . .> + . . . + <attributeGroup ref="xml:specialAttrs"/> + + will define a type which will schema-validate an instance + element with any of those attributes + + + + In keeping with the XML Schema WG's standard versioning + policy, this schema document will persist at + http://www.w3.org/2007/08/xml.xsd. + At the date of issue it can also be found at + http://www.w3.org/2001/xml.xsd. + The schema document at that URI may however change in the future, + in order to remain compatible with the latest version of XML Schema + itself, or with the XML namespace itself. In other words, if the XML + Schema or XML namespaces change, the version of this document at + http://www.w3.org/2001/xml.xsd will change + accordingly; the version at + http://www.w3.org/2007/08/xml.xsd will not change. + + + + + + Attempting to install the relevant ISO 2- and 3-letter + codes as the enumerated possible values is probably never + going to be a realistic possibility. See + RFC 3066 at http://www.ietf.org/rfc/rfc3066.txt and the IANA registry + at http://www.iana.org/assignments/lang-tag-apps.htm for + further information. + + The union allows for the 'un-declaration' of xml:lang with + the empty string. + + + + + + + + + + + + + + + + + + + + + + + + See http://www.w3.org/TR/xmlbase/ for + information about this attribute. + + + + + + See http://www.w3.org/TR/xml-id/ for + information about this attribute. + + + + + + + + + + + -- cgit v0.12 From 2567ec486d5d95dc4ca06874cf75bf03bd7502b9 Mon Sep 17 00:00:00 2001 From: Tobias Koenig Date: Mon, 13 Jul 2009 18:32:31 +0200 Subject: Add W3C license text for xml.xsd --- src/xmlpatterns/schema/xml.xsd-LICENSE | 40 ++++++++++++++++++++++++++++++++++ 1 file changed, 40 insertions(+) create mode 100644 src/xmlpatterns/schema/xml.xsd-LICENSE diff --git a/src/xmlpatterns/schema/xml.xsd-LICENSE b/src/xmlpatterns/schema/xml.xsd-LICENSE new file mode 100644 index 0000000..2c687d8 --- /dev/null +++ b/src/xmlpatterns/schema/xml.xsd-LICENSE @@ -0,0 +1,40 @@ +W3C® SOFTWARE NOTICE AND LICENSE + +This license came from: http://www.w3.org/Consortium/Legal/2002/copyright-software-20021231 + +This work (and included software, documentation such as READMEs, or other +related items) is being provided by the copyright holders under the following +license. By obtaining, using and/or copying this work, you (the licensee) +agree that you have read, understood, and will comply with the following +terms and conditions. + +Permission to copy, modify, and distribute this software and its +documentation, with or without modification, for any purpose and without +fee or royalty is hereby granted, provided that you include the following on +ALL copies of the software and documentation or portions thereof, including +modifications: + + 1. The full text of this NOTICE in a location viewable to users of the + redistributed or derivative work. + 2. Any pre-existing intellectual property disclaimers, notices, or terms + and conditions. If none exist, the W3C Software Short Notice should be + included (hypertext is preferred, text is permitted) + within the body of any redistributed or derivative code. + 3. Notice of any changes or modifications to the files, including the date + changes were made. (We recommend you provide URIs to the location from + which the code is derived.) + +THIS SOFTWARE AND DOCUMENTATION IS PROVIDED "AS IS," AND COPYRIGHT HOLDERS +MAKE NO REPRESENTATIONS OR WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT NOT +LIMITED TO, WARRANTIES OF MERCHANTABILITY OR FITNESS FOR ANY PARTICULAR +PURPOSE OR THAT THE USE OF THE SOFTWARE OR DOCUMENTATION WILL NOT INFRINGE +ANY THIRD PARTY PATENTS, COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS. + +COPYRIGHT HOLDERS WILL NOT BE LIABLE FOR ANY DIRECT, INDIRECT, SPECIAL OR +CONSEQUENTIAL DAMAGES ARISING OUT OF ANY USE OF THE SOFTWARE OR +DOCUMENTATION. + +The name and trademarks of copyright holders may NOT be used in +advertising or publicity pertaining to the software without specific, written +prior permission. Title to copyright in this software and any associated +documentation will at all times remain with copyright holders. -- cgit v0.12 From 4afd73f94b094d858c000432fcbbb134109d0323 Mon Sep 17 00:00:00 2001 From: Martin Smith Date: Tue, 14 Jul 2009 12:56:08 +0200 Subject: doc: Clarified what happens with a null Q3CString. If you call data() on a default constructed Q3CString, it returns a non-null pointer and from then on isNull() returns false. You have to use constData() to prevent the shared class from detaching the null representation and replacing it with an empty representation. Task-number: 210895 --- src/qt3support/tools/q3cstring.cpp | 32 +++++++++++++++++++++++++++----- 1 file changed, 27 insertions(+), 5 deletions(-) diff --git a/src/qt3support/tools/q3cstring.cpp b/src/qt3support/tools/q3cstring.cpp index 39f1c43..b33b9b6 100644 --- a/src/qt3support/tools/q3cstring.cpp +++ b/src/qt3support/tools/q3cstring.cpp @@ -77,11 +77,23 @@ QT_BEGIN_NAMESPACE and '\0' (NUL byte) terminated; otherwise the results are undefined. - A Q3CString that has not been assigned to anything is \e null, i.e. - both the length and the data pointer is 0. A Q3CString that - references the empty string ("", a single '\0' char) is \e empty. - Both null and empty Q3CStrings are legal parameters to the methods. - Assigning \c{const char *} 0 to Q3CString produces a null Q3CString. + A default constructed Q3CString is \e null, i.e. both the length + and the data pointer are 0 and isNull() returns true. + + \note However, if you ask for the data pointer of a null Q3CString + by calling data(), then because the internal representation of the + null Q3CString is shared, it will be detached and replaced with a + non-shared, empty representation, a non-null data pointer will be + returned, and subsequent calls to isNull() will return false. But + if you ask for the data pointer of a null Q3CString by calling + constData(), the shared internal representation is not detached, a + null data pointer is returned, and subsequent calls to isNull() + will continue to return true. + + A Q3CString that references the empty string ("", a single '\0' + char) is \e empty, i.e. isEmpty() returns true. Both null and + empty Q3CStrings are legal parameters to the methods. Assigning + \c{const char *} 0 to Q3CString produces a null Q3CString. The length() function returns the length of the string; resize() resizes the string and truncate() truncates the string. A string @@ -321,6 +333,16 @@ QT_BEGIN_NAMESPACE Returns true if the string is null, i.e. if data() == 0; otherwise returns false. A null string is also an empty string. + \note If you ask for the data pointer of a null Q3CString by + calling data(), then because the internal representation of the + null Q3CString is shared, it will be detached and replaced with a + non-shared, empty representation, a non-null data pointer will be + returned, and subsequent calls to isNull() will return false. But + if you ask for the data pointer of a null Q3CString by calling + constData(), the shared internal representation is not detached, a + null data pointer is returned, and subsequent calls to isNull() + will continue to return true. + Example: \snippet doc/src/snippets/code/src.qt3support.tools.q3cstring.cpp 1 -- cgit v0.12 From 9210e8cdc83b6812d10f5f5847d05703ef2e5f7c Mon Sep 17 00:00:00 2001 From: Denis Dzyubenko Date: Tue, 14 Jul 2009 13:02:37 +0200 Subject: Fixed the qlineedit autotest. The commit 099a32d changed a behavior of qlineedit not to insert text when a modifier is pressed. This commit fixes the appropriate autotest. --- tests/auto/qlineedit/tst_qlineedit.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/auto/qlineedit/tst_qlineedit.cpp b/tests/auto/qlineedit/tst_qlineedit.cpp index 3519afa..7fc8316 100644 --- a/tests/auto/qlineedit/tst_qlineedit.cpp +++ b/tests/auto/qlineedit/tst_qlineedit.cpp @@ -3025,11 +3025,11 @@ void tst_QLineEdit::charWithAltOrCtrlModifier() QTest::keyPress(testWidget, Qt::Key_Plus); QCOMPARE(testWidget->text(), QString("+")); QTest::keyPress(testWidget, Qt::Key_Plus, Qt::ControlModifier); - QCOMPARE(testWidget->text(), QString("++")); + QCOMPARE(testWidget->text(), QString("+")); QTest::keyPress(testWidget, Qt::Key_Plus, Qt::AltModifier); - QCOMPARE(testWidget->text(), QString("+++")); + QCOMPARE(testWidget->text(), QString("+")); QTest::keyPress(testWidget, Qt::Key_Plus, Qt::AltModifier | Qt::ControlModifier); - QCOMPARE(testWidget->text(), QString("++++")); + QCOMPARE(testWidget->text(), QString("+")); } void tst_QLineEdit::leftKeyOnSelectedText() -- cgit v0.12 From 34fde4a4b7220c92b03dfa92607feb6179454066 Mon Sep 17 00:00:00 2001 From: Marius Bugge Monsen Date: Thu, 2 Jul 2009 14:06:25 +0200 Subject: Add QGraphicsView::filtersChildEvents property. This obsoletes QGraphicsView::handlesChildEvents. --- src/gui/graphicsview/qgraphicsitem.cpp | 49 +++++++++++++++++- src/gui/graphicsview/qgraphicsitem.h | 3 ++ src/gui/graphicsview/qgraphicsitem_p.h | 15 +++--- src/gui/graphicsview/qgraphicsscene.cpp | 90 ++++++++++++++++++++++++++++++++- src/gui/graphicsview/qgraphicsscene_p.h | 1 + 5 files changed, 149 insertions(+), 9 deletions(-) diff --git a/src/gui/graphicsview/qgraphicsitem.cpp b/src/gui/graphicsview/qgraphicsitem.cpp index 03014d8..cb0418c 100644 --- a/src/gui/graphicsview/qgraphicsitem.cpp +++ b/src/gui/graphicsview/qgraphicsitem.cpp @@ -650,6 +650,10 @@ void QGraphicsItemPrivate::updateAncestorFlag(QGraphicsItem::GraphicsItemFlag ch // For root items only. This is the item that has either enabled or // disabled \a childFlag, or has been reparented. switch (int(childFlag)) { + case -2: + flag = AncestorFiltersChildEvents; + enabled = q->filtersChildEvents(); + break; case -1: flag = AncestorHandlesChildEvents; enabled = q->handlesChildEvents(); @@ -670,7 +674,8 @@ void QGraphicsItemPrivate::updateAncestorFlag(QGraphicsItem::GraphicsItemFlag ch // Inherit the enabled-state from our parents. if ((parent && ((parent->d_ptr->ancestorFlags & flag) || (int(parent->d_ptr->flags & childFlag) == childFlag) - || (childFlag == -1 && parent->d_ptr->handlesChildEvents)))) { + || (childFlag == -1 && parent->d_ptr->handlesChildEvents) + || (childFlag == -2 && parent->d_ptr->filtersDescendantEvents)))) { enabled = true; ancestorFlags |= flag; } @@ -691,7 +696,9 @@ void QGraphicsItemPrivate::updateAncestorFlag(QGraphicsItem::GraphicsItemFlag ch ancestorFlags &= ~flag; // Don't process children if the item has the main flag set on itself. - if ((childFlag != -1 && int(flags & childFlag) == childFlag) || (int(childFlag) == -1 && handlesChildEvents)) + if ((childFlag != -1 && int(flags & childFlag) == childFlag) + || (int(childFlag) == -1 && handlesChildEvents) + || (int(childFlag) == -2 && filtersDescendantEvents)) return; } @@ -953,6 +960,7 @@ void QGraphicsItemPrivate::setParentItemHelper(QGraphicsItem *newParent) } // Inherit ancestor flags from the new parent. + updateAncestorFlag(QGraphicsItem::GraphicsItemFlag(-2)); updateAncestorFlag(QGraphicsItem::GraphicsItemFlag(-1)); updateAncestorFlag(QGraphicsItem::ItemClipsChildrenToShape); updateAncestorFlag(QGraphicsItem::ItemIgnoresTransformations); @@ -969,6 +977,7 @@ void QGraphicsItemPrivate::setParentItemHelper(QGraphicsItem *newParent) } else { // Inherit ancestor flags from the new parent. + updateAncestorFlag(QGraphicsItem::GraphicsItemFlag(-2)); updateAncestorFlag(QGraphicsItem::GraphicsItemFlag(-1)); updateAncestorFlag(QGraphicsItem::ItemClipsChildrenToShape); updateAncestorFlag(QGraphicsItem::ItemIgnoresTransformations); @@ -2352,6 +2361,40 @@ void QGraphicsItem::setAcceptTouchEvents(bool enabled) } /*! + Returns true if this item filters child events (i.e., all events + intended for any of its children are instead sent to this item); + otherwise, false is returned. + + The default value is false; child events are not filtered. + + \sa setFiltersChildEvents() +*/ +bool QGraphicsItem::filtersChildEvents() const +{ + return d_ptr->filtersDescendantEvents; +} + +/*! + If \a enabled is true, this item is set to filter all events for + all its children (i.e., all events intented for any of its + children are instead sent to this item); otherwise, if \a enabled + is false, this item will only handle its own events. The default + value is false. + + \sa filtersChildEvents() +*/ +void QGraphicsItem::setFiltersChildEvents(bool enabled) +{ + if (d_ptr->filtersDescendantEvents == enabled) + return; + + d_ptr->filtersDescendantEvents = enabled; + d_ptr->updateAncestorFlag(QGraphicsItem::GraphicsItemFlag(-2)); +} + +/*! + \obsolete + Returns true if this item handles child events (i.e., all events intended for any of its children are instead sent to this item); otherwise, false is returned. @@ -2372,6 +2415,8 @@ bool QGraphicsItem::handlesChildEvents() const } /*! + \obsolete + If \a enabled is true, this item is set to handle all events for all its children (i.e., all events intented for any of its children are instead sent to this item); otherwise, if \a enabled diff --git a/src/gui/graphicsview/qgraphicsitem.h b/src/gui/graphicsview/qgraphicsitem.h index 72c4830..a307622 100644 --- a/src/gui/graphicsview/qgraphicsitem.h +++ b/src/gui/graphicsview/qgraphicsitem.h @@ -216,6 +216,9 @@ public: bool acceptTouchEvents() const; void setAcceptTouchEvents(bool enabled); + bool filtersChildEvents() const; + void setFiltersChildEvents(bool enabled); + bool handlesChildEvents() const; void setHandlesChildEvents(bool enabled); diff --git a/src/gui/graphicsview/qgraphicsitem_p.h b/src/gui/graphicsview/qgraphicsitem_p.h index 9bdd273..4729634 100644 --- a/src/gui/graphicsview/qgraphicsitem_p.h +++ b/src/gui/graphicsview/qgraphicsitem_p.h @@ -109,7 +109,8 @@ public: NoFlag = 0, AncestorHandlesChildEvents = 0x1, AncestorClipsChildren = 0x2, - AncestorIgnoresTransformations = 0x4 + AncestorIgnoresTransformations = 0x4, + AncestorFiltersChildEvents = 0x8 }; inline QGraphicsItemPrivate() @@ -157,6 +158,7 @@ public: ignoreOpacity(0), acceptTouchEvents(0), acceptedTouchBeginEvent(0), + filtersDescendantEvents(0), sceneTransformTranslateOnly(0), globalStackingOrder(-1), q_ptr(0) @@ -421,7 +423,7 @@ public: quint32 handlesChildEvents : 1; quint32 itemDiscovered : 1; quint32 hasCursor : 1; - quint32 ancestorFlags : 3; + quint32 ancestorFlags : 4; quint32 cacheMode : 2; quint32 hasBoundingRegionGranularity : 1; quint32 isWidget : 1; @@ -433,13 +435,13 @@ public: quint32 inSetPosHelper : 1; quint32 needSortChildren : 1; quint32 allChildrenDirty : 1; - quint32 fullUpdatePending : 1; // New 32 bits - quint32 flags : 13; + quint32 fullUpdatePending : 1; + quint32 flags : 12; quint32 dirtyChildrenBoundingRect : 1; quint32 paintedViewBoundingRectsNeedRepaint : 1; - quint32 dirtySceneTransform : 1; + quint32 dirtySceneTransform : 1; quint32 geometryChanged : 1; quint32 inDestructor : 1; quint32 isObject : 1; @@ -447,8 +449,9 @@ public: quint32 ignoreOpacity : 1; quint32 acceptTouchEvents : 1; quint32 acceptedTouchBeginEvent : 1; + quint32 filtersDescendantEvents : 1; quint32 sceneTransformTranslateOnly : 1; - quint32 unused : 8; // feel free to use + quint32 unused : 7; // feel free to use // Optional stacking order int globalStackingOrder; diff --git a/src/gui/graphicsview/qgraphicsscene.cpp b/src/gui/graphicsview/qgraphicsscene.cpp index c8e178a..e2458f5 100644 --- a/src/gui/graphicsview/qgraphicsscene.cpp +++ b/src/gui/graphicsview/qgraphicsscene.cpp @@ -853,6 +853,24 @@ void QGraphicsScenePrivate::removeSceneEventFilter(QGraphicsItem *watched, QGrap } /*! + \internal +*/ +bool QGraphicsScenePrivate::filterDescendantEvent(QGraphicsItem *item, QEvent *event) +{ + if (item && (item->d_ptr->ancestorFlags & QGraphicsItemPrivate::AncestorFiltersChildEvents)) { + QGraphicsItem *parent = item->parentItem(); + while (parent) { + if (parent->d_ptr->filtersDescendantEvents && parent->sceneEventFilter(item, event)) + return true; + if (!(parent->d_ptr->ancestorFlags & QGraphicsItemPrivate::AncestorFiltersChildEvents)) + return false; + parent = parent->parentItem(); + } + } + return false; +} + +/*! \internal */ bool QGraphicsScenePrivate::filterEvent(QGraphicsItem *item, QEvent *event) @@ -884,7 +902,9 @@ bool QGraphicsScenePrivate::sendEvent(QGraphicsItem *item, QEvent *event) { if (filterEvent(item, event)) return false; - return (item && item->isEnabled()) ? item->sceneEvent(event) : false; + if (filterDescendantEvent(item, event)) + return false; + return (item && item->isEnabled() ? item->sceneEvent(event) : false); } /*! @@ -3022,6 +3042,74 @@ bool QGraphicsScene::event(QEvent *event) return true; } +<<<<<<< HEAD:src/gui/graphicsview/qgraphicsscene.cpp +======= +void QGraphicsScenePrivate::sendGestureEvent(const QSet &gestures, const QSet &cancelled) +{ + Q_Q(QGraphicsScene); + typedef QMap > ItemGesturesMap; + ItemGesturesMap itemGestures; + QSet startedGestures; + for(QSet::const_iterator it = gestures.begin(), e = gestures.end(); + it != e; ++it) { + QGesture *g = *it; + Q_ASSERT(g != 0); + QGesturePrivate *gd = g->d_func(); + if (gd->graphicsItem != 0) { + itemGestures[gd->graphicsItem].insert(g); + if (g->state() == Qt::GestureStarted || gd->singleshot) + startedGestures.insert(g); + } + } + + QSet ignoredGestures; + for(ItemGesturesMap::const_iterator it = itemGestures.begin(), e = itemGestures.end(); + it != e; ++it) { + QGraphicsItem *receiver = it.key(); + Q_ASSERT(receiver != 0); + QGraphicsSceneGestureEvent event; + event.setGestures(it.value()); + event.setCancelledGestures(cancelled); + bool processed = sendEvent(receiver, &event); + QSet started = startedGestures.intersect(it.value()); + if (event.isAccepted()) + foreach(QGesture *g, started) + g->accept(); + if (!started.isEmpty() && !(processed && event.isAccepted())) { + // there are started gestures event that weren't + // accepted, so propagating each gesture independently. + QSet::const_iterator it = started.begin(), + e = started.end(); + for(; it != e; ++it) { + QGesture *g = *it; + if (processed && g->isAccepted()) { + continue; + } + QGesturePrivate *gd = g->d_func(); + QGraphicsItem *item = gd->graphicsItem; + Q_UNUSED(item); // ### REMOVE + gd->graphicsItem = 0; + + //### THIS IS BS, DONT FORGET TO REWRITE THIS CODE + // need to make sure we try to deliver event just once to each widget + const QString gestureType = g->type(); + QList itemsUnderGesture = q->items(g->hotSpot()); + for (int i = 0; i < itemsUnderGesture.size(); ++i) { + QGraphicsItem *item = itemsUnderGesture.at(i); + if (item != receiver && item->d_func()->hasGesture(gestureType)) { + ignoredGestures.insert(g); + gd->graphicsItem = item; + break; + } + } + } + } + } + if (!ignoredGestures.isEmpty()) + sendGestureEvent(ignoredGestures, cancelled); +} + +>>>>>>> 296da87... Add QGraphicsView::filtersChildEvents property.:src/gui/graphicsview/qgraphicsscene.cpp /*! \reimp diff --git a/src/gui/graphicsview/qgraphicsscene_p.h b/src/gui/graphicsview/qgraphicsscene_p.h index ffd62d5..9a91acc 100644 --- a/src/gui/graphicsview/qgraphicsscene_p.h +++ b/src/gui/graphicsview/qgraphicsscene_p.h @@ -172,6 +172,7 @@ public: QMultiMap sceneEventFilters; void installSceneEventFilter(QGraphicsItem *watched, QGraphicsItem *filter); void removeSceneEventFilter(QGraphicsItem *watched, QGraphicsItem *filter); + bool filterDescendantEvent(QGraphicsItem *item, QEvent *event); bool filterEvent(QGraphicsItem *item, QEvent *event); bool sendEvent(QGraphicsItem *item, QEvent *event); -- cgit v0.12 From a2bad25383e565233a0c2527e04cef9f6b577f14 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B8rn=20Erik=20Nilsen?= Date: Tue, 14 Jul 2009 13:03:10 +0200 Subject: Make sure QGraphicsScene::update() only requires one event-loop iteration before the views are updated. A full scene update (scene.update()) already supported it because the scene called update() on the views directly. However, partially scene updates (scene.update(rect)) required two event-loop iterations before the views were updated. Auto-test included. --- src/gui/graphicsview/qgraphicsscene.cpp | 14 ++++++------ src/gui/graphicsview/qgraphicsview.cpp | 10 +++------ src/gui/graphicsview/qgraphicsview_p.h | 10 +++++++++ tests/auto/qgraphicsscene/tst_qgraphicsscene.cpp | 27 ++++++++++++++++++++++++ 4 files changed, 46 insertions(+), 15 deletions(-) diff --git a/src/gui/graphicsview/qgraphicsscene.cpp b/src/gui/graphicsview/qgraphicsscene.cpp index c8e178a..48d8788 100644 --- a/src/gui/graphicsview/qgraphicsscene.cpp +++ b/src/gui/graphicsview/qgraphicsscene.cpp @@ -357,6 +357,9 @@ void QGraphicsScenePrivate::_q_emitUpdated() updateAll = false; for (int i = 0; i < views.size(); ++i) views.at(i)->d_func()->processPendingUpdates(); + // It's important that we update all views before we dispatch, hence two for-loops. + for (int i = 0; i < views.size(); ++i) + views.at(i)->d_func()->dispatchPendingUpdateRequests(); return; } @@ -447,13 +450,8 @@ void QGraphicsScenePrivate::_q_processDirtyItems() } // Immediately dispatch all pending update requests on the views. - for (int i = 0; i < views.size(); ++i) { - QWidget *viewport = views.at(i)->d_func()->viewport; - if (qt_widget_private(viewport)->paintOnScreen()) - QCoreApplication::sendPostedEvents(viewport, QEvent::UpdateRequest); - else - QCoreApplication::sendPostedEvents(viewport->window(), QEvent::UpdateRequest); - } + for (int i = 0; i < views.size(); ++i) + views.at(i)->d_func()->dispatchPendingUpdateRequests(); } /*! @@ -2730,7 +2728,7 @@ void QGraphicsScene::update(const QRectF &rect) if (directUpdates) { // Update all views. for (int i = 0; i < d->views.size(); ++i) - d->views.at(i)->d_func()->updateAll(); + d->views.at(i)->d_func()->fullUpdatePending = true; } } else { if (directUpdates) { diff --git a/src/gui/graphicsview/qgraphicsview.cpp b/src/gui/graphicsview/qgraphicsview.cpp index bcfd68c..1cea8db 100644 --- a/src/gui/graphicsview/qgraphicsview.cpp +++ b/src/gui/graphicsview/qgraphicsview.cpp @@ -821,13 +821,9 @@ void QGraphicsViewPrivate::processPendingUpdates() if (!scene) return; - if (fullUpdatePending) { // We have already called viewport->update() - dirtyBoundingRect = QRect(); - dirtyRegion = QRegion(); - return; - } - - if (viewportUpdateMode == QGraphicsView::BoundingRectViewportUpdate) { + if (fullUpdatePending) { + viewport->update(); + } else if (viewportUpdateMode == QGraphicsView::BoundingRectViewportUpdate) { if (optimizationFlags & QGraphicsView::DontAdjustForAntialiasing) viewport->update(dirtyBoundingRect.adjusted(-1, -1, 1, 1)); else diff --git a/src/gui/graphicsview/qgraphicsview_p.h b/src/gui/graphicsview/qgraphicsview_p.h index 0fa8b34..62a2b84 100644 --- a/src/gui/graphicsview/qgraphicsview_p.h +++ b/src/gui/graphicsview/qgraphicsview_p.h @@ -58,6 +58,7 @@ #if !defined(QT_NO_GRAPHICSVIEW) || (QT_EDITION & QT_MODULE_GRAPHICSVIEW) != QT_MODULE_GRAPHICSVIEW #include +#include #include "qgraphicssceneevent.h" #include #include @@ -168,6 +169,15 @@ public: dirtyBoundingRect = QRect(); dirtyRegion = QRegion(); } + + inline void dispatchPendingUpdateRequests() + { + if (qt_widget_private(viewport)->paintOnScreen()) + QCoreApplication::sendPostedEvents(viewport, QEvent::UpdateRequest); + else + QCoreApplication::sendPostedEvents(viewport->window(), QEvent::UpdateRequest); + } + bool updateRect(const QRect &rect); bool updateRegion(const QRegion ®ion); bool updateSceneSlotReimplementedChecked; diff --git a/tests/auto/qgraphicsscene/tst_qgraphicsscene.cpp b/tests/auto/qgraphicsscene/tst_qgraphicsscene.cpp index e9d6f1d..f7ea4ce 100644 --- a/tests/auto/qgraphicsscene/tst_qgraphicsscene.cpp +++ b/tests/auto/qgraphicsscene/tst_qgraphicsscene.cpp @@ -236,6 +236,7 @@ private slots: void contextMenuEvent(); void contextMenuEvent_ItemIgnoresTransformations(); void update(); + void update2(); void views(); void event(); void eventsToDisabledItems(); @@ -2779,6 +2780,32 @@ void tst_QGraphicsScene::update() QCOMPARE(region, QRectF(-100, -100, 200, 200)); } +void tst_QGraphicsScene::update2() +{ + QGraphicsScene scene; + scene.setSceneRect(-200, -200, 200, 200); + CustomView view; + view.setScene(&scene); + view.show(); +#ifdef Q_WS_X11 + qt_x11_wait_for_window_manager(&view); +#endif + QTest::qWait(250); + view.repaints = 0; + + // Make sure QGraphicsScene::update only requires one event-loop iteration + // before the view is updated. + scene.update(); + qApp->processEvents(); + QCOMPARE(view.repaints, 1); + view.repaints = 0; + + // The same for partial scene updates. + scene.update(QRectF(-100, -100, 100, 100)); + qApp->processEvents(); + QCOMPARE(view.repaints, 1); +} + void tst_QGraphicsScene::views() { QGraphicsScene scene; -- cgit v0.12 From ec11bd70c78cbdb07b399b058fabdb16d66072b0 Mon Sep 17 00:00:00 2001 From: Markus Goetz Date: Tue, 14 Jul 2009 13:05:11 +0200 Subject: QNetworkReply: Add isFinished() method The isFinished() method will return true if the reply has successfully finished or has been aborted. Task-number: 257349 Reviewed-by: Thiago Macieira --- src/network/access/qnetworkreply.cpp | 21 +++++++++++++++++++++ src/network/access/qnetworkreply.h | 2 ++ src/network/access/qnetworkreply_p.h | 2 ++ src/network/access/qnetworkreplyimpl.cpp | 5 +++++ src/network/access/qnetworkreplyimpl_p.h | 2 ++ tests/auto/qnetworkreply/tst_qnetworkreply.cpp | 10 ++++++++++ 6 files changed, 42 insertions(+) diff --git a/src/network/access/qnetworkreply.cpp b/src/network/access/qnetworkreply.cpp index 1b0d9f5..e55c202 100644 --- a/src/network/access/qnetworkreply.cpp +++ b/src/network/access/qnetworkreply.cpp @@ -442,6 +442,27 @@ QNetworkReply::NetworkError QNetworkReply::error() const } /*! + Returns true when the reply has finished or was aborted. + + \sa isRunning() +*/ +bool QNetworkReply::isFinished() const +{ + return d_func()->isFinished(); +} + +/*! + Returns true when the request is still processing and the + reply has not finished or was aborted yet. + + \sa isFinished() +*/ +bool QNetworkReply::isRunning() const +{ + return !isFinished(); +} + +/*! Returns the URL of the content downloaded or uploaded. Note that the URL may be different from that of the original request. diff --git a/src/network/access/qnetworkreply.h b/src/network/access/qnetworkreply.h index 7cb082f..30e89f1 100644 --- a/src/network/access/qnetworkreply.h +++ b/src/network/access/qnetworkreply.h @@ -116,6 +116,8 @@ public: QNetworkAccessManager::Operation operation() const; QNetworkRequest request() const; NetworkError error() const; + bool isFinished() const; + bool isRunning() const; QUrl url() const; // "cooked" headers diff --git a/src/network/access/qnetworkreply_p.h b/src/network/access/qnetworkreply_p.h index c8543f0..b51e3fb 100644 --- a/src/network/access/qnetworkreply_p.h +++ b/src/network/access/qnetworkreply_p.h @@ -75,6 +75,8 @@ public: static inline void setManager(QNetworkReply *reply, QNetworkAccessManager *manager) { reply->d_func()->manager = manager; } + virtual bool isFinished() const { return false; } + Q_DECLARE_PUBLIC(QNetworkReply) }; diff --git a/src/network/access/qnetworkreplyimpl.cpp b/src/network/access/qnetworkreplyimpl.cpp index b11d986..55b8b7f 100644 --- a/src/network/access/qnetworkreplyimpl.cpp +++ b/src/network/access/qnetworkreplyimpl.cpp @@ -532,6 +532,11 @@ void QNetworkReplyImplPrivate::sslErrors(const QList &errors) #endif } +bool QNetworkReplyImplPrivate::isFinished() const +{ + return (state == Finished || state == Aborted); +} + QNetworkReplyImpl::QNetworkReplyImpl(QObject *parent) : QNetworkReply(*new QNetworkReplyImplPrivate, parent) { diff --git a/src/network/access/qnetworkreplyimpl_p.h b/src/network/access/qnetworkreplyimpl_p.h index 3e89a00..454185a 100644 --- a/src/network/access/qnetworkreplyimpl_p.h +++ b/src/network/access/qnetworkreplyimpl_p.h @@ -152,6 +152,8 @@ public: void redirectionRequested(const QUrl &target); void sslErrors(const QList &errors); + bool isFinished() const; + QNetworkAccessBackend *backend; QIODevice *outgoingData; QRingBuffer *outgoingDataBuffer; diff --git a/tests/auto/qnetworkreply/tst_qnetworkreply.cpp b/tests/auto/qnetworkreply/tst_qnetworkreply.cpp index cb1cb9b..f2bfb1f 100644 --- a/tests/auto/qnetworkreply/tst_qnetworkreply.cpp +++ b/tests/auto/qnetworkreply/tst_qnetworkreply.cpp @@ -1003,6 +1003,7 @@ void tst_QNetworkReply::stateChecking() QCOMPARE(reply->request(), req); QCOMPARE(int(reply->operation()), int(QNetworkAccessManager::GetOperation)); QCOMPARE(reply->error(), QNetworkReply::NoError); + QCOMPARE(reply->isFinished(), false); QCOMPARE(reply->url(), url); reply->abort(); @@ -1324,6 +1325,9 @@ void tst_QNetworkReply::getErrors() QTEST(reply->readAll().isEmpty(), "dataIsEmpty"); + QVERIFY(reply->isFinished()); + QVERIFY(!reply->isRunning()); + QFETCH(int, httpStatusCode); if (httpStatusCode != 0) { QCOMPARE(reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt(), httpStatusCode); @@ -3237,6 +3241,8 @@ void tst_QNetworkReply::downloadProgress() connect(reply, SIGNAL(downloadProgress(qint64,qint64)), &QTestEventLoop::instance(), SLOT(exitLoop())); QVERIFY(spy.isValid()); + QVERIFY(!reply->isFinished()); + QVERIFY(reply->isRunning()); QCoreApplication::instance()->processEvents(); if (!server.hasPendingConnections()) @@ -3257,6 +3263,8 @@ void tst_QNetworkReply::downloadProgress() QTestEventLoop::instance().enterLoop(2); QVERIFY(!QTestEventLoop::instance().timeout()); QVERIFY(spy.count() > 0); + QVERIFY(!reply->isFinished()); + QVERIFY(reply->isRunning()); QList args = spy.last(); QCOMPARE(args.at(0).toInt(), i*data.size()); @@ -3270,6 +3278,8 @@ void tst_QNetworkReply::downloadProgress() QTestEventLoop::instance().enterLoop(2); QVERIFY(!QTestEventLoop::instance().timeout()); QVERIFY(spy.count() > 0); + QVERIFY(!reply->isRunning()); + QVERIFY(reply->isFinished()); QList args = spy.last(); QCOMPARE(args.at(0).toInt(), loopCount * data.size()); -- cgit v0.12 From 1d9cbee73b51078e92bca26dbbf4e7d33bf72471 Mon Sep 17 00:00:00 2001 From: Martin Smith Date: Tue, 14 Jul 2009 12:56:08 +0200 Subject: doc: Clarified what happens with a null Q3CString. If you call data() on a default constructed Q3CString, it returns a non-null pointer and from then on isNull() returns false. You have to use constData() to prevent the shared class from detaching the null representation and replacing it with an empty representation. Task-number: 210895 --- src/qt3support/tools/q3cstring.cpp | 32 +++++++++++++++++++++++++++----- 1 file changed, 27 insertions(+), 5 deletions(-) diff --git a/src/qt3support/tools/q3cstring.cpp b/src/qt3support/tools/q3cstring.cpp index 39f1c43..b33b9b6 100644 --- a/src/qt3support/tools/q3cstring.cpp +++ b/src/qt3support/tools/q3cstring.cpp @@ -77,11 +77,23 @@ QT_BEGIN_NAMESPACE and '\0' (NUL byte) terminated; otherwise the results are undefined. - A Q3CString that has not been assigned to anything is \e null, i.e. - both the length and the data pointer is 0. A Q3CString that - references the empty string ("", a single '\0' char) is \e empty. - Both null and empty Q3CStrings are legal parameters to the methods. - Assigning \c{const char *} 0 to Q3CString produces a null Q3CString. + A default constructed Q3CString is \e null, i.e. both the length + and the data pointer are 0 and isNull() returns true. + + \note However, if you ask for the data pointer of a null Q3CString + by calling data(), then because the internal representation of the + null Q3CString is shared, it will be detached and replaced with a + non-shared, empty representation, a non-null data pointer will be + returned, and subsequent calls to isNull() will return false. But + if you ask for the data pointer of a null Q3CString by calling + constData(), the shared internal representation is not detached, a + null data pointer is returned, and subsequent calls to isNull() + will continue to return true. + + A Q3CString that references the empty string ("", a single '\0' + char) is \e empty, i.e. isEmpty() returns true. Both null and + empty Q3CStrings are legal parameters to the methods. Assigning + \c{const char *} 0 to Q3CString produces a null Q3CString. The length() function returns the length of the string; resize() resizes the string and truncate() truncates the string. A string @@ -321,6 +333,16 @@ QT_BEGIN_NAMESPACE Returns true if the string is null, i.e. if data() == 0; otherwise returns false. A null string is also an empty string. + \note If you ask for the data pointer of a null Q3CString by + calling data(), then because the internal representation of the + null Q3CString is shared, it will be detached and replaced with a + non-shared, empty representation, a non-null data pointer will be + returned, and subsequent calls to isNull() will return false. But + if you ask for the data pointer of a null Q3CString by calling + constData(), the shared internal representation is not detached, a + null data pointer is returned, and subsequent calls to isNull() + will continue to return true. + Example: \snippet doc/src/snippets/code/src.qt3support.tools.q3cstring.cpp 1 -- cgit v0.12 From 75ab22f56052e1e4208b4c8dc1d667de9768f5b2 Mon Sep 17 00:00:00 2001 From: Denis Dzyubenko Date: Tue, 14 Jul 2009 13:02:37 +0200 Subject: Fixed the qlineedit autotest. The commit 099a32d changed a behavior of qlineedit not to insert text when a modifier is pressed. This commit fixes the appropriate autotest. --- tests/auto/qlineedit/tst_qlineedit.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/auto/qlineedit/tst_qlineedit.cpp b/tests/auto/qlineedit/tst_qlineedit.cpp index 3519afa..7fc8316 100644 --- a/tests/auto/qlineedit/tst_qlineedit.cpp +++ b/tests/auto/qlineedit/tst_qlineedit.cpp @@ -3025,11 +3025,11 @@ void tst_QLineEdit::charWithAltOrCtrlModifier() QTest::keyPress(testWidget, Qt::Key_Plus); QCOMPARE(testWidget->text(), QString("+")); QTest::keyPress(testWidget, Qt::Key_Plus, Qt::ControlModifier); - QCOMPARE(testWidget->text(), QString("++")); + QCOMPARE(testWidget->text(), QString("+")); QTest::keyPress(testWidget, Qt::Key_Plus, Qt::AltModifier); - QCOMPARE(testWidget->text(), QString("+++")); + QCOMPARE(testWidget->text(), QString("+")); QTest::keyPress(testWidget, Qt::Key_Plus, Qt::AltModifier | Qt::ControlModifier); - QCOMPARE(testWidget->text(), QString("++++")); + QCOMPARE(testWidget->text(), QString("+")); } void tst_QLineEdit::leftKeyOnSelectedText() -- cgit v0.12 From 8189132079abb2349b44b3e13e58b5453c489e98 Mon Sep 17 00:00:00 2001 From: Marius Bugge Monsen Date: Thu, 2 Jul 2009 15:48:08 +0200 Subject: Add auto-tests for QGraphicsItem::filtersChildEvents. --- tests/auto/qgraphicsitem/tst_qgraphicsitem.cpp | 123 +++++++++++++++++++++++++ 1 file changed, 123 insertions(+) diff --git a/tests/auto/qgraphicsitem/tst_qgraphicsitem.cpp b/tests/auto/qgraphicsitem/tst_qgraphicsitem.cpp index 96ee070..3f41a90 100644 --- a/tests/auto/qgraphicsitem/tst_qgraphicsitem.cpp +++ b/tests/auto/qgraphicsitem/tst_qgraphicsitem.cpp @@ -182,6 +182,8 @@ private slots: void handlesChildEvents(); void handlesChildEvents2(); void handlesChildEvents3(); + void filtersChildEvents(); + void filtersChildEvents2(); void ensureVisible(); void cursor(); //void textControlGetterSetter(); @@ -3406,6 +3408,127 @@ void tst_QGraphicsItem::handlesChildEvents3() QCOMPARE(group2->counter, 3); } + +class ChildEventFilterTester : public ChildEventTester +{ +public: + ChildEventFilterTester(const QRectF &rect, QGraphicsItem *parent = 0) + : ChildEventTester(rect, parent), filter(QEvent::None) + { } + + QEvent::Type filter; + +protected: + bool sceneEventFilter(QGraphicsItem *item, QEvent *event) + { + Q_UNUSED(item); + if (event->type() == filter) { + ++counter; + return true; + } + return false; + } +}; + +void tst_QGraphicsItem::filtersChildEvents() +{ + QGraphicsScene scene; + ChildEventFilterTester *root = new ChildEventFilterTester(QRectF(0, 0, 10, 10)); + ChildEventFilterTester *filter = new ChildEventFilterTester(QRectF(10, 10, 10, 10), root); + ChildEventTester *child = new ChildEventTester(QRectF(20, 20, 10, 10), filter); + + // setup filter + filter->setFiltersChildEvents(true); + filter->filter = QEvent::GraphicsSceneMousePress; + + scene.addItem(root); + + QGraphicsView view(&scene); + view.show(); + + QTest::qWait(1000); + + QGraphicsSceneMouseEvent pressEvent(QEvent::GraphicsSceneMousePress); + QGraphicsSceneMouseEvent releaseEvent(QEvent::GraphicsSceneMouseRelease); + + // send event to child + pressEvent.setButton(Qt::LeftButton); + pressEvent.setScenePos(QPointF(25, 25));//child->mapToScene(5, 5)); + pressEvent.setScreenPos(view.mapFromScene(pressEvent.scenePos())); + releaseEvent.setButton(Qt::LeftButton); + releaseEvent.setScenePos(QPointF(25, 25));//child->mapToScene(5, 5)); + releaseEvent.setScreenPos(view.mapFromScene(pressEvent.scenePos())); + QApplication::sendEvent(&scene, &pressEvent); + QApplication::sendEvent(&scene, &releaseEvent); + + QCOMPARE(child->counter, 1); // mouse release is not filtered + QCOMPARE(filter->counter, 1); // mouse press is filtered + QCOMPARE(root->counter, 0); + + // add another filter + root->setFiltersChildEvents(true); + root->filter = QEvent::GraphicsSceneMouseRelease; + + // send event to child + QApplication::sendEvent(&scene, &pressEvent); + QApplication::sendEvent(&scene, &releaseEvent); + + QCOMPARE(child->counter, 1); + QCOMPARE(filter->counter, 2); // mouse press is filtered + QCOMPARE(root->counter, 1); // mouse release is filtered + + // reparent to another sub-graph + ChildEventTester *parent = new ChildEventTester(QRectF(10, 10, 10, 10), root); + child->setParentItem(parent); + + // send event to child + QApplication::sendEvent(&scene, &pressEvent); + QApplication::sendEvent(&scene, &releaseEvent); + + QCOMPARE(child->counter, 2); // mouse press is _not_ filtered + QCOMPARE(parent->counter, 0); + QCOMPARE(filter->counter, 2); + QCOMPARE(root->counter, 2); // mouse release is filtered +} + +void tst_QGraphicsItem::filtersChildEvents2() +{ + ChildEventFilterTester *root = new ChildEventFilterTester(QRectF(0, 0, 10, 10)); + root->setFiltersChildEvents(true); + root->filter = QEvent::GraphicsSceneMousePress; + QVERIFY(root->filtersChildEvents()); + + ChildEventTester *child = new ChildEventTester(QRectF(0, 0, 10, 10), root); + QVERIFY(!child->filtersChildEvents()); + + ChildEventTester *child2 = new ChildEventTester(QRectF(0, 0, 10, 10)); + ChildEventTester *child3 = new ChildEventTester(QRectF(0, 0, 10, 10), child2); + ChildEventTester *child4 = new ChildEventTester(QRectF(0, 0, 10, 10), child3); + + child2->setParentItem(root); + QVERIFY(!child2->filtersChildEvents()); + QVERIFY(!child3->filtersChildEvents()); + QVERIFY(!child4->filtersChildEvents()); + + QGraphicsScene scene; + scene.addItem(root); + + QGraphicsView view(&scene); + view.show(); + + QTestEventLoop::instance().enterLoop(1); + + QMouseEvent event(QEvent::MouseButtonPress, view.mapFromScene(5, 5), + view.viewport()->mapToGlobal(view.mapFromScene(5, 5)), Qt::LeftButton, 0, 0); + QApplication::sendEvent(view.viewport(), &event); + + QCOMPARE(child->counter, 0); + QCOMPARE(child2->counter, 0); + QCOMPARE(child3->counter, 0); + QCOMPARE(child4->counter, 0); + QCOMPARE(root->counter, 1); +} + class CustomItem : public QGraphicsItem { public: -- cgit v0.12 From a749d4cb3509f9a82c1d7d3b6a03e2c99dfe1842 Mon Sep 17 00:00:00 2001 From: Marius Bugge Monsen Date: Tue, 14 Jul 2009 13:30:49 +0200 Subject: Remove sendGestureEvent(). --- src/gui/graphicsview/qgraphicsscene.cpp | 68 --------------------------------- 1 file changed, 68 deletions(-) diff --git a/src/gui/graphicsview/qgraphicsscene.cpp b/src/gui/graphicsview/qgraphicsscene.cpp index e2458f5..3296775 100644 --- a/src/gui/graphicsview/qgraphicsscene.cpp +++ b/src/gui/graphicsview/qgraphicsscene.cpp @@ -3042,74 +3042,6 @@ bool QGraphicsScene::event(QEvent *event) return true; } -<<<<<<< HEAD:src/gui/graphicsview/qgraphicsscene.cpp -======= -void QGraphicsScenePrivate::sendGestureEvent(const QSet &gestures, const QSet &cancelled) -{ - Q_Q(QGraphicsScene); - typedef QMap > ItemGesturesMap; - ItemGesturesMap itemGestures; - QSet startedGestures; - for(QSet::const_iterator it = gestures.begin(), e = gestures.end(); - it != e; ++it) { - QGesture *g = *it; - Q_ASSERT(g != 0); - QGesturePrivate *gd = g->d_func(); - if (gd->graphicsItem != 0) { - itemGestures[gd->graphicsItem].insert(g); - if (g->state() == Qt::GestureStarted || gd->singleshot) - startedGestures.insert(g); - } - } - - QSet ignoredGestures; - for(ItemGesturesMap::const_iterator it = itemGestures.begin(), e = itemGestures.end(); - it != e; ++it) { - QGraphicsItem *receiver = it.key(); - Q_ASSERT(receiver != 0); - QGraphicsSceneGestureEvent event; - event.setGestures(it.value()); - event.setCancelledGestures(cancelled); - bool processed = sendEvent(receiver, &event); - QSet started = startedGestures.intersect(it.value()); - if (event.isAccepted()) - foreach(QGesture *g, started) - g->accept(); - if (!started.isEmpty() && !(processed && event.isAccepted())) { - // there are started gestures event that weren't - // accepted, so propagating each gesture independently. - QSet::const_iterator it = started.begin(), - e = started.end(); - for(; it != e; ++it) { - QGesture *g = *it; - if (processed && g->isAccepted()) { - continue; - } - QGesturePrivate *gd = g->d_func(); - QGraphicsItem *item = gd->graphicsItem; - Q_UNUSED(item); // ### REMOVE - gd->graphicsItem = 0; - - //### THIS IS BS, DONT FORGET TO REWRITE THIS CODE - // need to make sure we try to deliver event just once to each widget - const QString gestureType = g->type(); - QList itemsUnderGesture = q->items(g->hotSpot()); - for (int i = 0; i < itemsUnderGesture.size(); ++i) { - QGraphicsItem *item = itemsUnderGesture.at(i); - if (item != receiver && item->d_func()->hasGesture(gestureType)) { - ignoredGestures.insert(g); - gd->graphicsItem = item; - break; - } - } - } - } - } - if (!ignoredGestures.isEmpty()) - sendGestureEvent(ignoredGestures, cancelled); -} - ->>>>>>> 296da87... Add QGraphicsView::filtersChildEvents property.:src/gui/graphicsview/qgraphicsscene.cpp /*! \reimp -- cgit v0.12 From 9e00fcde7a13bb561aebaa5e84c94297089f0c7f Mon Sep 17 00:00:00 2001 From: Joerg Bornemann Date: Tue, 14 Jul 2009 14:13:58 +0200 Subject: micro optimization in qfsfileengine_win.cpp Use the LARGE_INTEGER union properly and don't do unnessecary bit shifting. Reviewed-by: mauricek --- src/corelib/io/qfsfileengine_win.cpp | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/corelib/io/qfsfileengine_win.cpp b/src/corelib/io/qfsfileengine_win.cpp index ee49853..618566a 100644 --- a/src/corelib/io/qfsfileengine_win.cpp +++ b/src/corelib/io/qfsfileengine_win.cpp @@ -608,8 +608,7 @@ qint64 QFSFileEnginePrivate::nativePos() const // This approach supports large files. LARGE_INTEGER currentFilePos; LARGE_INTEGER offset; - offset.LowPart = 0; - offset.HighPart = 0; + offset.QuadPart = 0; if (!ptrSetFilePointerEx(fileHandle, offset, ¤tFilePos, FILE_CURRENT)) { thatQ->setError(QFile::UnspecifiedError, qt_error_string()); return 0; @@ -652,8 +651,7 @@ bool QFSFileEnginePrivate::nativeSeek(qint64 pos) // This approach supports large files. LARGE_INTEGER currentFilePos; LARGE_INTEGER offset; - offset.LowPart = (unsigned int)(quint64(pos) & Q_UINT64_C(0xffffffff)); - offset.HighPart = (unsigned int)((quint64(pos) >> 32) & Q_UINT64_C(0xffffffff)); + offset.QuadPart = pos; if (ptrSetFilePointerEx(fileHandle, offset, ¤tFilePos, FILE_BEGIN) == 0) { thatQ->setError(QFile::UnspecifiedError, qt_error_string()); return false; -- cgit v0.12 From b427fd6bd0e5e182fa507a1930356f9cbdeacd86 Mon Sep 17 00:00:00 2001 From: Joerg Bornemann Date: Tue, 14 Jul 2009 14:15:26 +0200 Subject: large file support for Windows CE Seeking in files above 0x80000000 failed on Windows CE. SetFilePointer was used in the 32 bit version. That means, seeking only worked for positions <= LONG_MAX (which is 0x80000000 - 1). Task-number: 255242 Reviewed-by: mauricek --- src/corelib/io/qfsfileengine_win.cpp | 35 +++++++++++++++++++---------------- 1 file changed, 19 insertions(+), 16 deletions(-) diff --git a/src/corelib/io/qfsfileengine_win.cpp b/src/corelib/io/qfsfileengine_win.cpp index 618566a..5365ff5 100644 --- a/src/corelib/io/qfsfileengine_win.cpp +++ b/src/corelib/io/qfsfileengine_win.cpp @@ -588,21 +588,23 @@ qint64 QFSFileEnginePrivate::nativePos() const if (fileHandle == INVALID_HANDLE_VALUE) return 0; -#if !defined(QT_NO_LIBRARY) +#if !defined(QT_NO_LIBRARY) && !defined(Q_OS_WINCE) QFSFileEnginePrivate::resolveLibs(); if (!ptrSetFilePointerEx) { #endif - DWORD newFilePointer = SetFilePointer(fileHandle, 0, NULL, FILE_CURRENT); - if (newFilePointer == 0xFFFFFFFF) { + LARGE_INTEGER filepos; + filepos.HighPart = 0; + DWORD newFilePointer = SetFilePointer(fileHandle, 0, &filepos.HighPart, FILE_CURRENT); + if (newFilePointer == 0xFFFFFFFF && GetLastError() != NO_ERROR) { thatQ->setError(QFile::UnspecifiedError, qt_error_string()); return 0; } - // Note: returns <4GB; does not work with large files. This is the - // case for MOC, UIC, qmake and other bootstrapped tools, and for - // Win9x/ME. - return qint64(newFilePointer); -#if !defined(QT_NO_LIBRARY) + // Note: This is the case for MOC, UIC, qmake and other + // bootstrapped tools, and for Windows CE. + filepos.LowPart = newFilePointer; + return filepos.QuadPart; +#if !defined(QT_NO_LIBRARY) && !defined(Q_OS_WINCE) } // This approach supports large files. @@ -631,21 +633,22 @@ bool QFSFileEnginePrivate::nativeSeek(qint64 pos) return seekFdFh(pos); } -#if !defined(QT_NO_LIBRARY) +#if !defined(QT_NO_LIBRARY) && !defined(Q_OS_WINCE) QFSFileEnginePrivate::resolveLibs(); if (!ptrSetFilePointerEx) { #endif - LONG seekToPos = LONG(pos); // <- lossy - DWORD newFilePointer = SetFilePointer(fileHandle, seekToPos, NULL, FILE_BEGIN); - if (newFilePointer == 0xFFFFFFFF) { - thatQ->setError(QFile::UnspecifiedError, qt_error_string()); + DWORD newFilePointer; + LARGE_INTEGER *li = reinterpret_cast(&pos); + newFilePointer = SetFilePointer(fileHandle, li->LowPart, &li->HighPart, FILE_BEGIN); + if (newFilePointer == 0xFFFFFFFF && GetLastError() != NO_ERROR) { + thatQ->setError(QFile::PositionError, qt_error_string()); return false; } - // Note: does not work with large files. This is the case for MOC, - // UIC, qmake and other bootstrapped tools, and for Win9x/ME. + // Note: This is the case for MOC, UIC, qmake and other + // bootstrapped tools, and for Windows CE. return true; -#if !defined(QT_NO_LIBRARY) +#if !defined(QT_NO_LIBRARY) && !defined(Q_OS_WINCE) } // This approach supports large files. -- cgit v0.12 From 67e52d5b57e604ba82351b8edb038a5adbaf8c5a Mon Sep 17 00:00:00 2001 From: Joerg Bornemann Date: Tue, 14 Jul 2009 14:22:21 +0200 Subject: outdated comment in qfsfileengine_win.cpp removed Reviewed-by: TrustMe --- src/corelib/io/qfsfileengine_win.cpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/corelib/io/qfsfileengine_win.cpp b/src/corelib/io/qfsfileengine_win.cpp index 5365ff5..fcace33 100644 --- a/src/corelib/io/qfsfileengine_win.cpp +++ b/src/corelib/io/qfsfileengine_win.cpp @@ -607,7 +607,6 @@ qint64 QFSFileEnginePrivate::nativePos() const #if !defined(QT_NO_LIBRARY) && !defined(Q_OS_WINCE) } - // This approach supports large files. LARGE_INTEGER currentFilePos; LARGE_INTEGER offset; offset.QuadPart = 0; @@ -651,7 +650,6 @@ bool QFSFileEnginePrivate::nativeSeek(qint64 pos) #if !defined(QT_NO_LIBRARY) && !defined(Q_OS_WINCE) } - // This approach supports large files. LARGE_INTEGER currentFilePos; LARGE_INTEGER offset; offset.QuadPart = pos; -- cgit v0.12 From 93db2c44b7b01eb08ef6f447d4a84198b2dcd1e3 Mon Sep 17 00:00:00 2001 From: Robert Griebl Date: Tue, 14 Jul 2009 14:56:27 +0200 Subject: Socket function cleanup: replacing direct POSIX calls with qt_safe_(). Reviewed-By: Thiago --- src/network/kernel/qhostinfo_unix.cpp | 4 +--- src/network/kernel/qnetworkinterface_unix.cpp | 19 ++++++++-------- src/network/socket/qnativesocketengine_p.h | 29 ------------------------- src/network/socket/qnativesocketengine_unix.cpp | 6 ++--- src/network/socket/qnet_unix_p.h | 28 ++++++++++++++++++++++++ 5 files changed, 42 insertions(+), 44 deletions(-) diff --git a/src/network/kernel/qhostinfo_unix.cpp b/src/network/kernel/qhostinfo_unix.cpp index 032e575..78df510 100644 --- a/src/network/kernel/qhostinfo_unix.cpp +++ b/src/network/kernel/qhostinfo_unix.cpp @@ -53,12 +53,10 @@ static const int RESOLVER_TIMEOUT = 2000; #include #include -extern "C" { #include #include #include #include -} #if defined (QT_NO_GETADDRINFO) #include @@ -180,7 +178,7 @@ QHostInfo QHostInfoAgent::fromName(const QString &hostName) } results.setHostName(QString::fromLatin1(hbuf)); #else - in_addr_t inetaddr = inet_addr(hostName.toLatin1().constData()); + in_addr_t inetaddr = qt_safe_inet_addr(hostName.toLatin1().constData()); struct hostent *ent = gethostbyaddr((const char *)&inetaddr, sizeof(inetaddr), AF_INET); if (!ent) { results.setError(QHostInfo::HostNotFound); diff --git a/src/network/kernel/qnetworkinterface_unix.cpp b/src/network/kernel/qnetworkinterface_unix.cpp index aa27726..4efbe45 100644 --- a/src/network/kernel/qnetworkinterface_unix.cpp +++ b/src/network/kernel/qnetworkinterface_unix.cpp @@ -43,6 +43,7 @@ #include "qnetworkinterface.h" #include "qnetworkinterface_p.h" #include "qalgorithms.h" +#include "private/qnet_unix_p.h" #ifndef QT_NO_NETWORKINTERFACE @@ -123,7 +124,7 @@ static QSet interfaceNames(int socket) interfaceList.ifc_len = storageBuffer.size(); // get the interface list - if (::ioctl(socket, SIOCGIFCONF, &interfaceList) >= 0) { + if (qt_safe_ioctl(socket, SIOCGIFCONF, &interfaceList) >= 0) { if (int(interfaceList.ifc_len + sizeof(ifreq) + 64) < storageBuffer.size()) { // if the buffer was big enough, break storageBuffer.resize(interfaceList.ifc_len); @@ -198,7 +199,7 @@ static QNetworkInterfacePrivate *findInterface(int socket, QList= 0) { + if (qt_safe_ioctl(socket, SIOCGIFNAME, &req) >= 0) { iface->name = QString::fromLatin1(req.ifr_name); // reset the name: @@ -211,13 +212,13 @@ static QNetworkInterfacePrivate *findInterface(int socket, QList= 0) { + if (qt_safe_ioctl(socket, SIOCGIFFLAGS, &req) >= 0) { iface->flags = convertFlags(req.ifr_flags); } #ifdef SIOCGIFHWADDR // Get the HW address - if (::ioctl(socket, SIOCGIFHWADDR, &req) >= 0) { + if (qt_safe_ioctl(socket, SIOCGIFHWADDR, &req) >= 0) { uchar *addr = (uchar *)&req.ifr_addr; iface->hardwareAddress = iface->makeHwAddress(6, addr); } @@ -232,7 +233,7 @@ static QList interfaceListing() QList interfaces; int socket; - if ((socket = ::socket(AF_INET, SOCK_STREAM, IPPROTO_IP)) == -1) + if ((socket = qt_safe_socket(AF_INET, SOCK_STREAM, IPPROTO_IP)) == -1) return interfaces; // error QSet names = interfaceNames(socket); @@ -247,7 +248,7 @@ static QList interfaceListing() // Get the interface broadcast address QNetworkAddressEntry entry; if (iface->flags & QNetworkInterface::CanBroadcast) { - if (::ioctl(socket, SIOCGIFBRDADDR, &req) >= 0) { + if (qt_safe_ioctl(socket, SIOCGIFBRDADDR, &req) >= 0) { sockaddr *sa = &req.ifr_addr; if (sa->sa_family == AF_INET) entry.setBroadcast(addressFromSockaddr(sa)); @@ -255,13 +256,13 @@ static QList interfaceListing() } // Get the interface netmask - if (::ioctl(socket, SIOCGIFNETMASK, &req) >= 0) { + if (qt_safe_ioctl(socket, SIOCGIFNETMASK, &req) >= 0) { sockaddr *sa = &req.ifr_addr; entry.setNetmask(addressFromSockaddr(sa)); } // Get the address of the interface - if (::ioctl(socket, SIOCGIFADDR, &req) >= 0) { + if (qt_safe_ioctl(socket, SIOCGIFADDR, &req) >= 0) { sockaddr *sa = &req.ifr_addr; entry.setIp(addressFromSockaddr(sa)); } @@ -392,7 +393,7 @@ static QList interfaceListing() QList interfaces; int socket; - if ((socket = ::socket(AF_INET, SOCK_STREAM, IPPROTO_IP)) == -1) + if ((socket = qt_safe_socket(AF_INET, SOCK_STREAM, IPPROTO_IP)) == -1) return interfaces; // error ifaddrs *interfaceListing; diff --git a/src/network/socket/qnativesocketengine_p.h b/src/network/socket/qnativesocketengine_p.h index 7811635..a9479d3 100644 --- a/src/network/socket/qnativesocketengine_p.h +++ b/src/network/socket/qnativesocketengine_p.h @@ -63,35 +63,6 @@ QT_BEGIN_NAMESPACE -#ifndef Q_OS_WIN -// Almost always the same. If not, specify in qplatformdefs.h. -#if !defined(QT_SOCKOPTLEN_T) -# define QT_SOCKOPTLEN_T QT_SOCKLEN_T -#endif - -// Tru64 redefines accept -> _accept with _XOPEN_SOURCE_EXTENDED -static inline int qt_socket_accept(int s, struct sockaddr *addr, QT_SOCKLEN_T *addrlen) -{ return ::accept(s, addr, static_cast(addrlen)); } -#if defined(accept) -# undef accept -#endif - -// UnixWare 7 redefines listen -> _listen -static inline int qt_socket_listen(int s, int backlog) -{ return ::listen(s, backlog); } -#if defined(listen) -# undef listen -#endif - -// UnixWare 7 redefines socket -> _socket -static inline int qt_socket_socket(int domain, int type, int protocol) -{ return ::socket(domain, type, protocol); } -#if defined(socket) -# undef socket -#endif - -#endif - // Use our own defines and structs which we know are correct # define QT_SS_MAXSIZE 128 # define QT_SS_ALIGNSIZE (sizeof(qint64)) diff --git a/src/network/socket/qnativesocketengine_unix.cpp b/src/network/socket/qnativesocketengine_unix.cpp index 0c1fa19..3991ae6 100644 --- a/src/network/socket/qnativesocketengine_unix.cpp +++ b/src/network/socket/qnativesocketengine_unix.cpp @@ -508,7 +508,7 @@ qint64 QNativeSocketEnginePrivate::nativeBytesAvailable() const int nbytes = 0; // gives shorter than true amounts on Unix domain sockets. qint64 available = 0; - if (::ioctl(socketDescriptor, FIONREAD, (char *) &nbytes) >= 0) + if (qt_safe_ioctl(socketDescriptor, FIONREAD, (char *) &nbytes) >= 0) available = (qint64) nbytes; #if defined (QNATIVESOCKETENGINE_DEBUG) @@ -634,8 +634,8 @@ qint64 QNativeSocketEnginePrivate::nativeSendDatagram(const char *data, qint64 l ssize_t sentBytes; do { - sentBytes = ::sendto(socketDescriptor, data, len, - 0, sockAddrPtr, sockAddrSize); + sentBytes = qt_safe_sendto(socketDescriptor, data, len, + 0, sockAddrPtr, sockAddrSize); } while (sentBytes == -1 && errno == EINTR); if (sentBytes < 0) { diff --git a/src/network/socket/qnet_unix_p.h b/src/network/socket/qnet_unix_p.h index 392c1e2..b33d225 100644 --- a/src/network/socket/qnet_unix_p.h +++ b/src/network/socket/qnet_unix_p.h @@ -59,6 +59,12 @@ #include #include +// for inet_addr +#include +#include +#include + + QT_BEGIN_NAMESPACE // Almost always the same. If not, specify in qplatformdefs.h. @@ -148,6 +154,28 @@ static inline int qt_safe_connect(int sockfd, const struct sockaddr *addr, QT_SO # undef listen #endif +template +static inline int qt_safe_ioctl(int sockfd, int request, T arg) +{ + return ::ioctl(sockfd, request, arg); +} + +static inline in_addr_t qt_safe_inet_addr(const char *cp) +{ + return ::inet_addr(cp); +} + +static inline int qt_safe_sendto(int sockfd, const void *buf, size_t len, int flags, const struct sockaddr *to, QT_SOCKLEN_T tolen) +{ +#ifdef MSG_NOSIGNAL + flags |= MSG_NOSIGNAL; +#endif + + register int ret; + EINTR_LOOP(ret, ::sendto(sockfd, buf, len, flags, to, tolen)); + return ret; +} + QT_END_NAMESPACE #endif // QNET_UNIX_P_H -- cgit v0.12 From 5a2027850cd476046143f70d19a7fc07b76d46e7 Mon Sep 17 00:00:00 2001 From: Joerg Bornemann Date: Tue, 14 Jul 2009 16:50:51 +0200 Subject: support context menu for system tray icons on Windows CE This is Windows CE only. For Windows mobile we don't support context menus for system tray icons. Task-number: 250528 Reviewed-by: thartman --- src/gui/util/qsystemtrayicon_win.cpp | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/src/gui/util/qsystemtrayicon_win.cpp b/src/gui/util/qsystemtrayicon_win.cpp index dea9264..85eae26 100644 --- a/src/gui/util/qsystemtrayicon_win.cpp +++ b/src/gui/util/qsystemtrayicon_win.cpp @@ -314,7 +314,6 @@ bool QSystemTrayIconSys::winEvent( MSG *m, long *result ) emit q->activated(QSystemTrayIcon::Trigger); break; -#if !defined(Q_WS_WINCE) case WM_LBUTTONDBLCLK: emit q->activated(QSystemTrayIcon::DoubleClick); break; @@ -322,20 +321,30 @@ bool QSystemTrayIconSys::winEvent( MSG *m, long *result ) case WM_RBUTTONUP: if (q->contextMenu()) { q->contextMenu()->popup(gpos); +#if defined(Q_WS_WINCE) + // We must ensure that the popup menu doesn't show up behind the task bar. + QRect desktopRect = qApp->desktop()->availableGeometry(); + int maxY = desktopRect.y() + desktopRect.height() - q->contextMenu()->height(); + if (gpos.y() > maxY) { + gpos.ry() = maxY; + q->contextMenu()->move(gpos); + } +#endif q->contextMenu()->activateWindow(); //Must be activated for proper keyboardfocus and menu closing on windows: } emit q->activated(QSystemTrayIcon::Context); break; +#if !defined(Q_WS_WINCE) case NIN_BALLOONUSERCLICK: emit q->messageClicked(); break; +#endif case WM_MBUTTONUP: emit q->activated(QSystemTrayIcon::MiddleClick); break; -#endif default: break; } -- cgit v0.12 From a37c2d34a53f1cfcaf1dba1ff9c7175f72e75095 Mon Sep 17 00:00:00 2001 From: Markus Goetz Date: Tue, 14 Jul 2009 16:36:31 +0200 Subject: QNetworkReply: Add isFinished() method documentation improvement --- src/network/access/qnetworkreply.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/network/access/qnetworkreply.cpp b/src/network/access/qnetworkreply.cpp index e55c202..e807d29 100644 --- a/src/network/access/qnetworkreply.cpp +++ b/src/network/access/qnetworkreply.cpp @@ -442,6 +442,8 @@ QNetworkReply::NetworkError QNetworkReply::error() const } /*! + \since 4.6 + Returns true when the reply has finished or was aborted. \sa isRunning() @@ -452,6 +454,8 @@ bool QNetworkReply::isFinished() const } /*! + \since 4.6 + Returns true when the request is still processing and the reply has not finished or was aborted yet. -- cgit v0.12 From b2dbbb15ab7f61f63b54c176bf2467760240b00c Mon Sep 17 00:00:00 2001 From: Robert Griebl Date: Tue, 14 Jul 2009 17:20:34 +0200 Subject: Forgot to include qnet_unix_p.h for the qt_safe_() functions Reviewed-By: TrustMe --- src/network/kernel/qhostinfo_unix.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/network/kernel/qhostinfo_unix.cpp b/src/network/kernel/qhostinfo_unix.cpp index 78df510..fef488b 100644 --- a/src/network/kernel/qhostinfo_unix.cpp +++ b/src/network/kernel/qhostinfo_unix.cpp @@ -52,6 +52,7 @@ static const int RESOLVER_TIMEOUT = 2000; #include #include #include +#include #include #include -- cgit v0.12 From 05e3dc0d340934c681501e8d47b787ff4e68d32c Mon Sep 17 00:00:00 2001 From: David Faure Date: Wed, 15 Jul 2009 08:24:41 +1000 Subject: Improve error message from configure.exe when trying to compile the Windows phonon backend: - mention the DirectShow SDK, not the DirectX SDK (which doesn't include DirectShow anymore) - mention which exact files were not found, rather than just "all required files couldn't be found" Merge-request: 881 Reviewed-by: Rohan McGovern --- tools/configure/configureapp.cpp | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/tools/configure/configureapp.cpp b/tools/configure/configureapp.cpp index 985c317..a899adb 100644 --- a/tools/configure/configureapp.cpp +++ b/tools/configure/configureapp.cpp @@ -1858,8 +1858,14 @@ bool Configure::checkAvailability(const QString &part) if (!available) { cout << "All the required DirectShow/Direct3D files couldn't be found." << endl - << "Make sure you have either the platform SDK AND the DirectX SDK or the Windows SDK installed." << endl - << "If you have the DirectX SDK installed, please make sure that you have run the \\SetEnv.Cmd script." << endl; + << "Make sure you have either the platform SDK AND the DirectShow SDK or the Windows SDK installed." << endl + << "If you have the DirectShow SDK installed, please make sure that you have run the \\SetEnv.Cmd script." << endl; + if (!findFile("vmr9.h")) cout << "vmr9.h not found" << endl; + if (!findFile("dshow.h")) cout << "dshow.h not found" << endl; + if (!findFile("strmiids.lib")) cout << "strmiids.lib not found" << endl; + if (!findFile("dmoguids.lib")) cout << "dmoguids.lib not found" << endl; + if (!findFile("msdmo.lib")) cout << "msdmo.lib not found" << endl; + if (!findFile("d3d9.h")) cout << "d3d9.h not found" << endl; } } else if (part == "WEBKIT") { available = (dictionary.value("QMAKESPEC") == "win32-msvc2005") || (dictionary.value("QMAKESPEC") == "win32-msvc2008") || (dictionary.value("QMAKESPEC") == "win32-g++"); -- cgit v0.12 From 6574b785813d9576e64af63ddfae55ec2b429fc2 Mon Sep 17 00:00:00 2001 From: Rohan McGovern Date: Wed, 15 Jul 2009 13:21:14 +1000 Subject: Fixed selftest failure. Update maxwarnings for testlib string change. --- tests/auto/selftests/expected_maxwarnings.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/auto/selftests/expected_maxwarnings.txt b/tests/auto/selftests/expected_maxwarnings.txt index bb5e54f..8dae5f7 100644 --- a/tests/auto/selftests/expected_maxwarnings.txt +++ b/tests/auto/selftests/expected_maxwarnings.txt @@ -1,5 +1,5 @@ ********* Start testing of MaxWarnings ********* -Config: Using QTest library 4.1.0, Qt 4.1.0 +Config: Using QTest library 4.6.0, Qt 4.6.0 PASS : MaxWarnings::initTestCase() QWARN : MaxWarnings::warn() 0 QWARN : MaxWarnings::warn() 1 @@ -2002,7 +2002,7 @@ QWARN : MaxWarnings::warn() 1997 QWARN : MaxWarnings::warn() 1998 QWARN : MaxWarnings::warn() 1999 QWARN : MaxWarnings::warn() 2000 -QSYSTEM: MaxWarnings::warn() Maximum amount of warnings exceeded. +QSYSTEM: MaxWarnings::warn() Maximum amount of warnings exceeded. Use -maxwarnings to override. PASS : MaxWarnings::warn() PASS : MaxWarnings::cleanupTestCase() Totals: 3 passed, 0 failed, 0 skipped -- cgit v0.12 From 454096217002f02379b4450e6e3d312f46c8cda9 Mon Sep 17 00:00:00 2001 From: Rohan McGovern Date: Wed, 15 Jul 2009 13:27:45 +1000 Subject: Fixed recompile of tests/auto/selftests/exception. Turns out making a binary named `exception' is quite a bad idea... when some code does `#include ', guess which file gets picked up :-) --- tests/auto/selftests/exception/exception.pro | 9 --- tests/auto/selftests/exception/tst_exception.cpp | 69 ---------------------- .../selftests/exceptionthrow/exceptionthrow.pro | 9 +++ .../exceptionthrow/tst_exceptionthrow.cpp | 69 ++++++++++++++++++++++ tests/auto/selftests/expected_exception.txt | 7 --- tests/auto/selftests/expected_exceptionthrow.txt | 7 +++ tests/auto/selftests/selftests.pro | 2 +- tests/auto/selftests/selftests.qrc | 2 +- tests/auto/selftests/tst_selftests.cpp | 8 +-- 9 files changed, 91 insertions(+), 91 deletions(-) delete mode 100644 tests/auto/selftests/exception/exception.pro delete mode 100644 tests/auto/selftests/exception/tst_exception.cpp create mode 100644 tests/auto/selftests/exceptionthrow/exceptionthrow.pro create mode 100644 tests/auto/selftests/exceptionthrow/tst_exceptionthrow.cpp delete mode 100644 tests/auto/selftests/expected_exception.txt create mode 100644 tests/auto/selftests/expected_exceptionthrow.txt diff --git a/tests/auto/selftests/exception/exception.pro b/tests/auto/selftests/exception/exception.pro deleted file mode 100644 index 65705c6..0000000 --- a/tests/auto/selftests/exception/exception.pro +++ /dev/null @@ -1,9 +0,0 @@ -load(qttest_p4) -SOURCES += tst_exception.cpp -QT = core - -mac:CONFIG -= app_bundle -CONFIG -= debug_and_release_target - - -TARGET = exception diff --git a/tests/auto/selftests/exception/tst_exception.cpp b/tests/auto/selftests/exception/tst_exception.cpp deleted file mode 100644 index a54bfbe..0000000 --- a/tests/auto/selftests/exception/tst_exception.cpp +++ /dev/null @@ -1,69 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the test suite of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the either Technology Preview License Agreement or the -** Beta Release License Agreement. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain -** additional rights. These rights are described in the Nokia Qt LGPL -** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this -** package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. -** -** If you are unsure which license is appropriate for your use, please -** contact the sales department at http://www.qtsoftware.com/contact. -** $QT_END_LICENSE$ -** -****************************************************************************/ - - -#include - -class tst_Exception: public QObject -{ - Q_OBJECT - -private slots: - void throwException() const; -}; - -/*! - \internal - - We simply throw an exception to check that we get sane output/reporting. - */ -void tst_Exception::throwException() const -{ - /* When exceptions are disabled, some compilers, at least linux-g++, treat - * exception clauses as hard errors. */ -#ifndef QT_NO_EXCEPTIONS - throw 3; -#endif -} - -QTEST_MAIN(tst_Exception) - -#include "tst_exception.moc" diff --git a/tests/auto/selftests/exceptionthrow/exceptionthrow.pro b/tests/auto/selftests/exceptionthrow/exceptionthrow.pro new file mode 100644 index 0000000..641818c --- /dev/null +++ b/tests/auto/selftests/exceptionthrow/exceptionthrow.pro @@ -0,0 +1,9 @@ +load(qttest_p4) +SOURCES += tst_exceptionthrow.cpp +QT = core + +mac:CONFIG -= app_bundle +CONFIG -= debug_and_release_target + + +TARGET = exceptionthrow diff --git a/tests/auto/selftests/exceptionthrow/tst_exceptionthrow.cpp b/tests/auto/selftests/exceptionthrow/tst_exceptionthrow.cpp new file mode 100644 index 0000000..7a65c2d --- /dev/null +++ b/tests/auto/selftests/exceptionthrow/tst_exceptionthrow.cpp @@ -0,0 +1,69 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at http://www.qtsoftware.com/contact. +** $QT_END_LICENSE$ +** +****************************************************************************/ + + +#include + +class tst_Exception: public QObject +{ + Q_OBJECT + +private slots: + void throwException() const; +}; + +/*! + \internal + + We simply throw an exception to check that we get sane output/reporting. + */ +void tst_Exception::throwException() const +{ + /* When exceptions are disabled, some compilers, at least linux-g++, treat + * exception clauses as hard errors. */ +#ifndef QT_NO_EXCEPTIONS + throw 3; +#endif +} + +QTEST_MAIN(tst_Exception) + +#include "tst_exceptionthrow.moc" diff --git a/tests/auto/selftests/expected_exception.txt b/tests/auto/selftests/expected_exception.txt deleted file mode 100644 index 141ea8b..0000000 --- a/tests/auto/selftests/expected_exception.txt +++ /dev/null @@ -1,7 +0,0 @@ -********* Start testing of tst_Exception ********* -Config: Using QTest library 4.3.0, Qt 4.3.0 -PASS : tst_Exception::initTestCase() -FAIL! : tst_Exception::throwException() Caught unhandled exception - Loc: [/home/fenglich/dev/qt-4.3/tools/qtestlib/src/qtestcase.cpp(1220)] -Totals: 1 passed, 1 failed, 0 skipped -********* Finished testing of tst_Exception ********* diff --git a/tests/auto/selftests/expected_exceptionthrow.txt b/tests/auto/selftests/expected_exceptionthrow.txt new file mode 100644 index 0000000..141ea8b --- /dev/null +++ b/tests/auto/selftests/expected_exceptionthrow.txt @@ -0,0 +1,7 @@ +********* Start testing of tst_Exception ********* +Config: Using QTest library 4.3.0, Qt 4.3.0 +PASS : tst_Exception::initTestCase() +FAIL! : tst_Exception::throwException() Caught unhandled exception + Loc: [/home/fenglich/dev/qt-4.3/tools/qtestlib/src/qtestcase.cpp(1220)] +Totals: 1 passed, 1 failed, 0 skipped +********* Finished testing of tst_Exception ********* diff --git a/tests/auto/selftests/selftests.pro b/tests/auto/selftests/selftests.pro index ca69afa..45de658 100644 --- a/tests/auto/selftests/selftests.pro +++ b/tests/auto/selftests/selftests.pro @@ -3,7 +3,7 @@ TEMPLATE = subdirs SUBDIRS = subtest test warnings maxwarnings cmptest globaldata skipglobal skip \ strcmp expectfail sleep fetchbogus crashes multiexec failinit failinitdata \ skipinit skipinitdata datetime singleskip assert waitwithoutgui differentexec \ - exception qexecstringlist datatable commandlinedata\ + exceptionthrow qexecstringlist datatable commandlinedata\ benchlibwalltime benchlibcallgrind benchlibeventcounter benchlibtickcounter \ benchliboptions xunit badxml diff --git a/tests/auto/selftests/selftests.qrc b/tests/auto/selftests/selftests.qrc index d57ff29..9dc9dd0 100644 --- a/tests/auto/selftests/selftests.qrc +++ b/tests/auto/selftests/selftests.qrc @@ -25,7 +25,7 @@ expected_fatal.txt expected_waitwithoutgui.txt expected_differentexec.txt - expected_exception.txt + expected_exceptionthrow.txt expected_qexecstringlist.txt expected_datatable.txt expected_commandlinedata.txt diff --git a/tests/auto/selftests/tst_selftests.cpp b/tests/auto/selftests/tst_selftests.cpp index de51f53..ba17ccb 100644 --- a/tests/auto/selftests/tst_selftests.cpp +++ b/tests/auto/selftests/tst_selftests.cpp @@ -170,7 +170,7 @@ void tst_Selftests::runSubTest_data() // with a warning that an uncaught exception was thrown. // This will time out and falsely fail, therefore we disable the test for that platform. # if !defined(Q_CC_INTEL) || !defined(Q_OS_WIN) - QTest::newRow("exception") << "exception" << QStringList(); + QTest::newRow("exceptionthrow") << "exceptionthrow" << QStringList(); # endif #endif QTest::newRow("qexecstringlist") << "qexecstringlist" << QStringList(); @@ -207,7 +207,7 @@ void tst_Selftests::doRunSubTest(QString &subdir, QStringList &arguments ) /* Windows-MSVC decide to output an error message when exceptions are thrown, * so let's not check stderr for those. */ #if defined(Q_OS_WIN) - if(subdir != QLatin1String("exception") && subdir != QLatin1String("fetchbogus")) + if(subdir != QLatin1String("exceptionthrow") && subdir != QLatin1String("fetchbogus")) #endif if(subdir != QLatin1String("xunit")) QVERIFY2(err.isEmpty(), err.constData()); @@ -343,7 +343,7 @@ void tst_Selftests::checkXML() const * this is what windows platforms says: * "This application has requested the Runtime to terminate it in an unusual way. * Please contact the application's support team for more information." */ - if(subdir != QLatin1String("exception") && subdir != QLatin1String("fetchbogus")) + if(subdir != QLatin1String("exceptionthrow") && subdir != QLatin1String("fetchbogus")) QVERIFY2(err.isEmpty(), err.constData()); QXmlStreamReader reader(out); @@ -385,7 +385,7 @@ void tst_Selftests::checkXunitxml() const * this is what windows platforms says: * "This application has requested the Runtime to terminate it in an unusual way. * Please contact the application's support team for more information." */ - if(subdir != QLatin1String("exception") && subdir != QLatin1String("fetchbogus")) + if(subdir != QLatin1String("exceptionthrow") && subdir != QLatin1String("fetchbogus")) QVERIFY2(err.isEmpty(), err.constData()); QXmlStreamReader reader(out); -- cgit v0.12 From b96ee5694a68607f64ee9f97061fad1e8f715d94 Mon Sep 17 00:00:00 2001 From: Bill King Date: Wed, 15 Jul 2009 16:12:32 +1000 Subject: Fixes sql autotests. Now that the precisionPolicy stuff is fixed, sql server seems to be behaving correctly (with double values, but still not with string values). --- tests/auto/q3sqlcursor/tst_q3sqlcursor.cpp | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/tests/auto/q3sqlcursor/tst_q3sqlcursor.cpp b/tests/auto/q3sqlcursor/tst_q3sqlcursor.cpp index 0a2e46e..e4b1a55 100644 --- a/tests/auto/q3sqlcursor/tst_q3sqlcursor.cpp +++ b/tests/auto/q3sqlcursor/tst_q3sqlcursor.cpp @@ -574,10 +574,7 @@ void tst_Q3SqlCursor::precision() QVERIFY_SQL(cur, select()); QVERIFY( cur.next() ); - if(!tst_Databases::isSqlServer(db)) - QCOMPARE( cur.value( 0 ).asString(), precStr ); - else - QCOMPARE( cur.value( 0 ).asString(), precStr.left(precStr.size()-1) ); // Sql server fails at counting. + QCOMPARE( cur.value( 0 ).asString(), precStr ); QVERIFY( cur.next() ); QCOMPARE( cur.value( 0 ).asDouble(), precDbl ); } -- cgit v0.12 From de91fc0274dfb94f8cb665730d2e82fa8c4b3c75 Mon Sep 17 00:00:00 2001 From: Bill King Date: Wed, 15 Jul 2009 16:22:34 +1000 Subject: Fixes more sql autotests --- tests/auto/qsqldatabase/tst_qsqldatabase.cpp | 22 ++++++++++++---------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/tests/auto/qsqldatabase/tst_qsqldatabase.cpp b/tests/auto/qsqldatabase/tst_qsqldatabase.cpp index 994a3d7..e1f1d3c 100644 --- a/tests/auto/qsqldatabase/tst_qsqldatabase.cpp +++ b/tests/auto/qsqldatabase/tst_qsqldatabase.cpp @@ -353,8 +353,10 @@ void tst_QSqlDatabase::dropTestTables(QSqlDatabase db) << qTableName("bug_249059"); QSqlQuery q(0, db); - if (db.driverName().startsWith("QPSQL")) + if (db.driverName().startsWith("QPSQL")) { q.exec("drop schema " + qTableName("qtestschema") + " cascade"); + q.exec("drop schema " + qTableName("qtestScHeMa") + " cascade"); + } if (testWhiteSpaceNames(db.driverName())) tableNames << db.driver()->escapeIdentifier(qTableName("qtest") + " test", QSqlDriver::TableName); @@ -558,19 +560,19 @@ void tst_QSqlDatabase::whitespaceInIdentifiers() QString tableName = qTableName("qtest") + " test"; QVERIFY(db.tables().contains(tableName, Qt::CaseInsensitive)); - QSqlRecord rec = db.record(tableName); + QSqlRecord rec = db.record(db.driver()->escapeIdentifier(tableName, QSqlDriver::TableName)); QCOMPARE(rec.count(), 1); QCOMPARE(rec.fieldName(0), QString("test test")); if(db.driverName().startsWith("QOCI")) - QCOMPARE(rec.field(0).type(), QVariant::String); + QCOMPARE(rec.field(0).type(), QVariant::Double); else QCOMPARE(rec.field(0).type(), QVariant::Int); - QSqlIndex idx = db.primaryIndex(tableName); + QSqlIndex idx = db.primaryIndex(db.driver()->escapeIdentifier(tableName, QSqlDriver::TableName)); QCOMPARE(idx.count(), 1); QCOMPARE(idx.fieldName(0), QString("test test")); if(db.driverName().startsWith("QOCI")) - QCOMPARE(idx.field(0).type(), QVariant::String); + QCOMPARE(idx.field(0).type(), QVariant::Double); else QCOMPARE(idx.field(0).type(), QVariant::Int); } else { @@ -1522,7 +1524,7 @@ void tst_QSqlDatabase::psql_escapedIdentifiers() QSqlQuery q(db); QString schemaName = qTableName("qtestScHeMa"); - QString tableName = qTableName("qtestTaBlE"); + QString tableName = qTableName("qtest"); QString field1Name = QString("fIeLdNaMe"); QString field2Name = QString("ZuLu"); @@ -1540,7 +1542,7 @@ void tst_QSqlDatabase::psql_escapedIdentifiers() rec.append(fld1); rec.append(fld2); - QVERIFY_SQL(q, exec(drv->sqlStatement(QSqlDriver::SelectStatement, schemaName + '.' + tableName, rec, false))); + QVERIFY_SQL(q, exec(drv->sqlStatement(QSqlDriver::SelectStatement, db.driver()->escapeIdentifier(schemaName, QSqlDriver::TableName) + '.' + db.driver()->escapeIdentifier(tableName, QSqlDriver::TableName), rec, false))); rec = q.record(); QCOMPARE(rec.count(), 2); @@ -2271,15 +2273,15 @@ void tst_QSqlDatabase::eventNotificationPSQL() QSqlQuery query(db); QString procedureName = qTableName("posteventProc"); - QSqlDriver *driver=db.driver(); - QVERIFY_SQL(*driver, subscribeToNotification(procedureName)); + QSqlDriver &driver=*(db.driver()); + QVERIFY_SQL(driver, subscribeToNotification(procedureName)); QSignalSpy spy(db.driver(), SIGNAL(notification(const QString&))); query.exec(QString("NOTIFY \"%1\"").arg(procedureName)); QCoreApplication::processEvents(); QCOMPARE(spy.count(), 1); QList arguments = spy.takeFirst(); QVERIFY(arguments.at(0).toString() == procedureName); - QVERIFY_SQL(*driver, unsubscribeFromNotification(procedureName)); + QVERIFY_SQL(driver, unsubscribeFromNotification(procedureName)); } void tst_QSqlDatabase::sqlite_bindAndFetchUInt() -- cgit v0.12 From 689d4fc5aac832a3ad170c1eac20e0815149fb69 Mon Sep 17 00:00:00 2001 From: Thierry Bastian Date: Tue, 14 Jul 2009 17:37:46 +0200 Subject: remove lots of warnings with mingw --- src/3rdparty/webkit/WebCore/WebCore.pro | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/3rdparty/webkit/WebCore/WebCore.pro b/src/3rdparty/webkit/WebCore/WebCore.pro index b76cad1..b0b0290 100644 --- a/src/3rdparty/webkit/WebCore/WebCore.pro +++ b/src/3rdparty/webkit/WebCore/WebCore.pro @@ -41,7 +41,7 @@ CONFIG -= warn_on # Disable a few warnings on Windows. The warnings are also # disabled in WebKitLibraries/win/tools/vsprops/common.vsprops -win32-*: QMAKE_CXXFLAGS += -wd4291 -wd4344 +!win32-g++:win32-*: QMAKE_CXXFLAGS += -wd4291 -wd4344 unix:!mac:*-g++*:QMAKE_CXXFLAGS += -ffunction-sections -fdata-sections unix:!mac:*-g++*:QMAKE_LFLAGS += -Wl,--gc-sections -- cgit v0.12 From df830896c9c1f0818b6a8def2e19d6fd6355ab17 Mon Sep 17 00:00:00 2001 From: Thierry Bastian Date: Wed, 15 Jul 2009 09:07:37 +0200 Subject: Fix compilation of webkit with mingw --- mkspecs/features/moc.prf | 3 --- 1 file changed, 3 deletions(-) diff --git a/mkspecs/features/moc.prf b/mkspecs/features/moc.prf index 60508c8..f534171 100644 --- a/mkspecs/features/moc.prf +++ b/mkspecs/features/moc.prf @@ -15,10 +15,7 @@ WIN_INCLUDETEMP= win32:count($$list($$INCPATH), 40, >) { INCLUDETEMP = $$MOC_DIR/mocinclude.tmp - # Remove any existing mocinclude.tmp when qmake runs WIN_INCLUDETEMP=$$INCLUDETEMP - WIN_INCLUDETEMP~=s,/,\,g - system($$QMAKE_DEL_FILE $$WIN_INCLUDETEMP > NUL 2>&1) EOC = $$escape_expand(\n\t) -- cgit v0.12 From 14a07bbce2cdb5bb544cc2da8ecec617cb1961b8 Mon Sep 17 00:00:00 2001 From: Thierry Bastian Date: Wed, 15 Jul 2009 09:07:15 +0200 Subject: Rebuilt the configure.exe --- configure.exe | Bin 1101312 -> 1102848 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/configure.exe b/configure.exe index 10b926e..b4b7c50 100644 Binary files a/configure.exe and b/configure.exe differ -- cgit v0.12 From e9ded3b600256686e4a735e365988f317a51db03 Mon Sep 17 00:00:00 2001 From: Olivier Goffart Date: Mon, 13 Jul 2009 21:39:04 +0200 Subject: Fix painting of the background of QAbstractItemView, QTextEdit and co when only setting a border with the stylesheet --- src/gui/styles/qstylesheetstyle.cpp | 2 +- .../auto/uiloader/baseline/css_scrollarea_base.ui | 197 +++++++++++++++++++++ 2 files changed, 198 insertions(+), 1 deletion(-) create mode 100644 tests/auto/uiloader/baseline/css_scrollarea_base.ui diff --git a/src/gui/styles/qstylesheetstyle.cpp b/src/gui/styles/qstylesheetstyle.cpp index 01d8aad..2efa4a7 100644 --- a/src/gui/styles/qstylesheetstyle.cpp +++ b/src/gui/styles/qstylesheetstyle.cpp @@ -4171,7 +4171,7 @@ void QStyleSheetStyle::drawPrimitive(PrimitiveElement pe, const QStyleOption *op if (!rule.hasDrawable()) { QWidget *container = containerWidget(w); if (autoFillDisabledWidgets->contains(container) - && (container == w || !renderRule(container, opt).hasDrawable())) { + && (container == w || !renderRule(container, opt).hasBackground())) { //we do not have a background, but we disabled the autofillbackground anyway. so fill the background now. // (this may happen if we have rules like :focus) p->fillRect(opt->rect, opt->palette.brush(w->backgroundRole())); diff --git a/tests/auto/uiloader/baseline/css_scrollarea_base.ui b/tests/auto/uiloader/baseline/css_scrollarea_base.ui new file mode 100644 index 0000000..495401f --- /dev/null +++ b/tests/auto/uiloader/baseline/css_scrollarea_base.ui @@ -0,0 +1,197 @@ + + + Form + + + + 0 + 0 + 407 + 339 + + + + Form + + + QAbstractScrollArea { border: 2px dashed #e12; } +QHeaderView { border-color: blue; } + + + + + + + + Note that the task 257517 requires to scroll down, and check that the backgroud is still filled with the base color (white by default) + +x +x + +x +x + +x +x + +x +x + + + + + + + + + + New Row + + + + + New Row + + + + + New Row + + + + + New Row + + + + + New Row + + + + + New Row + + + + + New Row + + + + + New Row + + + + + New Row + + + + + New Row + + + + + New Row + + + + + New Row + + + + + New Row + + + + + New Row + + + + + New Column + + + + + New Column + + + + + New Column + + + + + New Column + + + + + New Column + + + + + New Column + + + + + New Column + + + + + New Column + + + + + New Column + + + + + New Column + + + + + + + + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style=" font-family:'DejaVu Sans'; font-size:10pt; font-weight:400; font-style:normal;"> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">x</p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">x</p> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">x</p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">x</p> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">x</p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">x</p> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">x</p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">x</p> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">x</p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">x</p> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"></p></body></html> + + + + + + + + -- cgit v0.12 From a72c30020bdadbe0d82e583e17acd25715604f7b Mon Sep 17 00:00:00 2001 From: Olivier Goffart Date: Mon, 13 Jul 2009 21:43:12 +0200 Subject: Bad drawing of styled viewports within QAbstractScrollArea This patch includes lots of refactoring, but the real problem was that in QWidgetPrivate::paintBackground we call drawPrimitive(PE_Widget) with a potentialy translated painter, but the opt.rect is not translated. When having a scroll area the calling function used to translated the painter and then pass the offset around to rectify. but drawPrimitive cannot rectify it. The solution is not to translate the painter but use other way to rectify the brush Task-number: 257517 Reviewed-by: bnilsen --- src/gui/kernel/qcocoaview_mac.mm | 10 +--- src/gui/kernel/qwidget.cpp | 58 ++++++++++++---------- src/gui/kernel/qwidget_mac.mm | 11 +--- src/gui/kernel/qwidget_p.h | 2 +- src/gui/styles/qmacstyle_mac.mm | 11 ++-- .../tst_qabstractscrollarea.cpp | 35 +++++++++++++ 6 files changed, 75 insertions(+), 52 deletions(-) diff --git a/src/gui/kernel/qcocoaview_mac.mm b/src/gui/kernel/qcocoaview_mac.mm index 52685ca..3e5bfb6 100644 --- a/src/gui/kernel/qcocoaview_mac.mm +++ b/src/gui/kernel/qcocoaview_mac.mm @@ -550,15 +550,7 @@ extern "C" { qwidget->objectName().local8Bit().data()); #endif QPainter p(qwidget); - QAbstractScrollArea *scrollArea = qobject_cast(qwidget->parent()); - QPoint scrollAreaOffset; - if (scrollArea && scrollArea->viewport() == qwidget) { - QAbstractScrollAreaPrivate *priv - = static_cast(qt_widget_private(scrollArea)); - scrollAreaOffset = priv->contentsOffset(); - p.translate(-scrollAreaOffset); - } - qwidgetprivate->paintBackground(&p, qrgn, scrollAreaOffset, + qwidgetprivate->paintBackground(&p, qrgn, qwidget->isWindow() ? QWidgetPrivate::DrawAsRoot : 0); p.end(); } diff --git a/src/gui/kernel/qwidget.cpp b/src/gui/kernel/qwidget.cpp index 5f076ff..7026525 100644 --- a/src/gui/kernel/qwidget.cpp +++ b/src/gui/kernel/qwidget.cpp @@ -1966,10 +1966,9 @@ void QPixmap::fill( const QWidget *widget, const QPoint &off ) QPainter p(this); p.translate(-off); widget->d_func()->paintBackground(&p, QRect(off, size())); - } -static inline void fillRegion(QPainter *painter, const QRegion &rgn, const QPoint &offset, const QBrush &brush) +static inline void fillRegion(QPainter *painter, const QRegion &rgn, const QBrush &brush) { Q_ASSERT(painter); @@ -1978,26 +1977,39 @@ static inline void fillRegion(QPainter *painter, const QRegion &rgn, const QPoin // Optimize pattern filling on mac by using HITheme directly // when filling with the standard widget background. // Defined in qmacstyle_mac.cpp - extern void qt_mac_fill_background(QPainter *painter, const QRegion &rgn, const QPoint &offset, const QBrush &brush); - qt_mac_fill_background(painter, rgn, offset, brush); + extern void qt_mac_fill_background(QPainter *painter, const QRegion &rgn, const QBrush &brush); + qt_mac_fill_background(painter, rgn, brush); #else - const QRegion translated = rgn.translated(offset); - const QRect rect(translated.boundingRect()); - painter->setClipRegion(translated); + const QRect rect(rgn.boundingRect()); + painter->setClipRegion(rgn); painter->drawTiledPixmap(rect, brush.texture(), rect.topLeft()); #endif } else { const QVector &rects = rgn.rects(); for (int i = 0; i < rects.size(); ++i) - painter->fillRect(rects.at(i).translated(offset), brush); + painter->fillRect(rects.at(i), brush); } } - -void QWidgetPrivate::paintBackground(QPainter *painter, const QRegion &rgn, const QPoint &offset, int flags) const +void QWidgetPrivate::paintBackground(QPainter *painter, const QRegion &rgn, int flags) const { Q_Q(const QWidget); +#ifndef QT_NO_SCROLLAREA + bool resetBrushOrigin = false; + QPointF oldBrushOrigin; + //If we are painting the viewport of a scrollarea, we must apply an offset to the brush in case we are drawing a texture + QAbstractScrollArea *scrollArea = qobject_cast(parent); + if (scrollArea && scrollArea->viewport() == q) { + QObjectData *scrollPrivate = static_cast(scrollArea)->d_ptr; + QAbstractScrollAreaPrivate *priv = static_cast(scrollPrivate); + oldBrushOrigin = painter->brushOrigin(); + resetBrushOrigin = true; + painter->setBrushOrigin(-priv->contentsOffset()); + + } +#endif // QT_NO_SCROLLAREA + const QBrush autoFillBrush = q->palette().brush(q->backgroundRole()); if ((flags & DrawAsRoot) && !(q->autoFillBackground() && autoFillBrush.isOpaque())) { @@ -2006,18 +2018,24 @@ void QWidgetPrivate::paintBackground(QPainter *painter, const QRegion &rgn, cons if (!(flags & DontSetCompositionMode) && painter->paintEngine()->hasFeature(QPaintEngine::PorterDuff)) painter->setCompositionMode(QPainter::CompositionMode_Source); //copy alpha straight in #endif - fillRegion(painter, rgn, offset, bg); + fillRegion(painter, rgn, bg); } if (q->autoFillBackground()) - fillRegion(painter, rgn, offset, autoFillBrush); + fillRegion(painter, rgn, autoFillBrush); + if (q->testAttribute(Qt::WA_StyledBackground)) { - painter->setClipRegion(rgn.translated(offset)); + painter->setClipRegion(rgn); QStyleOption opt; opt.initFrom(q); q->style()->drawPrimitive(QStyle::PE_Widget, &opt, painter, q); } + +#ifndef QT_NO_SCROLLAREA + if (resetBrushOrigin) + painter->setBrushOrigin(oldBrushOrigin); +#endif // QT_NO_SCROLLAREA } /* @@ -4998,19 +5016,7 @@ void QWidgetPrivate::drawWidget(QPaintDevice *pdev, const QRegion &rgn, const QP && !q->testAttribute(Qt::WA_OpaquePaintEvent) && !q->testAttribute(Qt::WA_NoSystemBackground)) { QPainter p(q); - QPoint scrollAreaOffset; - -#ifndef QT_NO_SCROLLAREA - QAbstractScrollArea *scrollArea = qobject_cast(parent); - if (scrollArea && scrollArea->viewport() == q) { - QObjectData *scrollPrivate = static_cast(scrollArea)->d_ptr; - QAbstractScrollAreaPrivate *priv = static_cast(scrollPrivate); - scrollAreaOffset = priv->contentsOffset(); - p.translate(-scrollAreaOffset); - } -#endif // QT_NO_SCROLLAREA - - paintBackground(&p, toBePainted, scrollAreaOffset, (asRoot || onScreen) ? flags | DrawAsRoot : 0); + paintBackground(&p, toBePainted, (asRoot || onScreen) ? flags | DrawAsRoot : 0); } if (!sharedPainter) diff --git a/src/gui/kernel/qwidget_mac.mm b/src/gui/kernel/qwidget_mac.mm index 5577224..84c3def 100644 --- a/src/gui/kernel/qwidget_mac.mm +++ b/src/gui/kernel/qwidget_mac.mm @@ -1198,16 +1198,7 @@ OSStatus QWidgetPrivate::qt_widget_event(EventHandlerCallRef er, EventRef event, p.setClipping(false); if(was_unclipped) widget->setAttribute(Qt::WA_PaintUnclipped); - - QAbstractScrollArea *scrollArea = qobject_cast(widget->parent()); - QPoint scrollAreaOffset; - if (scrollArea && scrollArea->viewport() == widget) { - QAbstractScrollAreaPrivate *priv = static_cast(static_cast(scrollArea)->d_ptr); - scrollAreaOffset = priv->contentsOffset(); - p.translate(-scrollAreaOffset); - } - - widget->d_func()->paintBackground(&p, qrgn, scrollAreaOffset, widget->isWindow() ? DrawAsRoot : 0); + widget->d_func()->paintBackground(&p, qrgn, widget->isWindow() ? DrawAsRoot : 0); if (widget->testAttribute(Qt::WA_TintedBackground)) { QColor tint = widget->palette().window().color(); tint.setAlphaF(.6); diff --git a/src/gui/kernel/qwidget_p.h b/src/gui/kernel/qwidget_p.h index 626950e..998181e 100644 --- a/src/gui/kernel/qwidget_p.h +++ b/src/gui/kernel/qwidget_p.h @@ -295,7 +295,7 @@ public: void setUpdatesEnabled_helper(bool ); - void paintBackground(QPainter *, const QRegion &, const QPoint & = QPoint(), int flags = DrawAsRoot) const; + void paintBackground(QPainter *, const QRegion &, int flags = DrawAsRoot) const; bool isAboutToShow() const; QRegion prepareToRender(const QRegion ®ion, QWidget::RenderFlags renderFlags); void render_helper(QPainter *painter, const QPoint &targetOffset, const QRegion &sourceRegion, diff --git a/src/gui/styles/qmacstyle_mac.mm b/src/gui/styles/qmacstyle_mac.mm index c08009b..5d75392 100644 --- a/src/gui/styles/qmacstyle_mac.mm +++ b/src/gui/styles/qmacstyle_mac.mm @@ -1871,24 +1871,23 @@ QPixmap QMacStylePrivate::generateBackgroundPattern() const Fills the given \a rect with the pattern stored in \a brush. As an optimization, HIThemeSetFill us used directly if we are filling with the standard background. */ -void qt_mac_fill_background(QPainter *painter, const QRegion &rgn, const QPoint &offset, const QBrush &brush) +void qt_mac_fill_background(QPainter *painter, const QRegion &rgn, const QBrush &brush) { QPoint dummy; const QPaintDevice *target = painter->device(); const QPaintDevice *redirected = QPainter::redirected(target, &dummy); const bool usePainter = redirected && redirected != target; - const QRegion translated = rgn.translated(offset); if (!usePainter && qt_mac_backgroundPattern && qt_mac_backgroundPattern->cacheKey() == brush.texture().cacheKey()) { - painter->setClipRegion(translated); + painter->setClipRegion(rgn); CGContextRef cg = qt_mac_cg_context(target); CGContextSaveGState(cg); HIThemeSetFill(kThemeBrushDialogBackgroundActive, 0, cg, kHIThemeOrientationInverted); - const QVector &rects = translated.rects(); + const QVector &rects = rgn.rects(); for (int i = 0; i < rects.size(); ++i) { const QRect rect(rects.at(i)); // Anchor the pattern to the top so it stays put when the window is resized. @@ -1899,8 +1898,8 @@ void qt_mac_fill_background(QPainter *painter, const QRegion &rgn, const QPoint CGContextRestoreGState(cg); } else { - const QRect rect(translated.boundingRect()); - painter->setClipRegion(translated); + const QRect rect(rgn.boundingRect()); + painter->setClipRegion(rgn); painter->drawTiledPixmap(rect, brush.texture(), rect.topLeft()); } } diff --git a/tests/auto/qabstractscrollarea/tst_qabstractscrollarea.cpp b/tests/auto/qabstractscrollarea/tst_qabstractscrollarea.cpp index e976c1b..556e850 100644 --- a/tests/auto/qabstractscrollarea/tst_qabstractscrollarea.cpp +++ b/tests/auto/qabstractscrollarea/tst_qabstractscrollarea.cpp @@ -66,6 +66,7 @@ private slots: void setScrollBars(); void setScrollBars2(); void objectNaming(); + void patternBackground(); void viewportCrash(); void task214488_layoutDirection_data(); @@ -350,5 +351,39 @@ void tst_QAbstractScrollArea::task214488_layoutDirection() QVERIFY(lessThan ? (hbar->value() < refValue) : (hbar->value() > refValue)); } +void tst_QAbstractScrollArea::patternBackground() +{ + QScrollArea scrollArea; + scrollArea.resize(200, 200); + QWidget widget; + widget.resize(600, 600); + scrollArea.setWidget(&widget); + scrollArea.show(); + + QLinearGradient linearGrad(QPointF(250, 250), QPointF(300, 300)); + linearGrad.setColorAt(0, Qt::yellow); + linearGrad.setColorAt(1, Qt::red); + QBrush bg(linearGrad); + scrollArea.viewport()->setPalette(QPalette(Qt::black, bg, bg, bg, bg, bg, bg, bg, bg)); + widget.setPalette(Qt::transparent); + + QTest::qWait(50); + + QImage image(200, 200, QImage::Format_ARGB32); + scrollArea.render(&image); + + QCOMPARE(image.pixel(QPoint(20,20)) , QColor(Qt::yellow).rgb()); + + QScrollBar *hbar = scrollArea.horizontalScrollBar(); + hbar->setValue(hbar->maximum()); + QScrollBar *vbar = scrollArea.verticalScrollBar(); + vbar->setValue(vbar->maximum()); + + QTest::qWait(50); + + scrollArea.render(&image); + QCOMPARE(image.pixel(QPoint(20,20)) , QColor(Qt::red).rgb()); +} + QTEST_MAIN(tst_QAbstractScrollArea) #include "tst_qabstractscrollarea.moc" -- cgit v0.12 From c358eab1eb68388f9cf4a921cd6ef316bb37a3a8 Mon Sep 17 00:00:00 2001 From: Joerg Bornemann Date: Wed, 15 Jul 2009 12:04:15 +0200 Subject: repair the mouse cursor on Windows CE The LoadImage function doesn't seem to work for loading cursors from resources. Also, it isn't marked as deprecated for Windows CE like on desktop Windows. So we'll just use it again. Reviewed-by: thartman --- src/gui/kernel/qcursor_win.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/gui/kernel/qcursor_win.cpp b/src/gui/kernel/qcursor_win.cpp index db00835..26e395c 100644 --- a/src/gui/kernel/qcursor_win.cpp +++ b/src/gui/kernel/qcursor_win.cpp @@ -476,7 +476,11 @@ void QCursorData::update() qWarning("QCursor::update: Invalid cursor shape %d", cshape); return; } +#ifdef Q_WS_WINCE + hcurs = LoadCursor(0, sh); +#else hcurs = (HCURSOR)LoadImage(0, sh, IMAGE_CURSOR, 0, 0, LR_DEFAULTSIZE | LR_SHARED); +#endif } QT_END_NAMESPACE -- cgit v0.12 From 28d0930593c6c04a7ef538353f8bee55df00a0e8 Mon Sep 17 00:00:00 2001 From: Robert Griebl Date: Wed, 15 Jul 2009 12:25:50 +0200 Subject: Fix Solaris build failure with the new qt_safe_() socket functions. Reviewed-by: Thiago --- src/network/socket/qnet_unix_p.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/network/socket/qnet_unix_p.h b/src/network/socket/qnet_unix_p.h index b33d225..03ed3b4 100644 --- a/src/network/socket/qnet_unix_p.h +++ b/src/network/socket/qnet_unix_p.h @@ -138,7 +138,8 @@ static inline int qt_safe_listen(int s, int backlog) static inline int qt_safe_connect(int sockfd, const struct sockaddr *addr, QT_SOCKLEN_T addrlen) { register int ret; - EINTR_LOOP(ret, QT_SOCKET_CONNECT(sockfd, addr, addrlen)); + // Solaris e.g. expects a non-const 2nd parameter + EINTR_LOOP(ret, QT_SOCKET_CONNECT(sockfd, const_cast(addr), addrlen)); return ret; } #undef QT_SOCKET_CONNECT -- cgit v0.12 From 0d721a3b390b3f542be594941430ecfcac29f0ac Mon Sep 17 00:00:00 2001 From: Kavindra Devi Palaraja Date: Wed, 15 Jul 2009 12:39:13 +0200 Subject: Doc - fixed a typo Reviewed-By: TrustMe Task: 257919 --- doc/src/designer-manual.qdoc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/src/designer-manual.qdoc b/doc/src/designer-manual.qdoc index 25e7455..c67865d 100644 --- a/doc/src/designer-manual.qdoc +++ b/doc/src/designer-manual.qdoc @@ -1360,7 +1360,7 @@ inside. Both widgets and spacers can be used inside containers. Stacked widgets, tab widgets, and toolboxes are handled specially in \QD. - Norwally, when adding pages (tabs, pages, compartments) to these containers + Normally, when adding pages (tabs, pages, compartments) to these containers in your own code, you need to supply existing widgets, either as placeholders or containing child widgets. In \QD, these are automatically created for you, so you can add child objects to each page straight away. -- cgit v0.12 From fc7a6a7f9f857c4745476213ee41d9a92ce82a9c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B8rn=20Erik=20Nilsen?= Date: Mon, 13 Jul 2009 16:35:34 +0200 Subject: Make Graphics View auto-tests less dependant on WS. Several auto-tests failed on the Mac because the view get two paint events on the first show. This is a bug in QWidget, but shouldn't make graphics view auto-tests fail. Also, there's no difference between update() and repaint() on the Mac. --- tests/auto/qgraphicsitem/tst_qgraphicsitem.cpp | 27 ++++++++++++++++++-------- tests/auto/qgraphicsview/tst_qgraphicsview.cpp | 18 +++++++++-------- 2 files changed, 29 insertions(+), 16 deletions(-) diff --git a/tests/auto/qgraphicsitem/tst_qgraphicsitem.cpp b/tests/auto/qgraphicsitem/tst_qgraphicsitem.cpp index 3f41a90..f58cad2 100644 --- a/tests/auto/qgraphicsitem/tst_qgraphicsitem.cpp +++ b/tests/auto/qgraphicsitem/tst_qgraphicsitem.cpp @@ -4478,14 +4478,13 @@ void tst_QGraphicsItem::paint() view.hide(); QGraphicsScene scene2; + QGraphicsView view2(&scene2); + view2.show(); + QTest::qWait(250); PaintTester tester2; scene2.addItem(&tester2); - - QGraphicsView view2(&scene2); - view2.show(); qApp->processEvents(); - QTest::qWait(250); //First show one paint QVERIFY(tester2.painted == 1); @@ -5570,11 +5569,12 @@ public: void tst_QGraphicsItem::ensureUpdateOnTextItem() { QGraphicsScene scene; - TextItem *text1 = new TextItem(QLatin1String("123")); - scene.addItem(text1); QGraphicsView view(&scene); view.show(); QTest::qWait(250); + TextItem *text1 = new TextItem(QLatin1String("123")); + scene.addItem(text1); + qApp->processEvents(); QCOMPARE(text1->updates,1); //same bouding rect but we have to update @@ -6034,14 +6034,15 @@ void tst_QGraphicsItem::itemStacksBehindParent() scene.addItem(parent1); scene.addItem(parent2); - paintedItems.clear(); - QGraphicsView view(&scene); view.show(); #ifdef Q_WS_X11 qt_x11_wait_for_window_manager(&view); #endif QTest::qWait(250); + paintedItems.clear(); + view.viewport()->update(); + QTest::qWait(100); QCOMPARE(scene.items(0, 0, 100, 100), (QList() << grandChild111 << child11 @@ -7247,6 +7248,11 @@ void tst_QGraphicsItem::sorting() _paintedItems.clear(); view.viewport()->repaint(); +#ifdef Q_WS_MAC + // There's no difference between repaint and update on the Mac, + // so we have to process events here to make sure we get the event. + QTest::qWait(100); +#endif QCOMPARE(_paintedItems, QList() << grid[0][0] << grid[0][1] << grid[0][2] << grid[0][3] @@ -7279,6 +7285,11 @@ void tst_QGraphicsItem::itemHasNoContents() _paintedItems.clear(); view.viewport()->repaint(); +#ifdef Q_WS_MAC + // There's no difference between update() and repaint() on the Mac, + // so we have to process events here to make sure we get the event. + QTest::qWait(100); +#endif QCOMPARE(_paintedItems, QList() << item2); } diff --git a/tests/auto/qgraphicsview/tst_qgraphicsview.cpp b/tests/auto/qgraphicsview/tst_qgraphicsview.cpp index 9a5089b..37c5967 100644 --- a/tests/auto/qgraphicsview/tst_qgraphicsview.cpp +++ b/tests/auto/qgraphicsview/tst_qgraphicsview.cpp @@ -3338,6 +3338,15 @@ void tst_QGraphicsView::render() { // ### This test can be much more thorough - see QGraphicsScene::render. QGraphicsScene scene; + QGraphicsView view(&scene); + view.setFrameStyle(0); + view.resize(200, 200); + view.show(); +#ifdef Q_WS_X11 + qt_x11_wait_for_window_manager(&view); +#endif + QTest::qWait(200); + RenderTester *r1 = new RenderTester(QRectF(0, 0, 50, 50)); RenderTester *r2 = new RenderTester(QRectF(50, 50, 50, 50)); RenderTester *r3 = new RenderTester(QRectF(0, 50, 50, 50)); @@ -3347,14 +3356,7 @@ void tst_QGraphicsView::render() scene.addItem(r3); scene.addItem(r4); - QGraphicsView view(&scene); - view.setFrameStyle(0); - view.resize(200, 200); - view.show(); -#ifdef Q_WS_X11 - qt_x11_wait_for_window_manager(&view); -#endif - QTest::qWait(200); + qApp->processEvents(); QCOMPARE(r1->paints, 1); QCOMPARE(r2->paints, 1); -- cgit v0.12 From 147d6c45f6ecfb26ba5de55ea19cc8854c6bee64 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B8rn=20Erik=20Nilsen?= Date: Wed, 15 Jul 2009 12:37:43 +0200 Subject: Compile after a72c30020bdadbe0d82e583e17acd25715604f7b We don't translate the painter anymore (we instead set the brush origin), so we don't have to (and shouldn't) translate the rects here. --- src/gui/kernel/qwidget_mac.mm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/gui/kernel/qwidget_mac.mm b/src/gui/kernel/qwidget_mac.mm index 84c3def..1717fbd 100644 --- a/src/gui/kernel/qwidget_mac.mm +++ b/src/gui/kernel/qwidget_mac.mm @@ -1204,7 +1204,7 @@ OSStatus QWidgetPrivate::qt_widget_event(EventHandlerCallRef er, EventRef event, tint.setAlphaF(.6); const QVector &rects = qrgn.rects(); for (int i = 0; i < rects.size(); ++i) - p.fillRect(rects.at(i).translated(scrollAreaOffset), tint); + p.fillRect(rects.at(i), tint); } p.end(); if (!redirectionOffset.isNull()) -- cgit v0.12 From 1eafb5c771a10377216af0f2be873c08d6cd4e27 Mon Sep 17 00:00:00 2001 From: Volker Hilsheimer Date: Wed, 15 Jul 2009 14:04:36 +0200 Subject: Fix license header in new files - make testcase pass. --- src/gui/graphicsview/qgraphicsscenebsptreeindex_p.h | 6 +++--- src/gui/graphicsview/qgraphicssceneindex_p.h | 6 +++--- src/gui/graphicsview/qgraphicsscenelinearindex_p.h | 6 +++--- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/src/gui/graphicsview/qgraphicsscenebsptreeindex_p.h b/src/gui/graphicsview/qgraphicsscenebsptreeindex_p.h index 2e02458..ed5fa8e 100644 --- a/src/gui/graphicsview/qgraphicsscenebsptreeindex_p.h +++ b/src/gui/graphicsview/qgraphicsscenebsptreeindex_p.h @@ -1,9 +1,9 @@ /**************************************************************************** ** ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** Contact: Qt Software Information (qt-info@nokia.com) +** Contact: Nokia Corporation (qt-info@nokia.com) ** -** This file is part of the QtGui module of the Qt Toolkit. +** This file is part of the QtCore module of the Qt Toolkit. ** ** $QT_BEGIN_LICENSE:LGPL$ ** No Commercial Usage @@ -34,7 +34,7 @@ ** met: http://www.gnu.org/copyleft/gpl.html. ** ** If you are unsure which license is appropriate for your use, please -** contact the sales department at qt-sales@nokia.com. +** contact the sales department at http://www.qtsoftware.com/contact. ** $QT_END_LICENSE$ ** ****************************************************************************/ diff --git a/src/gui/graphicsview/qgraphicssceneindex_p.h b/src/gui/graphicsview/qgraphicssceneindex_p.h index 8cf0294..37dffb8 100644 --- a/src/gui/graphicsview/qgraphicssceneindex_p.h +++ b/src/gui/graphicsview/qgraphicssceneindex_p.h @@ -1,9 +1,9 @@ /**************************************************************************** ** ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** Contact: Qt Software Information (qt-info@nokia.com) +** Contact: Nokia Corporation (qt-info@nokia.com) ** -** This file is part of the QtGui module of the Qt Toolkit. +** This file is part of the QtCore module of the Qt Toolkit. ** ** $QT_BEGIN_LICENSE:LGPL$ ** No Commercial Usage @@ -34,7 +34,7 @@ ** met: http://www.gnu.org/copyleft/gpl.html. ** ** If you are unsure which license is appropriate for your use, please -** contact the sales department at qt-sales@nokia.com. +** contact the sales department at http://www.qtsoftware.com/contact. ** $QT_END_LICENSE$ ** ****************************************************************************/ diff --git a/src/gui/graphicsview/qgraphicsscenelinearindex_p.h b/src/gui/graphicsview/qgraphicsscenelinearindex_p.h index 56dde3a..3dbbc63 100644 --- a/src/gui/graphicsview/qgraphicsscenelinearindex_p.h +++ b/src/gui/graphicsview/qgraphicsscenelinearindex_p.h @@ -1,9 +1,9 @@ /**************************************************************************** ** ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** Contact: Qt Software Information (qt-info@nokia.com) +** Contact: Nokia Corporation (qt-info@nokia.com) ** -** This file is part of the QtGui module of the Qt Toolkit. +** This file is part of the QtCore module of the Qt Toolkit. ** ** $QT_BEGIN_LICENSE:LGPL$ ** No Commercial Usage @@ -34,7 +34,7 @@ ** met: http://www.gnu.org/copyleft/gpl.html. ** ** If you are unsure which license is appropriate for your use, please -** contact the sales department at qt-sales@nokia.com. +** contact the sales department at http://www.qtsoftware.com/contact. ** $QT_END_LICENSE$ ** ****************************************************************************/ -- cgit v0.12 From 271358459d605e909f4ec093b971a420ff730e8f Mon Sep 17 00:00:00 2001 From: Thierry Bastian Date: Wed, 15 Jul 2009 10:40:41 +0200 Subject: fix warnings for mingw in QtCore --- src/corelib/global/qglobal.cpp | 2 +- src/corelib/io/qfsfileengine_win.cpp | 10 +++++----- src/corelib/kernel/qcoreapplication_win.cpp | 4 ++-- src/corelib/tools/qlocale.cpp | 4 ++-- src/corelib/tools/qstring.cpp | 2 +- 5 files changed, 11 insertions(+), 11 deletions(-) diff --git a/src/corelib/global/qglobal.cpp b/src/corelib/global/qglobal.cpp index ad4868d..f7d6514 100644 --- a/src/corelib/global/qglobal.cpp +++ b/src/corelib/global/qglobal.cpp @@ -1668,7 +1668,7 @@ QSysInfo::WinVersion QSysInfo::windowsVersion() winver = QSysInfo::WV_WINDOWS7; } else { qWarning("Qt: Untested Windows version %d.%d detected!", - osver.dwMajorVersion, osver.dwMinorVersion); + int(osver.dwMajorVersion), int(osver.dwMinorVersion)); winver = QSysInfo::WV_NT_based; } } diff --git a/src/corelib/io/qfsfileengine_win.cpp b/src/corelib/io/qfsfileengine_win.cpp index fcace33..885ba39 100644 --- a/src/corelib/io/qfsfileengine_win.cpp +++ b/src/corelib/io/qfsfileengine_win.cpp @@ -109,9 +109,9 @@ static QString qfsPrivateCurrentDir = QLatin1String(""); QT_BEGIN_INCLUDE_NAMESPACE typedef DWORD (WINAPI *PtrGetNamedSecurityInfoW)(LPWSTR, SE_OBJECT_TYPE, SECURITY_INFORMATION, PSID*, PSID*, PACL*, PACL*, PSECURITY_DESCRIPTOR*); static PtrGetNamedSecurityInfoW ptrGetNamedSecurityInfoW = 0; -typedef DECLSPEC_IMPORT BOOL (WINAPI *PtrLookupAccountSidW)(LPCWSTR, PSID, LPWSTR, LPDWORD, LPWSTR, LPDWORD, PSID_NAME_USE); +typedef BOOL (WINAPI *PtrLookupAccountSidW)(LPCWSTR, PSID, LPWSTR, LPDWORD, LPWSTR, LPDWORD, PSID_NAME_USE); static PtrLookupAccountSidW ptrLookupAccountSidW = 0; -typedef DECLSPEC_IMPORT BOOL (WINAPI *PtrAllocateAndInitializeSid)(PSID_IDENTIFIER_AUTHORITY, BYTE, DWORD, DWORD, DWORD, DWORD, DWORD, DWORD, DWORD, DWORD, PSID*); +typedef BOOL (WINAPI *PtrAllocateAndInitializeSid)(PSID_IDENTIFIER_AUTHORITY, BYTE, DWORD, DWORD, DWORD, DWORD, DWORD, DWORD, DWORD, DWORD, PSID*); static PtrAllocateAndInitializeSid ptrAllocateAndInitializeSid = 0; typedef VOID (WINAPI *PtrBuildTrusteeWithSidW)(PTRUSTEE_W, PSID); static PtrBuildTrusteeWithSidW ptrBuildTrusteeWithSidW = 0; @@ -119,7 +119,7 @@ typedef VOID (WINAPI *PtrBuildTrusteeWithNameW)(PTRUSTEE_W, unsigned short*); static PtrBuildTrusteeWithNameW ptrBuildTrusteeWithNameW = 0; typedef DWORD (WINAPI *PtrGetEffectiveRightsFromAclW)(PACL, PTRUSTEE_W, OUT PACCESS_MASK); static PtrGetEffectiveRightsFromAclW ptrGetEffectiveRightsFromAclW = 0; -typedef DECLSPEC_IMPORT PVOID (WINAPI *PtrFreeSid)(PSID); +typedef PVOID (WINAPI *PtrFreeSid)(PSID); static PtrFreeSid ptrFreeSid = 0; static TRUSTEE_W currentUserTrusteeW; @@ -1519,8 +1519,8 @@ QString QFSFileEngine::fileName(FileName file) const if (!isRelativePath()) { #if !defined(Q_OS_WINCE) - if (d->filePath.size() > 2 && d->filePath.at(1) == QLatin1Char(':') - && d->filePath.at(2) != QLatin1Char('/') || // It's a drive-relative path, so Z:a.txt -> Z:\currentpath\a.txt + if ((d->filePath.size() > 2 && d->filePath.at(1) == QLatin1Char(':') + && d->filePath.at(2) != QLatin1Char('/')) || // It's a drive-relative path, so Z:a.txt -> Z:\currentpath\a.txt d->filePath.startsWith(QLatin1Char('/')) // It's a absolute path to the current drive, so \a.txt -> Z:\a.txt ) { ret = QDir::fromNativeSeparators(nativeAbsoluteFilePath(d->filePath)); diff --git a/src/corelib/kernel/qcoreapplication_win.cpp b/src/corelib/kernel/qcoreapplication_win.cpp index a71f284..bf5716a 100644 --- a/src/corelib/kernel/qcoreapplication_win.cpp +++ b/src/corelib/kernel/qcoreapplication_win.cpp @@ -280,7 +280,7 @@ QT_END_INCLUDE_NAMESPACE // The values below should never change. Note that none of the usual // WM_...FIRST & WM_...LAST values are in the list, as they normally have other // WM_... representations -struct { +struct KnownWM { uint WM; const char* str; } knownWM[] = @@ -582,7 +582,7 @@ struct { { 0,0 }}; // End of known messages // Looks up the WM_ message in the table above -const char* findWMstr(uint msg) +static const char* findWMstr(uint msg) { uint i = 0; const char* result = 0; diff --git a/src/corelib/tools/qlocale.cpp b/src/corelib/tools/qlocale.cpp index fef1931..296d5a0 100644 --- a/src/corelib/tools/qlocale.cpp +++ b/src/corelib/tools/qlocale.cpp @@ -413,8 +413,8 @@ QByteArray getWinLocaleName(LCID id = LOCALE_USER_DEFAULT) result = envVarLocale(); QChar lang[3]; QChar cntry[2]; - if ( result == "C" || !result.isEmpty() - && splitLocaleName(QString::fromLocal8Bit(result), lang, cntry) ) { + if ( result == "C" || (!result.isEmpty() + && splitLocaleName(QString::fromLocal8Bit(result), lang, cntry)) ) { long id = 0; bool ok = false; id = qstrtoll(result.data(), 0, 0, &ok); diff --git a/src/corelib/tools/qstring.cpp b/src/corelib/tools/qstring.cpp index b160b90..7cca339 100644 --- a/src/corelib/tools/qstring.cpp +++ b/src/corelib/tools/qstring.cpp @@ -3480,7 +3480,7 @@ QByteArray QString::toAscii() const return toLatin1(); } -#ifndef Q_WS_MAC +#if !defined(Q_WS_MAC) && defined(Q_OS_UNIX) static QByteArray toLocal8Bit_helper(const QChar *data, int length) { #ifndef QT_NO_TEXTCODEC -- cgit v0.12 From a6782030bc6077b3b1ffe380dfd303cfb7662795 Mon Sep 17 00:00:00 2001 From: Thierry Bastian Date: Wed, 15 Jul 2009 14:02:43 +0200 Subject: Fix warnings for mingw did a small refactor and used QStyleHelper::uniqueName in plastique and windows styles --- src/gui/dialogs/qwizard.cpp | 4 +- src/gui/dialogs/qwizard_win.cpp | 4 +- src/gui/kernel/qapplication_win.cpp | 42 +++++++------ src/gui/kernel/qkeymapper_win.cpp | 8 +-- src/gui/kernel/qmime_win.cpp | 2 +- src/gui/painting/qdrawutil.cpp | 3 +- src/gui/painting/qdrawutil.h | 7 +-- src/gui/painting/qpaintengine_raster.cpp | 102 ------------------------------- src/gui/styles/qplastiquestyle.cpp | 28 +++------ src/gui/styles/qstyle_p.h | 2 +- src/gui/styles/qstylehelper.cpp | 7 +-- src/gui/styles/qwindowsstyle.cpp | 9 ++- src/gui/styles/qwindowsvistastyle.cpp | 20 +++--- src/gui/styles/qwindowsxpstyle.cpp | 17 ++++-- src/gui/text/qfontengine_win.cpp | 12 +--- src/gui/text/qzip.cpp | 20 ++++-- 16 files changed, 92 insertions(+), 195 deletions(-) diff --git a/src/gui/dialogs/qwizard.cpp b/src/gui/dialogs/qwizard.cpp index a7dccd8..a97aedd 100644 --- a/src/gui/dialogs/qwizard.cpp +++ b/src/gui/dialogs/qwizard.cpp @@ -343,8 +343,8 @@ void QWizardHeader::setup(const QWizardLayoutInfo &info, const QString &title, { bool modern = ((info.wizStyle == QWizard::ModernStyle) #if !defined(QT_NO_STYLE_WINDOWSVISTA) - || ((info.wizStyle == QWizard::AeroStyle) - && (QVistaHelper::vistaState() == QVistaHelper::Classic) || vistaDisabled()) + || ((info.wizStyle == QWizard::AeroStyle + && QVistaHelper::vistaState() == QVistaHelper::Classic) || vistaDisabled()) #endif ); diff --git a/src/gui/dialogs/qwizard_win.cpp b/src/gui/dialogs/qwizard_win.cpp index 840149b..1def47f 100644 --- a/src/gui/dialogs/qwizard_win.cpp +++ b/src/gui/dialogs/qwizard_win.cpp @@ -616,7 +616,7 @@ bool QVistaHelper::drawTitleText(QPainter *painter, const QString &text, const Q // Set up a memory DC and bitmap that we'll draw into HDC dcMem; HBITMAP bmp; - BITMAPINFO dib = {0}; + BITMAPINFO dib = {{0}}; dcMem = CreateCompatibleDC(hdc); dib.bmiHeader.biSize = sizeof(BITMAPINFOHEADER); @@ -662,7 +662,7 @@ bool QVistaHelper::drawBlackRect(const QRect &rect, HDC hdc) // Set up a memory DC and bitmap that we'll draw into HDC dcMem; HBITMAP bmp; - BITMAPINFO dib = {0}; + BITMAPINFO dib = {{0}}; dcMem = CreateCompatibleDC(hdc); dib.bmiHeader.biSize = sizeof(BITMAPINFOHEADER); diff --git a/src/gui/kernel/qapplication_win.cpp b/src/gui/kernel/qapplication_win.cpp index 164a228..243e361 100644 --- a/src/gui/kernel/qapplication_win.cpp +++ b/src/gui/kernel/qapplication_win.cpp @@ -275,6 +275,8 @@ extern HRGN qt_tryCreateRegion(QRegion::RegionType type, int left, int top, int #define GET_XBUTTON_WPARAM(wParam) (HIWORD(wParam)) #define XBUTTON1 0x0001 #define XBUTTON2 0x0002 +#endif +#ifndef MK_XBUTTON1 #define MK_XBUTTON1 0x0020 #define MK_XBUTTON2 0x0040 #endif @@ -807,9 +809,10 @@ void qt_init(QApplicationPrivate *priv, int) ptrUpdateLayeredWindowIndirect = qt_updateLayeredWindowIndirect; // Notify Vista and Windows 7 that we support highter DPI settings - if (ptrSetProcessDPIAware = (PtrSetProcessDPIAware) - QLibrary::resolve(QLatin1String("user32"), "SetProcessDPIAware")) - ptrSetProcessDPIAware(); + ptrSetProcessDPIAware = (PtrSetProcessDPIAware) + QLibrary::resolve(QLatin1String("user32"), "SetProcessDPIAware"); + if (ptrSetProcessDPIAware) + ptrSetProcessDPIAware(); #endif priv->lastGestureId = 0; @@ -1351,13 +1354,13 @@ static int inputcharset = CP_ACP; static bool qt_is_translatable_mouse_event(UINT message) { - return (message >= WM_MOUSEFIRST && message <= WM_MOUSELAST || - message >= WM_XBUTTONDOWN && message <= WM_XBUTTONDBLCLK) + return (((message >= WM_MOUSEFIRST && message <= WM_MOUSELAST) || + (message >= WM_XBUTTONDOWN && message <= WM_XBUTTONDBLCLK)) && message != WM_MOUSEWHEEL - && message != WM_MOUSEHWHEEL + && message != WM_MOUSEHWHEEL) #ifndef Q_WS_WINCE - || message >= WM_NCMOUSEMOVE && message <= WM_NCMBUTTONDBLCLK + || (message >= WM_NCMOUSEMOVE && message <= WM_NCMBUTTONDBLCLK) #endif ; } @@ -2601,7 +2604,7 @@ bool qt_try_modal(QWidget *widget, MSG *msg, int& ret) bool block_event = false; #ifndef Q_WS_WINCE - if (type != WM_NCHITTEST) + if (type != WM_NCHITTEST) { #endif if ((type >= WM_MOUSEFIRST && type <= WM_MOUSELAST) || type == WM_MOUSEWHEEL || type == WM_MOUSEHWHEEL || @@ -2631,17 +2634,18 @@ bool qt_try_modal(QWidget *widget, MSG *msg, int& ret) block_event = true; } #ifndef Q_WS_WINCE - else if (type == WM_MOUSEACTIVATE || type == WM_NCLBUTTONDOWN){ - if (!top->isActiveWindow()) { - top->activateWindow(); - } else { - QApplication::beep(); - } - block_event = true; - ret = MA_NOACTIVATEANDEAT; - } else if (type == WM_SYSCOMMAND) { - if (!(msg->wParam == SC_RESTORE && widget->isMinimized())) + else if (type == WM_MOUSEACTIVATE || type == WM_NCLBUTTONDOWN){ + if (!top->isActiveWindow()) { + top->activateWindow(); + } else { + QApplication::beep(); + } block_event = true; + ret = MA_NOACTIVATEANDEAT; + } else if (type == WM_SYSCOMMAND) { + if (!(msg->wParam == SC_RESTORE && widget->isMinimized())) + block_event = true; + } } #endif @@ -2843,7 +2847,7 @@ void qt_win_eatMouseMove() // remove all those messages (usually 1) and post the last one with a // reset button state - MSG msg = {0, 0, 0, 0, 0, 0, 0}; + MSG msg = {0, 0, 0, 0, 0, {0, 0} }; while (PeekMessage(&msg, 0, WM_MOUSEMOVE, WM_MOUSEMOVE, PM_REMOVE)) ; if (msg.message == WM_MOUSEMOVE) diff --git a/src/gui/kernel/qkeymapper_win.cpp b/src/gui/kernel/qkeymapper_win.cpp index b13e622..0998631 100644 --- a/src/gui/kernel/qkeymapper_win.cpp +++ b/src/gui/kernel/qkeymapper_win.cpp @@ -851,8 +851,8 @@ bool QKeyMapperPrivate::translateKeyEvent(QWidget *widget, const MSG &msg, bool } } else if (msgType == WM_KEYUP) { if (dirStatus == VK_LSHIFT - && (msg.wParam == VK_SHIFT && GetKeyState(VK_LCONTROL) - || msg.wParam == VK_CONTROL && GetKeyState(VK_LSHIFT))) { + && ((msg.wParam == VK_SHIFT && GetKeyState(VK_LCONTROL)) + || (msg.wParam == VK_CONTROL && GetKeyState(VK_LSHIFT)))) { k0 = q->sendKeyEvent(widget, grab, QEvent::KeyPress, Qt::Key_Direction_L, 0, QString(), false, 0, scancode, msg.wParam, nModifiers); @@ -861,8 +861,8 @@ bool QKeyMapperPrivate::translateKeyEvent(QWidget *widget, const MSG &msg, bool scancode, msg.wParam, nModifiers); dirStatus = 0; } else if (dirStatus == VK_RSHIFT - && (msg.wParam == VK_SHIFT && GetKeyState(VK_RCONTROL) - || msg.wParam == VK_CONTROL && GetKeyState(VK_RSHIFT))) { + && ( (msg.wParam == VK_SHIFT && GetKeyState(VK_RCONTROL)) + || (msg.wParam == VK_CONTROL && GetKeyState(VK_RSHIFT)))) { k0 = q->sendKeyEvent(widget, grab, QEvent::KeyPress, Qt::Key_Direction_R, 0, QString(), false, 0, scancode, msg.wParam, nModifiers); diff --git a/src/gui/kernel/qmime_win.cpp b/src/gui/kernel/qmime_win.cpp index c7559d8..acd7cfc 100644 --- a/src/gui/kernel/qmime_win.cpp +++ b/src/gui/kernel/qmime_win.cpp @@ -170,7 +170,7 @@ static QByteArray getData(int cf, IDataObject *pDataObj) if (pDataObj->GetData(&formatetc, &s) == S_OK) { char szBuffer[4096]; ULONG actualRead = 0; - LARGE_INTEGER pos = {0, 0}; + LARGE_INTEGER pos = {{0, 0}}; //Move to front (can fail depending on the data model implemented) HRESULT hr = s.pstm->Seek(pos, STREAM_SEEK_SET, NULL); while(SUCCEEDED(hr)){ diff --git a/src/gui/painting/qdrawutil.cpp b/src/gui/painting/qdrawutil.cpp index a3ae102..602b991 100644 --- a/src/gui/painting/qdrawutil.cpp +++ b/src/gui/painting/qdrawutil.cpp @@ -1008,8 +1008,7 @@ void qDrawItem(QPainter *p, Qt::GUIStyle gs, ; #ifndef QT_NO_IMAGE_HEURISTIC_MASK } else { // color pixmap, no mask - QString k; - k.sprintf("$qt-drawitem-%llx", pm.cacheKey()); + QString k = QString::fromLatin1("$qt-drawitem-%1").arg(pm.cacheKey()); if (!QPixmapCache::find(k, pm)) { pm = pm.createHeuristicMask(); pm.setMask((QBitmap&)pm); diff --git a/src/gui/painting/qdrawutil.h b/src/gui/painting/qdrawutil.h index 8f6797c..ce07c1f 100644 --- a/src/gui/painting/qdrawutil.h +++ b/src/gui/painting/qdrawutil.h @@ -133,7 +133,7 @@ Q_GUI_EXPORT QT3_SUPPORT void qDrawArrow(QPainter *p, Qt::ArrowType type, Qt::GU const QPalette &pal, bool enabled); #endif -struct Q_GUI_EXPORT QMargins +struct QMargins { inline QMargins(int margin = 0) : top(margin), @@ -151,7 +151,7 @@ struct Q_GUI_EXPORT QMargins int right; }; -struct Q_GUI_EXPORT QTileRules +struct QTileRules { inline QTileRules(Qt::TileRule horizontalRule, Qt::TileRule verticalRule = Qt::Stretch) : horizontal(horizontalRule), vertical(verticalRule) {} @@ -168,8 +168,7 @@ Q_GUI_EXPORT void qDrawBorderPixmap(QPainter *painter, const QRect &sourceRect, const QMargins &sourceMargins, const QTileRules &rules = QTileRules()); - -Q_GUI_EXPORT inline void qDrawBorderPixmap(QPainter *painter, +inline void qDrawBorderPixmap(QPainter *painter, const QRect &target, const QMargins &margins, const QPixmap &pixmap) diff --git a/src/gui/painting/qpaintengine_raster.cpp b/src/gui/painting/qpaintengine_raster.cpp index 4c35004..e9ff752 100644 --- a/src/gui/painting/qpaintengine_raster.cpp +++ b/src/gui/painting/qpaintengine_raster.cpp @@ -110,10 +110,6 @@ extern bool qt_scaleForTransform(const QTransform &transform, qreal *scale); // #define qt_swap_int(x, y) { int tmp = (x); (x) = (y); (y) = tmp; } #define qt_swap_qreal(x, y) { qreal tmp = (x); (x) = (y); (y) = tmp; } -#ifdef Q_WS_WIN -static bool qt_enable_16bit_colors = false; -#endif - // #define QT_DEBUG_DRAW #ifdef QT_DEBUG_DRAW void dumpClip(int width, int height, QClipData *clip); @@ -4661,104 +4657,6 @@ static int qt_intersect_spans(QT_FT_Span *spans, int numSpans, return n; } -/* - \internal - Clip spans to \a{clip}-region. - Returns number of unclipped spans -*/ -static int qt_intersect_spans(QT_FT_Span *spans, int numSpans, - int *currSpan, - QT_FT_Span *outSpans, int maxOut, - const QRegion &clip) -{ - const QVector rects = clip.rects(); - const int numRects = rects.size(); - - int r = 0; - short miny, minx, maxx, maxy; - { - const QRect &rect = rects[0]; - miny = rect.top(); - minx = rect.left(); - maxx = rect.right(); - maxy = rect.bottom(); - } - - // TODO: better mapping of currY and startRect - - int n = 0; - int i = *currSpan; - int currY = spans[i].y; - while (i < numSpans) { - - if (spans[i].y != currY && r != 0) { - currY = spans[i].y; - r = 0; - const QRect &rect = rects[r]; - miny = rect.top(); - minx = rect.left(); - maxx = rect.right(); - maxy = rect.bottom(); - } - - if (spans[i].y < miny) { - ++i; - continue; - } - - if (spans[i].y > maxy || spans[i].x > maxx) { - if (++r >= numRects) { - ++i; - continue; - } - - const QRect &rect = rects[r]; - miny = rect.top(); - minx = rect.left(); - maxx = rect.right(); - maxy = rect.bottom(); - continue; - } - - if (spans[i].x + spans[i].len <= minx) { - ++i; - continue; - } - - outSpans[n].y = spans[i].y; - outSpans[n].coverage = spans[i].coverage; - - if (spans[i].x < minx) { - const ushort cutaway = minx - spans[i].x; - outSpans[n].len = qMin(spans[i].len - cutaway, maxx - minx + 1); - outSpans[n].x = minx; - if (outSpans[n].len == spans[i].len - cutaway) { - ++i; - } else { - // span wider than current rect - spans[i].len -= outSpans[n].len + cutaway; - spans[i].x = maxx + 1; - } - } else { // span starts inside current rect - outSpans[n].x = spans[i].x; - outSpans[n].len = qMin(spans[i].len, - ushort(maxx - spans[i].x + 1)); - if (outSpans[n].len == spans[i].len) { - ++i; - } else { - // span wider than current rect - spans[i].len -= outSpans[n].len; - spans[i].x = maxx + 1; - } - } - - if (++n >= maxOut) - break; - } - - *currSpan = i; - return n; -} static void qt_span_fill_clipRect(int count, const QSpan *spans, void *userData) diff --git a/src/gui/styles/qplastiquestyle.cpp b/src/gui/styles/qplastiquestyle.cpp index 12aa679..cd0bd0a 100644 --- a/src/gui/styles/qplastiquestyle.cpp +++ b/src/gui/styles/qplastiquestyle.cpp @@ -730,16 +730,6 @@ static QColor mergedColors(const QColor &colorA, const QColor &colorB, int facto return tmp; } -static QString uniqueName(const QString &key, const QStyleOption *option, const QSize &size) -{ - QString tmp; - const QStyleOptionComplex *complexOption = qstyleoption_cast(option); - tmp.sprintf("%s-%d-%d-%d-%lld-%dx%d", key.toLatin1().constData(), uint(option->state), - option->direction, complexOption ? uint(complexOption->activeSubControls) : uint(0), - option->palette.cacheKey(), size.width(), size.height()); - return tmp; -} - static void qt_plastique_draw_gradient(QPainter *painter, const QRect &rect, const QColor &gradientStart, const QColor &gradientStop) { @@ -1512,7 +1502,7 @@ void QPlastiqueStyle::drawPrimitive(PrimitiveElement element, const QStyleOption rect.adjust(2, 0, -2, 0); } #endif - QString pixmapName = uniqueName(QLatin1String("toolbarhandle"), option, rect.size()); + QString pixmapName = QStyleHelper::uniqueName(QLatin1String("toolbarhandle"), option, rect.size()); if (!QPixmapCache::find(pixmapName, cache)) { cache = QPixmap(rect.size()); cache.fill(Qt::transparent); @@ -2777,7 +2767,7 @@ void QPlastiqueStyle::drawControl(ControlElement element, const QStyleOption *op // contents painter->setPen(QPen()); - QString progressBarName = uniqueName(QLatin1String("progressBarContents"), + QString progressBarName = QStyleHelper::uniqueName(QLatin1String("progressBarContents"), option, rect.size()); QPixmap cache; if (!QPixmapCache::find(progressBarName, cache) && rect.height() > 7) { @@ -2837,7 +2827,7 @@ void QPlastiqueStyle::drawControl(ControlElement element, const QStyleOption *op // Draws the header in tables. if (const QStyleOptionHeader *header = qstyleoption_cast(option)) { QPixmap cache; - QString pixmapName = uniqueName(QLatin1String("headersection"), option, option->rect.size()); + QString pixmapName = QStyleHelper::uniqueName(QLatin1String("headersection"), option, option->rect.size()); pixmapName += QString::number(- int(header->position)); pixmapName += QString::number(- int(header->orientation)); @@ -3084,7 +3074,7 @@ void QPlastiqueStyle::drawControl(ControlElement element, const QStyleOption *op // Draws a menu bar item; File, Edit, Help etc.. if ((option->state & State_Selected)) { QPixmap cache; - QString pixmapName = uniqueName(QLatin1String("menubaritem"), option, option->rect.size()); + QString pixmapName = QStyleHelper::uniqueName(QLatin1String("menubaritem"), option, option->rect.size()); if (!QPixmapCache::find(pixmapName, cache)) { cache = QPixmap(option->rect.size()); cache.fill(Qt::white); @@ -3447,7 +3437,7 @@ void QPlastiqueStyle::drawControl(ControlElement element, const QStyleOption *op bool reverse = scrollBar->direction == Qt::RightToLeft; bool sunken = scrollBar->state & State_Sunken; - QString addLinePixmapName = uniqueName(QLatin1String("scrollbar_addline"), option, option->rect.size()); + QString addLinePixmapName = QStyleHelper::uniqueName(QLatin1String("scrollbar_addline"), option, option->rect.size()); QPixmap cache; if (!QPixmapCache::find(addLinePixmapName, cache)) { cache = QPixmap(option->rect.size()); @@ -3519,7 +3509,7 @@ void QPlastiqueStyle::drawControl(ControlElement element, const QStyleOption *op bool sunken = scrollBar->state & State_Sunken; bool horizontal = scrollBar->orientation == Qt::Horizontal; - QString groovePixmapName = uniqueName(QLatin1String("scrollbar_groove"), option, option->rect.size()); + QString groovePixmapName = QStyleHelper::uniqueName(QLatin1String("scrollbar_groove"), option, option->rect.size()); if (sunken) groovePixmapName += QLatin1String("-sunken"); if (element == CE_ScrollBarAddPage) @@ -3578,7 +3568,7 @@ void QPlastiqueStyle::drawControl(ControlElement element, const QStyleOption *op button2.setRect(scrollBarSubLine.left(), scrollBarSubLine.bottom() - (scrollBarExtent - 1), scrollBarSubLine.width(), scrollBarExtent); } - QString subLinePixmapName = uniqueName(QLatin1String("scrollbar_subline"), option, button1.size()); + QString subLinePixmapName = QStyleHelper::uniqueName(QLatin1String("scrollbar_subline"), option, button1.size()); QPixmap cache; if (!QPixmapCache::find(subLinePixmapName, cache)) { cache = QPixmap(button1.size()); @@ -3653,7 +3643,7 @@ void QPlastiqueStyle::drawControl(ControlElement element, const QStyleOption *op // The slider if (option->rect.isValid()) { - QString sliderPixmapName = uniqueName(QLatin1String("scrollbar_slider"), option, option->rect.size()); + QString sliderPixmapName = QStyleHelper::uniqueName(QLatin1String("scrollbar_slider"), option, option->rect.size()); if (horizontal) sliderPixmapName += QLatin1String("-horizontal"); @@ -3873,7 +3863,7 @@ void QPlastiqueStyle::drawComplexControl(ComplexControl control, const QStyleOpt } if ((option->subControls & SC_SliderHandle) && handle.isValid()) { - QString handlePixmapName = uniqueName(QLatin1String("slider_handle"), option, handle.size()); + QString handlePixmapName = QStyleHelper::uniqueName(QLatin1String("slider_handle"), option, handle.size()); if (ticksAbove && !ticksBelow) handlePixmapName += QLatin1String("-flipped"); if ((option->activeSubControls & SC_SliderHandle) && (option->state & State_Sunken)) diff --git a/src/gui/styles/qstyle_p.h b/src/gui/styles/qstyle_p.h index 854874f..213e938 100644 --- a/src/gui/styles/qstyle_p.h +++ b/src/gui/styles/qstyle_p.h @@ -78,7 +78,7 @@ public: QPixmap internalPixmapCache; \ QImage imageCache; \ QPainter *p = painter; \ - QString unique = uniqueName((a), option, option->rect.size()); \ + QString unique = QStyleHelper::uniqueName((a), option, option->rect.size()); \ int txType = painter->deviceTransform().type() | painter->worldTransform().type(); \ bool doPixmapCache = txType <= QTransform::TxTranslate; \ if (doPixmapCache && QPixmapCache::find(unique, internalPixmapCache)) { \ diff --git a/src/gui/styles/qstylehelper.cpp b/src/gui/styles/qstylehelper.cpp index f9010e8..4877ec4 100644 --- a/src/gui/styles/qstylehelper.cpp +++ b/src/gui/styles/qstylehelper.cpp @@ -60,11 +60,10 @@ namespace QStyleHelper { QString uniqueName(const QString &key, const QStyleOption *option, const QSize &size) { - QString tmp; const QStyleOptionComplex *complexOption = qstyleoption_cast(option); - tmp.sprintf("%s-%d-%d-%lld-%dx%d-%d", key.toLatin1().constData(), uint(option->state), - complexOption ? uint(complexOption->activeSubControls) : uint(0), - option->palette.cacheKey(), size.width(), size.height(), option->direction); + QString tmp = QString::fromLatin1("%1-%2-%3-%4-%5-%6x%7").arg(key).arg(uint(option->state)).arg(option->direction) + .arg(complexOption ? uint(complexOption->activeSubControls) : uint(0)) + .arg(option->palette.cacheKey()).arg(size.width()).arg(size.height()); #ifndef QT_NO_SPINBOX if (const QStyleOptionSpinBox *spinBox = qstyleoption_cast(option)) { tmp.append(QLatin1Char('-')); diff --git a/src/gui/styles/qwindowsstyle.cpp b/src/gui/styles/qwindowsstyle.cpp index 4f25e68..4c66bbb 100644 --- a/src/gui/styles/qwindowsstyle.cpp +++ b/src/gui/styles/qwindowsstyle.cpp @@ -1061,6 +1061,8 @@ QPixmap QWindowsStyle::standardPixmap(StandardPixmap standardPixmap, const QStyl } } break; + default: + break; } if (!desktopIcon.isNull()) { return desktopIcon; @@ -1375,11 +1377,8 @@ void QWindowsStyle::drawPrimitive(PrimitiveElement pe, const QStyleOption *opt, QRect r = opt->rect; int size = qMin(r.height(), r.width()); QPixmap pixmap; - QString pixmapName; - pixmapName.sprintf("%s-%s-%d-%d-%d-%lld", - "$qt_ia", metaObject()->className(), - uint(opt->state), pe, - size, opt->palette.cacheKey()); + QString pixmapName = QStyleHelper::uniqueName(QLatin1String("$qt_ia-") + QLatin1String(metaObject()->className()), opt, QSize(size, size)) + + QLatin1Char('-') + QString::number(pe); if (!QPixmapCache::find(pixmapName, pixmap)) { int border = size/5; int sqsize = 2*(size/2); diff --git a/src/gui/styles/qwindowsvistastyle.cpp b/src/gui/styles/qwindowsvistastyle.cpp index 3e65eef..f3d0f04 100644 --- a/src/gui/styles/qwindowsvistastyle.cpp +++ b/src/gui/styles/qwindowsvistastyle.cpp @@ -735,7 +735,7 @@ void QWindowsVistaStyle::drawPrimitive(PrimitiveElement element, const QStyleOpt if (const QListView *listview = qobject_cast(widget)) { if (listview->viewMode() == QListView::IconMode) newStyle = true; - } else if (const QTreeView* treeview = qobject_cast(widget)) { + } else if (qobject_cast(widget)) { newStyle = true; } if (newStyle && view && (vopt = qstyleoption_cast(option))) { @@ -1093,7 +1093,7 @@ void QWindowsVistaStyle::drawControl(ControlElement element, const QStyleOption XPThemeData theme(widget, painter, QLatin1String("PROGRESS"), vertical ? PP_FILLVERT : PP_FILL); theme.rect = option->rect; - bool reverse = bar->direction == Qt::LeftToRight && inverted || bar->direction == Qt::RightToLeft && !inverted; + bool reverse = bar->direction == (Qt::LeftToRight && inverted) || (bar->direction == Qt::RightToLeft && !inverted); QTime current = QTime::currentTime(); if (isIndeterminate) { @@ -1271,7 +1271,7 @@ void QWindowsVistaStyle::drawControl(ControlElement element, const QStyleOption int yoff = y-2 + h / 2; QPoint p1 = QPoint(x + checkcol, yoff); QPoint p2 = QPoint(x + w + 6 , yoff); - int stateId = stateId = MBI_HOT; + stateId = MBI_HOT; QRect subRect(p1.x(), p1.y(), p2.x() - p1.x(), 6); subRect = QStyle::visualRect(option->direction, option->rect, subRect ); XPThemeData theme2(widget, painter, QLatin1String("MENU"), MENU_POPUPSEPARATOR, stateId, subRect); @@ -1283,7 +1283,7 @@ void QWindowsVistaStyle::drawControl(ControlElement element, const QStyleOption menuitem->rect.y(), checkcol - 6, menuitem->rect.height())); if (act) { - int stateId = stateId = MBI_HOT; + stateId = MBI_HOT; XPThemeData theme2(widget, painter, QLatin1String("MENU"), MENU_POPUPITEM, stateId, option->rect); d->drawBackground(theme2); } @@ -1403,7 +1403,7 @@ void QWindowsVistaStyle::drawControl(ControlElement element, const QStyleOption break; case CE_MenuBarEmptyArea: { - int stateId = MBI_NORMAL; + stateId = MBI_NORMAL; if (!(state & State_Enabled)) stateId = MBI_DISABLED; XPThemeData theme(widget, painter, QLatin1String("MENU"), MENU_BARBACKGROUND, stateId, option->rect); @@ -1500,7 +1500,7 @@ void QWindowsVistaStyle::drawControl(ControlElement element, const QStyleOption if (const QListView *listview = qobject_cast(widget)) { if (listview->viewMode() == QListView::IconMode) newStyle = true; - } else if (const QTreeView* treeview = qobject_cast(widget)) { + } else if (qobject_cast(widget)) { newStyle = true; } if (newStyle && view && (vopt = qstyleoption_cast(option))) { @@ -2014,7 +2014,7 @@ QRect QWindowsVistaStyle::subElementRect(SubElement element, const QStyleOption MARGINS borderSize; HTHEME theme = pOpenThemeData(widget ? QWindowsVistaStylePrivate::winId(widget) : 0, L"Button"); if (theme) { - int stateId; + int stateId = PBS_NORMAL; if (!(option->state & State_Enabled)) stateId = PBS_DISABLED; else if (option->state & State_Sunken) @@ -2023,8 +2023,6 @@ QRect QWindowsVistaStyle::subElementRect(SubElement element, const QStyleOption stateId = PBS_HOT; else if (btn->features & QStyleOptionButton::DefaultButton) stateId = PBS_DEFAULTED; - else - stateId = PBS_NORMAL; int border = proxy()->pixelMetric(PM_DefaultFrameWidth, btn, widget); rect = option->rect.adjusted(border, border, -border, -border); @@ -2097,7 +2095,7 @@ QRect QWindowsVistaStyle::subElementRect(SubElement element, const QStyleOption rect = QCommonStyle::subElementRect(SE_ProgressBarGroove, option, widget); break; case SE_ItemViewItemDecoration: - if (const QStyleOptionViewItemV4 *vopt = qstyleoption_cast(option)) + if (qstyleoption_cast(option)) rect.adjust(-2, 0, 2, 0); break; case SE_ItemViewItemFocusRect: @@ -2303,6 +2301,8 @@ QRect QWindowsVistaStyle::subControlRect(ComplexControl control, const QStyleOpt rect = visualRect(option->direction, option->rect, rect); } break; + default: + break; } } break; diff --git a/src/gui/styles/qwindowsxpstyle.cpp b/src/gui/styles/qwindowsxpstyle.cpp index 9c4afee..4d1fb7a 100644 --- a/src/gui/styles/qwindowsxpstyle.cpp +++ b/src/gui/styles/qwindowsxpstyle.cpp @@ -1918,8 +1918,8 @@ void QWindowsXPStyle::drawControl(ControlElement element, const QStyleOption *op { name = QLatin1String("BUTTON"); partId = BP_PUSHBUTTON; - bool justFlat = (btn->features & QStyleOptionButton::Flat) && !(flags & (State_On|State_Sunken)) - || (btn->features & QStyleOptionButton::CommandLinkButton + bool justFlat = ((btn->features & QStyleOptionButton::Flat) && !(flags & (State_On|State_Sunken))) + || ((btn->features & QStyleOptionButton::CommandLinkButton) && !(flags & State_MouseOver) && !(btn->features & QStyleOptionButton::DefaultButton)); if (!(flags & State_Enabled) && !(btn->features & QStyleOptionButton::Flat)) @@ -3244,7 +3244,7 @@ int QWindowsXPStyle::pixelMetric(PixelMetric pm, const QStyleOption *option, con if (theme.isValid()) { SIZE size; pGetThemePartSize(theme.handle(), 0, theme.partId, theme.stateId, 0, TS_TRUE, &size); - res = (pm == PM_IndicatorWidth ? size.cx : res = size.cy); + res = (pm == PM_IndicatorWidth) ? size.cx : size.cy; } } break; @@ -3256,7 +3256,7 @@ int QWindowsXPStyle::pixelMetric(PixelMetric pm, const QStyleOption *option, con if (theme.isValid()) { SIZE size; pGetThemePartSize(theme.handle(), 0, theme.partId, theme.stateId, 0, TS_TRUE, &size); - res = (pm == PM_ExclusiveIndicatorWidth ? size.cx : res = size.cy); + res = (pm == PM_ExclusiveIndicatorWidth) ? size.cx : size.cy; } } break; @@ -3536,6 +3536,8 @@ QRect QWindowsXPStyle::subControlRect(ComplexControl cc, const QStyleOptionCompl rect = QRect(frameWidth + hPad, controlTop + vPad, iconSize.width(), iconSize.height()); } break; + default: + break; } } break; @@ -3562,6 +3564,9 @@ QRect QWindowsXPStyle::subControlRect(ComplexControl cc, const QStyleOptionCompl case SC_ComboBoxListBoxPopup: rect = cmb->rect; break; + + default: + break; } } break; @@ -3802,6 +3807,8 @@ QPixmap QWindowsXPStyle::standardPixmap(StandardPixmap standardPixmap, const QSt } } break; + default: + break; } return QWindowsStyle::standardPixmap(standardPixmap, option, widget); } @@ -3923,6 +3930,8 @@ QIcon QWindowsXPStyle::standardIconImplementation(StandardPixmap standardIcon, } break; + default: + break; } return QWindowsStyle::standardIconImplementation(standardIcon, option, widget); diff --git a/src/gui/text/qfontengine_win.cpp b/src/gui/text/qfontengine_win.cpp index f4adc9a..c6717e3 100644 --- a/src/gui/text/qfontengine_win.cpp +++ b/src/gui/text/qfontengine_win.cpp @@ -125,8 +125,6 @@ HDC shared_dc() } #endif -static HFONT stock_sysfont = 0; - typedef BOOL (WINAPI *PtrGetCharWidthI)(HDC, UINT, UINT, LPWORD, LPINT); static PtrGetCharWidthI ptrGetCharWidthI = 0; static bool resolvedGetCharWidthI = false; @@ -542,13 +540,6 @@ glyph_metrics_t QFontEngineWin::boundingBox(const QGlyphLayout &glyphs) } - - -#ifndef Q_WS_WINCE -typedef HRESULT (WINAPI *pGetCharABCWidthsFloat)(HDC, UINT, UINT, LPABCFLOAT); -static pGetCharABCWidthsFloat qt_GetCharABCWidthsFloat = 0; -#endif - glyph_metrics_t QFontEngineWin::boundingBox(glyph_t glyph, const QTransform &t) { #ifndef Q_WS_WINCE @@ -1143,8 +1134,7 @@ QNativeImage *QFontEngineWin::drawGDIGlyph(HFONT font, glyph_t glyph, int margin memset(&mat, 0, sizeof(mat)); mat.eM11.value = mat.eM22.value = 1; - int error = GetGlyphOutline(hdc, glyph, ggo_options, &tgm, 0, 0, &mat); - if (error == GDI_ERROR) { + if (GetGlyphOutline(hdc, glyph, ggo_options, &tgm, 0, 0, &mat) == GDI_ERROR) { qWarning("QWinFontEngine: unable to query transformed glyph metrics..."); return 0; } diff --git a/src/gui/text/qzip.cpp b/src/gui/text/qzip.cpp index 5fbc36d..ccb4e6b 100644 --- a/src/gui/text/qzip.cpp +++ b/src/gui/text/qzip.cpp @@ -56,13 +56,23 @@ #if defined(Q_OS_WIN) #undef S_IFREG #define S_IFREG 0100000 -# define S_ISDIR(x) ((x) & 0040000) > 0 -# define S_ISREG(x) ((x) & 0170000) == S_IFREG +# ifndef S_ISDIR +# define S_ISDIR(x) ((x) & 0040000) > 0 +# endif +# ifndef S_ISREG +# define S_ISREG(x) ((x) & 0170000) == S_IFREG +# endif # define S_IFLNK 020000 # define S_ISLNK(x) ((x) & S_IFLNK) > 0 -# define S_IRUSR 0400 -# define S_IWUSR 0200 -# define S_IXUSR 0100 +# ifndef S_IRUSR +# define S_IRUSR 0400 +# endif +# ifndef S_IWUSR +# define S_IWUSR 0200 +# endif +# ifndef S_IXUSR +# define S_IXUSR 0100 +# endif # define S_IRGRP 0040 # define S_IWGRP 0020 # define S_IXGRP 0010 -- cgit v0.12 From 0c58fe61b18317d071ac27857bd8cf4d52ec6703 Mon Sep 17 00:00:00 2001 From: dt Date: Wed, 15 Jul 2009 14:23:38 +0200 Subject: Support more than 63 handles in QWindowsFileSystemWatcher We spawn/stop additional threads as needed to watch any number of files/directories. The old logic of using just one handle per watched directory (regardless of how many files we watch in it.) is preserved. In the worst case a thread is started per 63 files to watch. This enabled Qt Creator to watch all .pro and .pri files even while having qt's projects.pro and qtcreator.pro open. Task-number: 185259, 253014 Reviewed-by: denis --- src/corelib/io/qfilesystemwatcher_p.h | 7 +- src/corelib/io/qfilesystemwatcher_win.cpp | 427 ++++++++++++++++++------------ src/corelib/io/qfilesystemwatcher_win_p.h | 51 +++- 3 files changed, 304 insertions(+), 181 deletions(-) diff --git a/src/corelib/io/qfilesystemwatcher_p.h b/src/corelib/io/qfilesystemwatcher_p.h index 850e150..83be197 100644 --- a/src/corelib/io/qfilesystemwatcher_p.h +++ b/src/corelib/io/qfilesystemwatcher_p.h @@ -69,13 +69,14 @@ class QFileSystemWatcherEngine : public QThread Q_OBJECT protected: - inline QFileSystemWatcherEngine() + inline QFileSystemWatcherEngine(bool move = true) { - moveToThread(this); + if (move) + moveToThread(this); } public: - // fills \a files and \a directires with the \a paths it could + // fills \a files and \a directories with the \a paths it could // watch, and returns a list of paths this engine could not watch virtual QStringList addPaths(const QStringList &paths, QStringList *files, diff --git a/src/corelib/io/qfilesystemwatcher_win.cpp b/src/corelib/io/qfilesystemwatcher_win.cpp index c15b1d2..9eeef02 100644 --- a/src/corelib/io/qfilesystemwatcher_win.cpp +++ b/src/corelib/io/qfilesystemwatcher_win.cpp @@ -53,23 +53,268 @@ QT_BEGIN_NAMESPACE +void QWindowsFileSystemWatcherEngine::stop() +{ + foreach(QWindowsFileSystemWatcherEngineThread *thread, threads) + thread->stop(); +} + QWindowsFileSystemWatcherEngine::QWindowsFileSystemWatcherEngine() - : msg(0) + : QFileSystemWatcherEngine(false) { - if (HANDLE h = CreateEvent(0, false, false, 0)) { - handles.reserve(MAXIMUM_WAIT_OBJECTS); - handles.append(h); - } } QWindowsFileSystemWatcherEngine::~QWindowsFileSystemWatcherEngine() { - if (handles.isEmpty()) + if (threads.isEmpty()) return; - stop(); - wait(); + foreach(QWindowsFileSystemWatcherEngineThread *thread, threads) { + thread->stop(); + thread->wait(); + delete thread; + } +} + +QStringList QWindowsFileSystemWatcherEngine::addPaths(const QStringList &paths, + QStringList *files, + QStringList *directories) +{ + // qDebug()<<"Adding"<count() + directories->count())<<"watchers"; + QStringList p = paths; + QMutableListIterator it(p); + while (it.hasNext()) { + QString path = it.next(); + QString normalPath = path; + if ((normalPath.endsWith(QLatin1Char('/')) || normalPath.endsWith(QLatin1Char('\\'))) +#ifdef Q_OS_WINCE + && normalPath.size() > 1) +#else + ) +#endif + normalPath.chop(1); + QFileInfo fileInfo(normalPath.toLower()); + if (!fileInfo.exists()) + continue; + + bool isDir = fileInfo.isDir(); + if (isDir) { + if (directories->contains(path)) + continue; + } else { + if (files->contains(path)) + continue; + } + + // qDebug()<<"Looking for a thread/handle for"<::const_iterator jt, end; + end = threads.constEnd(); + for(jt = threads.constBegin(); jt != end; ++jt) { + thread = *jt; + QMutexLocker locker(&(thread->mutex)); + + handle = thread->handleForDir.value(absolutePath); + if (handle.handle != INVALID_HANDLE_VALUE && handle.flags == flags) { + // found a thread now insert... + // qDebug()<<" Found a thread"< &h + = thread->pathInfoForHandle[handle.handle]; + if (!h.contains(fileInfo.absoluteFilePath())) { + thread->pathInfoForHandle[handle.handle].insert(fileInfo.absoluteFilePath(), pathInfo); + if (isDir) + directories->append(path); + else + files->append(path); + } + it.remove(); + thread->wakeup(); + break; + } + } + + // no thread found, first create a handle + if (handle.handle == INVALID_HANDLE_VALUE || handle.flags != flags) { + // qDebug()<<" No thread found"; + // Volume and folder paths need a trailing slash for proper notification + // (e.g. "c:" -> "c:/"). + const QString effectiveAbsolutePath = + isDir ? (absolutePath + QLatin1Char('/')) : absolutePath; + + handle.handle = FindFirstChangeNotification((wchar_t*) QDir::toNativeSeparators(effectiveAbsolutePath).utf16(), false, flags); + handle.flags = flags; + if (handle.handle == INVALID_HANDLE_VALUE) + continue; + + // now look for a thread to insert + bool found = false; + foreach(QWindowsFileSystemWatcherEngineThread *thread, threads) { + QMutexLocker(&(thread->mutex)); + if (thread->handles.count() < MAXIMUM_WAIT_OBJECTS) { + // qDebug() << " Added handle" << handle.handle << "for" << absolutePath << "to watch" << fileInfo.absoluteFilePath(); + // qDebug()<< " to existing thread"<handles.append(handle.handle); + thread->handleForDir.insert(absolutePath, handle); + + thread->pathInfoForHandle[handle.handle].insert(fileInfo.absoluteFilePath(), pathInfo); + if (isDir) + directories->append(path); + else + files->append(path); + + it.remove(); + found = true; + thread->wakeup(); + break; + } + } + if (!found) { + QWindowsFileSystemWatcherEngineThread *thread = new QWindowsFileSystemWatcherEngineThread(); + //qDebug()<<" ###Creating new thread"<handles.append(handle.handle); + thread->handleForDir.insert(absolutePath, handle); + + thread->pathInfoForHandle[handle.handle].insert(fileInfo.absoluteFilePath(), pathInfo); + if (isDir) + directories->append(path); + else + files->append(path); + + connect(thread, SIGNAL(fileChanged(const QString &, bool)), + this, SIGNAL(fileChanged(const QString &, bool))); + connect(thread, SIGNAL(directoryChanged(const QString &, bool)), + this, SIGNAL(directoryChanged(const QString &, bool))); + + thread->msg = '@'; + thread->start(); + threads.append(thread); + it.remove(); + } + } + } + return p; +} + +QStringList QWindowsFileSystemWatcherEngine::removePaths(const QStringList &paths, + QStringList *files, + QStringList *directories) +{ + // qDebug()<<"removePaths"< it(p); + while (it.hasNext()) { + QString path = it.next(); + QString normalPath = path; + if (normalPath.endsWith(QLatin1Char('/')) || normalPath.endsWith(QLatin1Char('\\'))) + normalPath.chop(1); + QFileInfo fileInfo(normalPath.toLower()); + // qDebug()<<"removing"<::iterator jt, end; + end = threads.end(); + for(jt = threads.begin(); jt!= end; ++jt) { + QWindowsFileSystemWatcherEngineThread *thread = *jt; + if (*jt == 0) + continue; + + QMutexLocker locker(&(thread->mutex)); + + QWindowsFileSystemWatcherEngine::Handle handle = thread->handleForDir.value(absolutePath); + if (handle.handle == INVALID_HANDLE_VALUE) { + // perhaps path is a file? + absolutePath = fileInfo.absolutePath(); + handle = thread->handleForDir.value(absolutePath); + } + if (handle.handle != INVALID_HANDLE_VALUE) { + QHash &h = + thread->pathInfoForHandle[handle.handle]; + if (h.remove(fileInfo.absoluteFilePath())) { + // ### + files->removeAll(path); + directories->removeAll(path); + + if (h.isEmpty()) { + // qDebug() << "Closing handle" << handle.handle; + FindCloseChangeNotification(handle.handle); // This one might generate a notification + + int indexOfHandle = thread->handles.indexOf(handle.handle); + Q_ASSERT(indexOfHandle != -1); + thread->handles.remove(indexOfHandle); + + thread->handleForDir.remove(absolutePath); + // h is now invalid + + it.remove(); + + if (thread->handleForDir.isEmpty()) { + // qDebug()<<"Stopping thread "<stop(); + thread->wait(); + locker.relock(); + // We can't delete the thread until the mutex locker is + // out of scope + } + } + } + // Found the file, go to next one + break; + } + } + } + + // Remove all threads that we stopped + QList::iterator jt, end; + end = threads.end(); + for(jt = threads.begin(); jt != end; ++jt) { + if (!(*jt)->isRunning()) { + delete *jt; + *jt = 0; + } + } + + threads.removeAll(0); + return p; +} + +/////////// +// QWindowsFileSystemWatcherEngineThread +/////////// +QWindowsFileSystemWatcherEngineThread::QWindowsFileSystemWatcherEngineThread() + : msg(0) +{ + if (HANDLE h = CreateEvent(0, false, false, 0)) { + handles.reserve(MAXIMUM_WAIT_OBJECTS); + handles.append(h); + } + moveToThread(this); +} + + +QWindowsFileSystemWatcherEngineThread::~QWindowsFileSystemWatcherEngineThread() +{ CloseHandle(handles.at(0)); handles[0] = INVALID_HANDLE_VALUE; @@ -80,13 +325,13 @@ QWindowsFileSystemWatcherEngine::~QWindowsFileSystemWatcherEngine() } } -void QWindowsFileSystemWatcherEngine::run() +void QWindowsFileSystemWatcherEngineThread::run() { QMutexLocker locker(&mutex); forever { QVector handlesCopy = handles; locker.unlock(); - // qDebug() << "QWindowsFileSystemWatcherEngine: waiting on" << handlesCopy.count() << "handles"; + // qDebug() << "QWindowsFileSystemWatcherThread"< &h = pathInfoForHandle[handle]; - QMutableHashIterator it(h); + QHash &h = pathInfoForHandle[handle]; + QMutableHashIterator it(h); while (it.hasNext()) { - QHash::iterator x = it.next(); + QHash::iterator x = it.next(); QString absolutePath = x.value().absolutePath; QFileInfo fileInfo(x.value().path); // qDebug() << "checking" << x.key(); @@ -162,160 +407,14 @@ void QWindowsFileSystemWatcherEngine::run() } } -QStringList QWindowsFileSystemWatcherEngine::addPaths(const QStringList &paths, - QStringList *files, - QStringList *directories) -{ - if (handles.isEmpty() || handles.count() == MAXIMUM_WAIT_OBJECTS) - return paths; - - QMutexLocker locker(&mutex); - - QStringList p = paths; - QMutableListIterator it(p); - while (it.hasNext()) { - QString path = it.next(); - QString normalPath = path; - if ((normalPath.endsWith(QLatin1Char('/')) || normalPath.endsWith(QLatin1Char('\\'))) -#ifdef Q_OS_WINCE - && normalPath.size() > 1) -#else - ) -#endif - normalPath.chop(1); - QFileInfo fileInfo(normalPath.toLower()); - if (!fileInfo.exists()) - continue; - - bool isDir = fileInfo.isDir(); - if (isDir) { - if (directories->contains(path)) - continue; - } else { - if (files->contains(path)) - continue; - } - const QString absolutePath = isDir ? fileInfo.absoluteFilePath() : fileInfo.absolutePath(); - const uint flags = isDir - ? (FILE_NOTIFY_CHANGE_DIR_NAME - | FILE_NOTIFY_CHANGE_FILE_NAME) - : (FILE_NOTIFY_CHANGE_DIR_NAME - | FILE_NOTIFY_CHANGE_FILE_NAME - | FILE_NOTIFY_CHANGE_ATTRIBUTES - | FILE_NOTIFY_CHANGE_SIZE - | FILE_NOTIFY_CHANGE_LAST_WRITE - | FILE_NOTIFY_CHANGE_SECURITY); - - Handle handle = handleForDir.value(absolutePath); - if (handle.handle == INVALID_HANDLE_VALUE || handle.flags != flags) { - // Volume and folder paths need a trailing slash for proper notification - // (e.g. "c:" -> "c:/"). - const QString effectiveAbsolutePath = - isDir ? (absolutePath + QLatin1Char('/')) : absolutePath; - - handle.handle = FindFirstChangeNotification((wchar_t*) QDir::toNativeSeparators(effectiveAbsolutePath).utf16(), false, flags); - handle.flags = flags; - if (handle.handle == INVALID_HANDLE_VALUE) - continue; - // qDebug() << "Added handle" << handle << "for" << absolutePath << "to watch" << fileInfo.absoluteFilePath(); - handles.append(handle.handle); - handleForDir.insert(absolutePath, handle); - } - - PathInfo pathInfo; - pathInfo.absolutePath = absolutePath; - pathInfo.isDir = isDir; - pathInfo.path = path; - pathInfo = fileInfo; - QHash &h = pathInfoForHandle[handle.handle]; - if (!h.contains(fileInfo.absoluteFilePath())) { - pathInfoForHandle[handle.handle].insert(fileInfo.absoluteFilePath(), pathInfo); - if (isDir) - directories->append(path); - else - files->append(path); - } - - it.remove(); - } - - if (!isRunning()) { - msg = '@'; - start(); - } else { - wakeup(); - } - - return p; -} - -QStringList QWindowsFileSystemWatcherEngine::removePaths(const QStringList &paths, - QStringList *files, - QStringList *directories) -{ - QMutexLocker locker(&mutex); - - QStringList p = paths; - QMutableListIterator it(p); - while (it.hasNext()) { - QString path = it.next(); - QString normalPath = path; - if (normalPath.endsWith(QLatin1Char('/')) || normalPath.endsWith(QLatin1Char('\\'))) - normalPath.chop(1); - QFileInfo fileInfo(normalPath.toLower()); - - QString absolutePath = fileInfo.absoluteFilePath(); - Handle handle = handleForDir.value(absolutePath); - if (handle.handle == INVALID_HANDLE_VALUE) { - // perhaps path is a file? - absolutePath = fileInfo.absolutePath(); - handle = handleForDir.value(absolutePath); - if (handle.handle == INVALID_HANDLE_VALUE) - continue; - } - - QHash &h = pathInfoForHandle[handle.handle]; - if (h.remove(fileInfo.absoluteFilePath())) { - // ### - files->removeAll(path); - directories->removeAll(path); - - if (h.isEmpty()) { - // qDebug() << "Closing handle" << handle; - FindCloseChangeNotification(handle.handle); // This one might generate a notification - - int indexOfHandle = handles.indexOf(handle.handle); - Q_ASSERT(indexOfHandle != -1); - handles.remove(indexOfHandle); - - handleForDir.remove(absolutePath); - // h is now invalid - - it.remove(); - } - } - } - - if (handleForDir.isEmpty()) { - stop(); - locker.unlock(); - wait(); - locker.relock(); - } else { - wakeup(); - } - - return p; -} - -void QWindowsFileSystemWatcherEngine::stop() +void QWindowsFileSystemWatcherEngineThread::stop() { msg = 'q'; SetEvent(handles.at(0)); } -void QWindowsFileSystemWatcherEngine::wakeup() +void QWindowsFileSystemWatcherEngineThread::wakeup() { msg = '@'; SetEvent(handles.at(0)); diff --git a/src/corelib/io/qfilesystemwatcher_win_p.h b/src/corelib/io/qfilesystemwatcher_win_p.h index 5d42cac..405d255 100644 --- a/src/corelib/io/qfilesystemwatcher_win_p.h +++ b/src/corelib/io/qfilesystemwatcher_win_p.h @@ -68,27 +68,24 @@ QT_BEGIN_NAMESPACE +class QWindowsFileSystemWatcherEngineThread; + +// Even though QWindowsFileSystemWatcherEngine is derived of QThread +// via QFileSystemWatcher, it does not start a thread. +// Instead QWindowsFileSystemWatcher creates QWindowsFileSystemWatcherEngineThreads +// to do the actually watching. class QWindowsFileSystemWatcherEngine : public QFileSystemWatcherEngine { Q_OBJECT - public: QWindowsFileSystemWatcherEngine(); ~QWindowsFileSystemWatcherEngine(); - void run(); - QStringList addPaths(const QStringList &paths, QStringList *files, QStringList *directories); QStringList removePaths(const QStringList &paths, QStringList *files, QStringList *directories); void stop(); -private: - void wakeup(); - - QMutex mutex; - QVector handles; - int msg; class Handle { @@ -97,13 +94,12 @@ private: uint flags; Handle() - : handle(INVALID_HANDLE_VALUE), flags(0u) + : handle(INVALID_HANDLE_VALUE), flags(0u) { } Handle(const Handle &other) - : handle(other.handle), flags(other.flags) + : handle(other.handle), flags(other.flags) { } }; - QHash handleForDir; class PathInfo { public: @@ -118,7 +114,7 @@ private: QDateTime lastModified; PathInfo &operator=(const QFileInfo &fileInfo) - { + { ownerId = fileInfo.ownerId(); groupId = fileInfo.groupId(); permissions = fileInfo.permissions(); @@ -134,8 +130,35 @@ private: || lastModified != fileInfo.lastModified()); } }; - QHash > pathInfoForHandle; +private: + QList threads; + +}; + +class QWindowsFileSystemWatcherEngineThread : public QThread +{ + Q_OBJECT + +public: + QWindowsFileSystemWatcherEngineThread(); + ~QWindowsFileSystemWatcherEngineThread(); + void run(); + void stop(); + void wakeup(); + + QMutex mutex; + QVector handles; + int msg; + + QHash handleForDir; + + QHash > pathInfoForHandle; + +Q_SIGNALS: + void fileChanged(const QString &path, bool removed); + void directoryChanged(const QString &path, bool removed); }; + #endif // QT_NO_FILESYSTEMWATCHER QT_END_NAMESPACE -- cgit v0.12 From 3be33d012e02610cecd918007174bce3347a111a Mon Sep 17 00:00:00 2001 From: Denis Dzyubenko Date: Wed, 15 Jul 2009 15:10:40 +0200 Subject: Added a version information to our executables. On Windows, the FileDescription part of the version information is used as a caption for the grouped taskbar button. Task-number: 253065 Reviewed-by: Prasanth Ullattil --- demos/qtdemo/qtdemo.rc | 30 +++++++++++++++++++++++++++ tools/assistant/tools/assistant/assistant.rc | 31 ++++++++++++++++++++++++++++ tools/designer/src/designer/designer.rc | 30 +++++++++++++++++++++++++++ tools/linguist/linguist/linguist.rc | 31 ++++++++++++++++++++++++++++ 4 files changed, 122 insertions(+) diff --git a/demos/qtdemo/qtdemo.rc b/demos/qtdemo/qtdemo.rc index 4cf2a63..882b355 100644 --- a/demos/qtdemo/qtdemo.rc +++ b/demos/qtdemo/qtdemo.rc @@ -1,2 +1,32 @@ +#include "winver.h" + IDI_ICON1 ICON DISCARDABLE "qtdemo.ico" +VS_VERSION_INFO VERSIONINFO + FILEVERSION 1,0,0,0 + PRODUCTVERSION 1,0,0,0 + FILEFLAGS 0x0L + FILEFLAGSMASK 0x3fL + FILEOS 0x00040004L + FILETYPE 0x1L + FILESUBTYPE 0x0L +BEGIN + BLOCK "StringFileInfo" + BEGIN + BLOCK "000004b0" + BEGIN + VALUE "CompanyName", "Nokia Corporation and/or its subsidiary(-ies)" + VALUE "FileDescription", "Qt Examples and Demos" + VALUE "FileVersion", "1.0.0.0" + VALUE "LegalCopyright", "Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies)." + VALUE "InternalName", "qtdemo" + VALUE "OriginalFilename", "qtdemo.exe" + VALUE "ProductName", "Qt Examples and Demos" + VALUE "ProductVersion", "1.0.0.0" + END + END + BLOCK "VarFileInfo" + BEGIN + VALUE "Translation", 0x0, 1200 + END +END diff --git a/tools/assistant/tools/assistant/assistant.rc b/tools/assistant/tools/assistant/assistant.rc index b4786ce..deaf40c 100644 --- a/tools/assistant/tools/assistant/assistant.rc +++ b/tools/assistant/tools/assistant/assistant.rc @@ -1 +1,32 @@ +#include "winver.h" + IDI_ICON1 ICON DISCARDABLE "assistant.ico" + +VS_VERSION_INFO VERSIONINFO + FILEVERSION 1,0,0,0 + PRODUCTVERSION 1,0,0,0 + FILEFLAGS 0x0L + FILEFLAGSMASK 0x3fL + FILEOS 0x00040004L + FILETYPE 0x1L + FILESUBTYPE 0x0L +BEGIN + BLOCK "StringFileInfo" + BEGIN + BLOCK "000004b0" + BEGIN + VALUE "CompanyName", "Nokia Corporation and/or its subsidiary(-ies)" + VALUE "FileDescription", "Qt Assistant" + VALUE "FileVersion", "1.0.0.0" + VALUE "LegalCopyright", "Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies)." + VALUE "InternalName", "assistant.exe" + VALUE "OriginalFilename", "assistant.exe" + VALUE "ProductName", "Qt Assistant" + VALUE "ProductVersion", "1.0.0.0" + END + END + BLOCK "VarFileInfo" + BEGIN + VALUE "Translation", 0x0, 1200 + END +END diff --git a/tools/designer/src/designer/designer.rc b/tools/designer/src/designer/designer.rc index 4b6324b..1f8bc0a 100644 --- a/tools/designer/src/designer/designer.rc +++ b/tools/designer/src/designer/designer.rc @@ -1,2 +1,32 @@ +#include "winver.h" + IDI_ICON1 ICON DISCARDABLE "designer.ico" +VS_VERSION_INFO VERSIONINFO + FILEVERSION 1,0,0,0 + PRODUCTVERSION 1,0,0,0 + FILEFLAGS 0x0L + FILEFLAGSMASK 0x3fL + FILEOS 0x00040004L + FILETYPE 0x1L + FILESUBTYPE 0x0L +BEGIN + BLOCK "StringFileInfo" + BEGIN + BLOCK "000004b0" + BEGIN + VALUE "CompanyName", "Nokia Corporation and/or its subsidiary(-ies)" + VALUE "FileDescription", "Qt Designer" + VALUE "FileVersion", "1.0.0.0" + VALUE "LegalCopyright", "Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies)." + VALUE "InternalName", "designer" + VALUE "OriginalFilename", "designer.exe" + VALUE "ProductName", "Qt Designer" + VALUE "ProductVersion", "1.0.0.0" + END + END + BLOCK "VarFileInfo" + BEGIN + VALUE "Translation", 0x0, 1200 + END +END diff --git a/tools/linguist/linguist/linguist.rc b/tools/linguist/linguist/linguist.rc index 865e021..5ff37ca 100644 --- a/tools/linguist/linguist/linguist.rc +++ b/tools/linguist/linguist/linguist.rc @@ -1 +1,32 @@ +#include "winver.h" + IDI_ICON1 ICON DISCARDABLE "linguist.ico" + +VS_VERSION_INFO VERSIONINFO + FILEVERSION 1,0,0,0 + PRODUCTVERSION 1,0,0,0 + FILEFLAGS 0x0L + FILEFLAGSMASK 0x3fL + FILEOS 0x00040004L + FILETYPE 0x1L + FILESUBTYPE 0x0L +BEGIN + BLOCK "StringFileInfo" + BEGIN + BLOCK "000004b0" + BEGIN + VALUE "CompanyName", "Nokia Corporation and/or its subsidiary(-ies)" + VALUE "FileDescription", "Qt Linguist" + VALUE "FileVersion", "1.0.0.0" + VALUE "LegalCopyright", "Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies)." + VALUE "InternalName", "linguist" + VALUE "OriginalFilename", "linguist.exe" + VALUE "ProductName", "Qt Linguist" + VALUE "ProductVersion", "1.0.0.0" + END + END + BLOCK "VarFileInfo" + BEGIN + VALUE "Translation", 0x0, 1200 + END +END -- cgit v0.12 From 234cb624f5dcfc80133843b20e840d1c386082df Mon Sep 17 00:00:00 2001 From: Denis Dzyubenko Date: Wed, 15 Jul 2009 15:49:54 +0200 Subject: Compile fix. Include the qstylehelper header file since the macro uses it. --- src/gui/styles/qstyle_p.h | 1 + 1 file changed, 1 insertion(+) diff --git a/src/gui/styles/qstyle_p.h b/src/gui/styles/qstyle_p.h index 213e938..2d6ef22 100644 --- a/src/gui/styles/qstyle_p.h +++ b/src/gui/styles/qstyle_p.h @@ -43,6 +43,7 @@ #define QSTYLE_P_H #include "private/qobject_p.h" +#include "private/qstylehelper_p.h" #include QT_BEGIN_NAMESPACE -- cgit v0.12 From 41ce7d3be0c4560d5f4ef0187e3e6916149e5d49 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Wed, 15 Jul 2009 16:01:34 +0200 Subject: Restore the use of threadsafe-fdcloexec calls on weird Linux toolchains. Approach suggested by Rohan on 1866485e46039d51ea78a6d672b678aa02f68eef --- src/corelib/kernel/qcore_unix_p.h | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/src/corelib/kernel/qcore_unix_p.h b/src/corelib/kernel/qcore_unix_p.h index 8d43897..dd97841 100644 --- a/src/corelib/kernel/qcore_unix_p.h +++ b/src/corelib/kernel/qcore_unix_p.h @@ -69,10 +69,27 @@ struct sockaddr; -#if defined(Q_OS_LINUX) && defined(O_CLOEXEC) && defined(__GLIBC__) && (__GLIBC__ * 0x100 + __GLIBC_MINOR__) >= 0x0204 +#if defined(Q_OS_LINUX) && defined(__GLIBC__) && (__GLIBC__ * 0x100 + __GLIBC_MINOR__) >= 0x0204 // Linux supports thread-safe FD_CLOEXEC # define QT_UNIX_SUPPORTS_THREADSAFE_CLOEXEC 1 +// add defines for the consts for Linux +# ifndef O_CLOEXEC +# define O_CLOEXEC 02000000 +# endif +# ifndef FD_DUPFD_CLOEXEC +# define F_DUPFD_CLOEXEC 1030 +# endif +# ifndef SOCK_CLOEXEC +# define SOCK_CLOEXEC O_CLOEXEC +# endif +# ifndef SOCK_NONBLOCK +# define SOCK_NONBLOCK O_NONBLOCK +# endif +# ifndef MSG_CMSG_CLOEXEC +# define MSG_CMSG_CLOEXEC 0x40000000 +# endif + QT_BEGIN_NAMESPACE namespace QtLibcSupplement { Q_CORE_EXPORT int accept4(int, sockaddr *, QT_SOCKLEN_T *, int flags); -- cgit v0.12 From 21052c1ad0a670ab746298569c3a90720741a0ce Mon Sep 17 00:00:00 2001 From: Thierry Bastian Date: Wed, 15 Jul 2009 18:10:23 +0200 Subject: fix build on linux --- src/gui/styles/qgtkstyle.cpp | 12 +----------- 1 file changed, 1 insertion(+), 11 deletions(-) diff --git a/src/gui/styles/qgtkstyle.cpp b/src/gui/styles/qgtkstyle.cpp index 67586ac..9d5a3bc 100644 --- a/src/gui/styles/qgtkstyle.cpp +++ b/src/gui/styles/qgtkstyle.cpp @@ -70,6 +70,7 @@ #include #undef signals // Collides with GTK stymbols #include "qgtkpainter_p.h" +#include "qstylehelper_p.h" #include @@ -208,17 +209,6 @@ static GdkColor fromQColor(const QColor &color) return retval; } -// Note this is different from uniqueName as used in QGtkPainter -static QString uniqueName(const QString &key, const QStyleOption *option, const QSize &size) -{ - QString tmp; - const QStyleOptionComplex *complexOption = qstyleoption_cast(option); - tmp.sprintf("%s-%d-%d-%d-%lld-%dx%d", key.toLatin1().constData(), uint(option->state), - option->direction, complexOption ? uint(complexOption->activeSubControls) : uint(0), - option->palette.cacheKey(), size.width(), size.height()); - return tmp; -} - /*! \class QGtkStyle \brief The QGtkStyle class provides a widget style rendered by GTK+ -- cgit v0.12 From d71f6a8c0c9c089d3fe18846835ee183aab47ae9 Mon Sep 17 00:00:00 2001 From: Thierry Bastian Date: Wed, 15 Jul 2009 15:30:06 +0200 Subject: Fix warnings in mingw --- src/network/socket/qlocalsocket_win.cpp | 2 +- src/opengl/qgl_win.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/network/socket/qlocalsocket_win.cpp b/src/network/socket/qlocalsocket_win.cpp index 794b2b7..3a36ac0 100644 --- a/src/network/socket/qlocalsocket_win.cpp +++ b/src/network/socket/qlocalsocket_win.cpp @@ -514,7 +514,7 @@ bool QLocalSocket::waitForReadyRead(int msecs) return false; } - qWarning("QLocalSocket::waitForReadyRead WaitForSingleObject failed with error code %d.", GetLastError()); + qWarning("QLocalSocket::waitForReadyRead WaitForSingleObject failed with error code %d.", int(GetLastError())); return false; } diff --git a/src/opengl/qgl_win.cpp b/src/opengl/qgl_win.cpp index 400b3bc..232d47b 100644 --- a/src/opengl/qgl_win.cpp +++ b/src/opengl/qgl_win.cpp @@ -1413,7 +1413,7 @@ void QGLWidget::setContext(QGLContext *context, } if (!d->glcx->isValid()) { - bool wasSharing = shareContext || oldcx && oldcx->isSharing(); + bool wasSharing = shareContext || (oldcx && oldcx->isSharing()); d->glcx->create(shareContext ? shareContext : oldcx); // the above is a trick to keep disp lists etc when a // QGLWidget has been reparented, so remove the sharing -- cgit v0.12 From e9a4c7f9e86d9b00d1e1690a8d842152413cd1ed Mon Sep 17 00:00:00 2001 From: Thierry Bastian Date: Wed, 15 Jul 2009 16:34:17 +0200 Subject: Fix warnings for QtNetwork on mingw --- src/corelib/io/qfsfileengine_win.cpp | 6 +-- src/network/socket/qnativesocketengine_win.cpp | 73 ++++++++++---------------- 2 files changed, 30 insertions(+), 49 deletions(-) diff --git a/src/corelib/io/qfsfileengine_win.cpp b/src/corelib/io/qfsfileengine_win.cpp index 885ba39..d4e2e93 100644 --- a/src/corelib/io/qfsfileengine_win.cpp +++ b/src/corelib/io/qfsfileengine_win.cpp @@ -165,11 +165,11 @@ void QFSFileEnginePrivate::resolveLibs() if (ptrBuildTrusteeWithNameW) { HINSTANCE versionHnd = LoadLibraryW(L"version"); if (versionHnd) { - typedef DWORD (WINAPI *PtrGetFileVersionInfoSizeW)(LPWSTR lptstrFilename,LPDWORD lpdwHandle); + typedef DWORD (WINAPI *PtrGetFileVersionInfoSizeW)(LPCWSTR lptstrFilename,LPDWORD lpdwHandle); PtrGetFileVersionInfoSizeW ptrGetFileVersionInfoSizeW = (PtrGetFileVersionInfoSizeW)GetProcAddress(versionHnd, "GetFileVersionInfoSizeW"); - typedef BOOL (WINAPI *PtrGetFileVersionInfoW)(LPWSTR lptstrFilename,DWORD dwHandle,DWORD dwLen,LPVOID lpData); + typedef BOOL (WINAPI *PtrGetFileVersionInfoW)(LPCWSTR lptstrFilename,DWORD dwHandle,DWORD dwLen,LPVOID lpData); PtrGetFileVersionInfoW ptrGetFileVersionInfoW = (PtrGetFileVersionInfoW)GetProcAddress(versionHnd, "GetFileVersionInfoW"); - typedef BOOL (WINAPI *PtrVerQueryValueW)(const LPVOID pBlock,LPWSTR lpSubBlock,LPVOID *lplpBuffer,PUINT puLen); + typedef BOOL (WINAPI *PtrVerQueryValueW)(const LPVOID pBlock,LPCWSTR lpSubBlock,LPVOID *lplpBuffer,PUINT puLen); PtrVerQueryValueW ptrVerQueryValueW = (PtrVerQueryValueW)GetProcAddress(versionHnd, "VerQueryValueW"); if(ptrGetFileVersionInfoSizeW && ptrGetFileVersionInfoW && ptrVerQueryValueW) { DWORD fakeHandle; diff --git a/src/network/socket/qnativesocketengine_win.cpp b/src/network/socket/qnativesocketengine_win.cpp index ce8d810..6bc23ce 100644 --- a/src/network/socket/qnativesocketengine_win.cpp +++ b/src/network/socket/qnativesocketengine_win.cpp @@ -166,11 +166,11 @@ static QByteArray qt_prettyDebug(const char *data, int len, int maxLength) Extracts the port and address from a sockaddr, and stores them in \a port and \a addr if they are non-null. */ -static inline void qt_socket_getPortAndAddress(SOCKET socketDescriptor, struct sockaddr *sa, quint16 *port, QHostAddress *address) +static inline void qt_socket_getPortAndAddress(SOCKET socketDescriptor, const qt_sockaddr *sa, quint16 *port, QHostAddress *address) { #if !defined (QT_NO_IPV6) - if (sa->sa_family == AF_INET6) { - qt_sockaddr_in6 *sa6 = (qt_sockaddr_in6 *)sa; + if (sa->a.sa_family == AF_INET6) { + const qt_sockaddr_in6 *sa6 = &sa->a6; Q_IPV6ADDR tmp; for (int i = 0; i < 16; ++i) tmp.c[i] = sa6->sin6_addr.qt_s6_addr[i]; @@ -182,8 +182,8 @@ static inline void qt_socket_getPortAndAddress(SOCKET socketDescriptor, struct s WSANtohs(socketDescriptor, sa6->sin6_port, port); } else #endif - if (sa->sa_family == AF_INET) { - struct sockaddr_in *sa4 = (struct sockaddr_in *)sa; + if (sa->a.sa_family == AF_INET) { + const sockaddr_in *sa4 = &sa->a4; unsigned long addr; WSANtohl(socketDescriptor, sa4->sin_addr.s_addr, &addr); QHostAddress a; @@ -463,20 +463,15 @@ bool QNativeSocketEnginePrivate::fetchConnectionParameters() if (socketDescriptor == -1) return false; -#if !defined (QT_NO_IPV6) - struct qt_sockaddr_storage sa; -#else - struct sockaddr_in sa; -#endif - struct sockaddr *pSa = (struct sockaddr *) &sa; - - QT_SOCKLEN_T sz = sizeof(sa); + qt_sockaddr sa; + QT_SOCKLEN_T sockAddrSize = sizeof(sa); + // Determine local address memset(&sa, 0, sizeof(sa)); - if (::getsockname(socketDescriptor, pSa, &sz) == 0) { - qt_socket_getPortAndAddress(socketDescriptor, pSa, &localPort, &localAddress); + if (::getsockname(socketDescriptor, &sa.a, &sockAddrSize) == 0) { + qt_socket_getPortAndAddress(socketDescriptor, &sa, &localPort, &localAddress); // Determine protocol family - switch (pSa->sa_family) { + switch (sa.a.sa_family) { case AF_INET: socketProtocol = QAbstractSocket::IPv4Protocol; break; @@ -500,8 +495,8 @@ bool QNativeSocketEnginePrivate::fetchConnectionParameters() } memset(&sa, 0, sizeof(sa)); - if (::getpeername(socketDescriptor, pSa, &sz) == 0) { - qt_socket_getPortAndAddress(socketDescriptor, pSa, &peerPort, &peerAddress); + if (::getpeername(socketDescriptor, &sa.a, &sockAddrSize) == 0) { + qt_socket_getPortAndAddress(socketDescriptor, &sa, &peerPort, &peerAddress); } else { WS_ERROR_DEBUG(WSAGetLastError()); } @@ -533,8 +528,8 @@ bool QNativeSocketEnginePrivate::nativeConnect(const QHostAddress &address, quin struct sockaddr_in sockAddrIPv4; qt_sockaddr_in6 sockAddrIPv6; - struct sockaddr *sockAddrPtr; - QT_SOCKLEN_T sockAddrSize; + struct sockaddr *sockAddrPtr = 0; + QT_SOCKLEN_T sockAddrSize = 0; qt_socket_setPortAndAddress(socketDescriptor, &sockAddrIPv4, &sockAddrIPv6, port, address, &sockAddrPtr, &sockAddrSize); @@ -638,8 +633,8 @@ bool QNativeSocketEnginePrivate::nativeBind(const QHostAddress &address, quint16 { struct sockaddr_in sockAddrIPv4; qt_sockaddr_in6 sockAddrIPv6; - struct sockaddr *sockAddrPtr; - QT_SOCKLEN_T sockAddrSize; + struct sockaddr *sockAddrPtr = 0; + QT_SOCKLEN_T sockAddrSize = 0; qt_socket_setPortAndAddress(socketDescriptor, &sockAddrIPv4, &sockAddrIPv6, port, address, &sockAddrPtr, &sockAddrSize); @@ -766,20 +761,9 @@ bool QNativeSocketEnginePrivate::nativeHasPendingDatagrams() const { #if !defined(Q_OS_WINCE) // Create a sockaddr struct and reset its port number. -#if !defined(QT_NO_IPV6) - qt_sockaddr_in6 storage; - qt_sockaddr_in6 *storagePtrIPv6 = reinterpret_cast(&storage); - storagePtrIPv6->sin6_port = 0; -#else - struct sockaddr storage; -#endif - sockaddr *storagePtr = reinterpret_cast(&storage); - storagePtr->sa_family = 0; - - sockaddr_in *storagePtrIPv4 = reinterpret_cast(&storage); - storagePtrIPv4->sin_port = 0; + qt_sockaddr storage; QT_SOCKLEN_T storageSize = sizeof(storage); - + memset(&storage, 0, storageSize); bool result = false; @@ -791,7 +775,7 @@ bool QNativeSocketEnginePrivate::nativeHasPendingDatagrams() const buf.len = sizeof(c); DWORD available = 0; DWORD flags = MSG_PEEK; - int ret = ::WSARecvFrom(socketDescriptor, &buf, 1, &available, &flags, storagePtr, &storageSize,0,0); + int ret = ::WSARecvFrom(socketDescriptor, &buf, 1, &available, &flags, &storage.a, &storageSize,0,0); int err = WSAGetLastError(); if (ret == SOCKET_ERROR && err != WSAEMSGSIZE) { WS_ERROR_DEBUG(err); @@ -801,7 +785,7 @@ bool QNativeSocketEnginePrivate::nativeHasPendingDatagrams() const // notifiers. flags = 0; ::WSARecvFrom(socketDescriptor, &buf, 1, &available, &flags, - storagePtr, &storageSize, 0, 0); + &storage.a, &storageSize, 0, 0); } } else { // If there's no error, or if our buffer was too small, there must be @@ -893,14 +877,11 @@ qint64 QNativeSocketEnginePrivate::nativeReceiveDatagram(char *data, qint64 maxL { qint64 ret = 0; -#if !defined(QT_NO_IPV6) - qt_sockaddr_storage aa; -#else - struct sockaddr_in aa; -#endif + qt_sockaddr aa; memset(&aa, 0, sizeof(aa)); QT_SOCKLEN_T sz; sz = sizeof(aa); + WSABUF buf; buf.buf = data; buf.len = maxLength; @@ -915,7 +896,7 @@ qint64 QNativeSocketEnginePrivate::nativeReceiveDatagram(char *data, qint64 maxL DWORD flags = 0; DWORD bytesRead = 0; - int wsaRet = ::WSARecvFrom(socketDescriptor, &buf, 1, &bytesRead, &flags, (struct sockaddr *) &aa, &sz,0,0); + int wsaRet = ::WSARecvFrom(socketDescriptor, &buf, 1, &bytesRead, &flags, &aa.a, &sz,0,0); if (wsaRet == SOCKET_ERROR) { int err = WSAGetLastError(); WS_ERROR_DEBUG(err); @@ -925,7 +906,7 @@ qint64 QNativeSocketEnginePrivate::nativeReceiveDatagram(char *data, qint64 maxL ret = qint64(bytesRead); } - qt_socket_getPortAndAddress(socketDescriptor, (struct sockaddr *) &aa, port, address); + qt_socket_getPortAndAddress(socketDescriptor, &aa, port, address); #if defined (QNATIVESOCKETENGINE_DEBUG) qDebug("QNativeSocketEnginePrivate::nativeReceiveDatagram(%p \"%s\", %li, %s, %i) == %li", @@ -944,8 +925,8 @@ qint64 QNativeSocketEnginePrivate::nativeSendDatagram(const char *data, qint64 l qint64 ret = -1; struct sockaddr_in sockAddrIPv4; qt_sockaddr_in6 sockAddrIPv6; - struct sockaddr *sockAddrPtr; - QT_SOCKLEN_T sockAddrSize; + struct sockaddr *sockAddrPtr = 0; + QT_SOCKLEN_T sockAddrSize = 0; qt_socket_setPortAndAddress(socketDescriptor, &sockAddrIPv4, &sockAddrIPv6, port, address, &sockAddrPtr, &sockAddrSize); -- cgit v0.12