diff --git a/src/xercesc/internal/XMLScanner.cpp b/src/xercesc/internal/XMLScanner.cpp index 944442b6af0cd34aef9d23f3cdcde4ebfabb2ebf..b1d26efaac87f54567601d1043ebacdf94a56bdc 100644 --- a/src/xercesc/internal/XMLScanner.cpp +++ b/src/xercesc/internal/XMLScanner.cpp @@ -140,6 +140,7 @@ XMLScanner::XMLScanner(XMLValidator* const valToAdopt, , fUseCachedGrammar(false) , fLoadExternalDTD(true) , fNormalizeData(true) + , fGenerateSyntheticAnnotations(false) , fErrorCount(0) , fEntityExpansionLimit(0) , fEntityExpansionCount(0) @@ -218,6 +219,7 @@ XMLScanner::XMLScanner( XMLDocumentHandler* const docHandler , fUseCachedGrammar(false) , fLoadExternalDTD(true) , fNormalizeData(true) + , fGenerateSyntheticAnnotations(false) , fErrorCount(0) , fEntityExpansionLimit(0) , fEntityExpansionCount(0) diff --git a/src/xercesc/internal/XMLScanner.hpp b/src/xercesc/internal/XMLScanner.hpp index 5e49559f8769028839ab1b9a19906c614ccc385b..c42dc6729b891993dbfa5e680fc0f4c441803974 100644 --- a/src/xercesc/internal/XMLScanner.hpp +++ b/src/xercesc/internal/XMLScanner.hpp @@ -16,6 +16,9 @@ /* * $Log$ + * Revision 1.38 2004/09/23 01:09:55 cargilld + * Add support for generating synthetic XSAnnotations. When a schema component has non-schema attributes and no child attributes create a synthetic XSAnnotation (under feature control) so the non-schema attributes can be recovered under PSVI. + * * Revision 1.37 2004/09/08 13:56:14 peiyongz * Apache License Version 2.0 * @@ -513,6 +516,8 @@ public : unsigned int getPrefixId(const XMLCh* const prefix) const; const XMLCh* getPrefixForId(unsigned int prefId) const; + bool getGenerateSyntheticAnnotations() const; + // ----------------------------------------------------------------------- // Getter methods // ----------------------------------------------------------------------- @@ -606,6 +611,8 @@ public : void setParseSettings(XMLScanner* const refScanner); void setStandardUriConformant(const bool newValue); + void setGenerateSyntheticAnnotations(const bool newValue); + // ----------------------------------------------------------------------- // Mutator methods // ----------------------------------------------------------------------- @@ -957,6 +964,7 @@ protected: bool fUseCachedGrammar; bool fLoadExternalDTD; bool fNormalizeData; + bool fGenerateSyntheticAnnotations; int fErrorCount; unsigned int fEntityExpansionLimit; unsigned int fEntityExpansionCount; @@ -1302,6 +1310,11 @@ inline const XMLCh* XMLScanner::getPrefixForId(unsigned int prefId) const return fElemStack.getPrefixForId(prefId); } +inline bool XMLScanner::getGenerateSyntheticAnnotations() const +{ + return fGenerateSyntheticAnnotations; +} + // --------------------------------------------------------------------------- // XMLScanner: Setter methods // --------------------------------------------------------------------------- @@ -1455,6 +1468,11 @@ inline void XMLScanner::setStandardUriConformant(const bool newValue) fReaderMgr.setStandardUriConformant(newValue); } +inline void XMLScanner::setGenerateSyntheticAnnotations(const bool newValue) +{ + fGenerateSyntheticAnnotations = newValue; +} + // --------------------------------------------------------------------------- // XMLScanner: Mutator methods // --------------------------------------------------------------------------- diff --git a/src/xercesc/parsers/AbstractDOMParser.cpp b/src/xercesc/parsers/AbstractDOMParser.cpp index 9bbcf45bc91eaaf27225270f14ab0bc4c6d3d928..9957364f9cfb747291d1a0cef275d9ce587c910f 100644 --- a/src/xercesc/parsers/AbstractDOMParser.cpp +++ b/src/xercesc/parsers/AbstractDOMParser.cpp @@ -230,6 +230,11 @@ bool AbstractDOMParser::getDoNamespaces() const return fScanner->getDoNamespaces(); } +bool AbstractDOMParser::getGenerateSyntheticAnnotations() const +{ + return fScanner->getGenerateSyntheticAnnotations(); +} + bool AbstractDOMParser::getExitOnFirstFatalError() const { return fScanner->getExitOnFirstFatal(); @@ -323,6 +328,11 @@ void AbstractDOMParser::setDoNamespaces(const bool newState) fScanner->setDoNamespaces(newState); } +void AbstractDOMParser::setGenerateSyntheticAnnotations(const bool newState) +{ + fScanner->setGenerateSyntheticAnnotations(newState); +} + void AbstractDOMParser::setExitOnFirstFatalError(const bool newState) { fScanner->setExitOnFirstFatal(newState); diff --git a/src/xercesc/parsers/AbstractDOMParser.hpp b/src/xercesc/parsers/AbstractDOMParser.hpp index f22f1496a75cc5a575cd93a4223b344d4f1eb588..ddb558412e5175ce080b3ad0d6ecaa49fab85378 100644 --- a/src/xercesc/parsers/AbstractDOMParser.hpp +++ b/src/xercesc/parsers/AbstractDOMParser.hpp @@ -408,6 +408,19 @@ public : */ bool getCreateSchemaInfo() const; + /** Get the 'generate synthetic validations' flag + * + * @return true, if the parser is currently configured to + * generate synthetic annotations, false otherwise. + * A synthetic XSAnnotation is created when a schema + * component has non-schema attributes but has no + * child annotations so that the non-schema attributes + * can be recovered under PSVI. + * + * @see #setGenerateSyntheticAnnotations + */ + bool getGenerateSyntheticAnnotations() const; + //@} @@ -417,6 +430,18 @@ public : /** @name Setter methods */ //@{ + /** set the 'generate synthetic validations' flag + * + * @param newValue The value for specifying whether Synthetic Annotations + * should be generated or not. + * A synthetic XSAnnotation is created when a schema + * component has non-schema attributes but has no + * child annotations so that the non-schema attributes + * can be recovered under PSVI. + * + * @see #getGenerateSyntheticAnnotations + */ + void setGenerateSyntheticAnnotations(const bool newValue); /** Set the 'do namespaces' flag * diff --git a/src/xercesc/parsers/DOMBuilderImpl.cpp b/src/xercesc/parsers/DOMBuilderImpl.cpp index 7278438ed433b75eb7572500242da12293dd42dd..552e1b82746debff36fe9b7affcdc62cd71872e2 100644 --- a/src/xercesc/parsers/DOMBuilderImpl.cpp +++ b/src/xercesc/parsers/DOMBuilderImpl.cpp @@ -231,6 +231,10 @@ void DOMBuilderImpl::setFeature(const XMLCh* const name, const bool state) { setCreateSchemaInfo(state); } + else if (XMLString::compareIString(name, XMLUni::fgXercesGenerateSyntheticAnnotations) == 0) + { + getScanner()->setGenerateSyntheticAnnotations(state); + } else { throw DOMException(DOMException::NOT_FOUND_ERR, 0, getMemoryManager()); } @@ -321,6 +325,10 @@ bool DOMBuilderImpl::getFeature(const XMLCh* const name) const else if (XMLString::compareIString(name, XMLUni::fgXercesDOMHasPSVIInfo) == 0) { return getCreateSchemaInfo(); } + else if (XMLString::compareIString(name, XMLUni::fgXercesGenerateSyntheticAnnotations) == 0) + { + return getScanner()->getGenerateSyntheticAnnotations(); + } else { throw DOMException(DOMException::NOT_FOUND_ERR, 0, getMemoryManager()); } diff --git a/src/xercesc/parsers/SAX2XMLReaderImpl.cpp b/src/xercesc/parsers/SAX2XMLReaderImpl.cpp index 02c199267115a21aec33cd071cb079679c8f86e0..000b280f776a89bd621c0e16a2cec26199bebf68 100644 --- a/src/xercesc/parsers/SAX2XMLReaderImpl.cpp +++ b/src/xercesc/parsers/SAX2XMLReaderImpl.cpp @@ -16,6 +16,9 @@ /* * $Log$ + * Revision 1.36 2004/09/23 01:09:55 cargilld + * Add support for generating synthetic XSAnnotations. When a schema component has non-schema attributes and no child attributes create a synthetic XSAnnotation (under feature control) so the non-schema attributes can be recovered under PSVI. + * * Revision 1.35 2004/09/08 13:56:17 peiyongz * Apache License Version 2.0 * @@ -1557,6 +1560,10 @@ void SAX2XMLReaderImpl::setFeature(const XMLCh* const name, const bool value) { fScanner->setStandardUriConformant(value); } + else if (XMLString::compareIString(name, XMLUni::fgXercesGenerateSyntheticAnnotations) == 0) + { + fScanner->setGenerateSyntheticAnnotations(value); + } else throw SAXNotRecognizedException("Unknown Feature", fMemoryManager); } @@ -1591,6 +1598,8 @@ bool SAX2XMLReaderImpl::getFeature(const XMLCh* const name) const return fScanner->getCalculateSrcOfs(); else if (XMLString::compareIString(name, XMLUni::fgXercesStandardUriConformant) == 0) return fScanner->getStandardUriConformant(); + else if (XMLString::compareIString(name, XMLUni::fgXercesGenerateSyntheticAnnotations) == 0) + return fScanner->getGenerateSyntheticAnnotations(); else throw SAXNotRecognizedException("Unknown Feature", fMemoryManager); diff --git a/src/xercesc/parsers/SAXParser.cpp b/src/xercesc/parsers/SAXParser.cpp index bb51fbbe71636f5ec58f2d0544718bee72e5acc8..96f54e8684d311292742a59b83e57ef31869e8c5 100644 --- a/src/xercesc/parsers/SAXParser.cpp +++ b/src/xercesc/parsers/SAXParser.cpp @@ -16,6 +16,9 @@ /* * $Log$ + * Revision 1.34 2004/09/23 01:09:55 cargilld + * Add support for generating synthetic XSAnnotations. When a schema component has non-schema attributes and no child attributes create a synthetic XSAnnotation (under feature control) so the non-schema attributes can be recovered under PSVI. + * * Revision 1.33 2004/09/08 13:56:17 peiyongz * Apache License Version 2.0 * @@ -446,6 +449,10 @@ bool SAXParser::getDoNamespaces() const return fScanner->getDoNamespaces(); } +bool SAXParser::getGenerateSyntheticAnnotations() const +{ + return fScanner->getGenerateSyntheticAnnotations(); +} bool SAXParser::getExitOnFirstFatalError() const { @@ -558,6 +565,10 @@ void SAXParser::setDoNamespaces(const bool newState) fScanner->setDoNamespaces(newState); } +void SAXParser::setGenerateSyntheticAnnotations(const bool newState) +{ + fScanner->setGenerateSyntheticAnnotations(newState); +} void SAXParser::setExitOnFirstFatalError(const bool newState) { diff --git a/src/xercesc/parsers/SAXParser.hpp b/src/xercesc/parsers/SAXParser.hpp index 96a89e7f6ab5dd5412afd14f29040e7b160944cf..f67f2cf411ff3013f0f5b38160bc8377622efb2b 100644 --- a/src/xercesc/parsers/SAXParser.hpp +++ b/src/xercesc/parsers/SAXParser.hpp @@ -16,6 +16,9 @@ /* * $Log$ + * Revision 1.33 2004/09/23 01:09:55 cargilld + * Add support for generating synthetic XSAnnotations. When a schema component has non-schema attributes and no child attributes create a synthetic XSAnnotation (under feature control) so the non-schema attributes can be recovered under PSVI. + * * Revision 1.32 2004/09/08 13:56:18 peiyongz * Apache License Version 2.0 * @@ -642,6 +645,19 @@ public : */ unsigned int getSrcOffset() const; + /** Get the 'generate synthetic validations' flag + * + * @return true, if the parser is currently configured to + * generate synthetic annotations, false otherwise. + * A synthetic XSAnnotation is created when a schema + * component has non-schema attributes but has no + * child annotations so that the non-schema attributes + * can be recovered under PSVI. + * + * @see #setGenerateSyntheticAnnotations + */ + bool getGenerateSyntheticAnnotations() const; + //@} @@ -651,6 +667,18 @@ public : /** @name Setter methods */ //@{ + /** set the 'generate synthetic validations' flag + * + * @param newValue The value for specifying whether Synthetic Annotations + * should be generated or not. + * A synthetic XSAnnotation is created when a schema + * component has non-schema attributes but has no + * child annotations. + * + * @see #getGenerateSyntheticAnnotations + */ + void setGenerateSyntheticAnnotations(const bool newValue); + /** * This method allows users to enable or disable the parser's * namespace processing. When set to true, parser starts enforcing diff --git a/src/xercesc/util/XMLUni.cpp b/src/xercesc/util/XMLUni.cpp index e7fd74b32368b331733f6771a9e31784670d7552..df76173607d65775992225441e0b9d950fa953f3 100644 --- a/src/xercesc/util/XMLUni.cpp +++ b/src/xercesc/util/XMLUni.cpp @@ -30,6 +30,7 @@ XERCES_CPP_NAMESPACE_BEGIN // --------------------------------------------------------------------------- // XMLUni: Static data // --------------------------------------------------------------------------- + const XMLCh XMLUni::fgAnyString[] = { chLatin_A, chLatin_N, chLatin_Y, chNull @@ -1094,6 +1095,21 @@ const XMLCh XMLUni::fgXercesDOMHasPSVIInfo[] = , chDash, chLatin_i, chLatin_n, chLatin_f, chLatin_o, chNull }; +//Xerces: http://apache.org/xml/features/generate-synthetic-annotations +const XMLCh XMLUni::fgXercesGenerateSyntheticAnnotations[] = +{ + chLatin_h, chLatin_t, chLatin_t, chLatin_p, chColon, chForwardSlash + , chForwardSlash, chLatin_a, chLatin_p, chLatin_a, chLatin_c, chLatin_h + , chLatin_e, chPeriod, chLatin_o, chLatin_r, chLatin_g, chForwardSlash + , chLatin_x, chLatin_m, chLatin_l, chForwardSlash, chLatin_f, chLatin_e + , chLatin_a, chLatin_t, chLatin_u, chLatin_r, chLatin_e, chLatin_s + , chForwardSlash, chLatin_g, chLatin_e, chLatin_n, chLatin_e, chLatin_r + , chLatin_a, chLatin_t, chLatin_e, chDash, chLatin_s, chLatin_y, chLatin_n + , chLatin_t, chLatin_h, chLatin_e, chLatin_t, chLatin_i, chLatin_c, chDash + , chLatin_a, chLatin_n, chLatin_n, chLatin_o, chLatin_t, chLatin_a, chLatin_t + , chLatin_i, chLatin_o, chLatin_n, chLatin_s, chNull +}; + //Property //Xerces: http://apache.org/xml/properties/schema/external-schemaLocation const XMLCh XMLUni::fgXercesSchemaExternalSchemaLocation[] = diff --git a/src/xercesc/util/XMLUni.hpp b/src/xercesc/util/XMLUni.hpp index 9ec11ee6864fd7917c5f77f6cb22ec244245e8fd..9f4837043175efcbf56330a48fdd1a180d41dce3 100644 --- a/src/xercesc/util/XMLUni.hpp +++ b/src/xercesc/util/XMLUni.hpp @@ -220,6 +220,7 @@ public : static const XMLCh fgXercesCalculateSrcOfs[]; static const XMLCh fgXercesStandardUriConformant[]; static const XMLCh fgXercesDOMHasPSVIInfo[]; + static const XMLCh fgXercesGenerateSyntheticAnnotations[]; // SAX2 features/properties names static const XMLCh fgSAX2CoreValidation[]; diff --git a/src/xercesc/validators/schema/TraverseSchema.cpp b/src/xercesc/validators/schema/TraverseSchema.cpp index 69694035f7c379072ecdafe12454eb69f69a0f27..bdfd8cf7806399a8f29f8e0509bd3f325ce47778 100644 --- a/src/xercesc/validators/schema/TraverseSchema.cpp +++ b/src/xercesc/validators/schema/TraverseSchema.cpp @@ -141,6 +141,28 @@ const XMLCh* fgIdentityConstraints[] = SchemaSymbols::fgELT_KEYREF }; +const XMLCh fgAnnotation[] = +{ + chLatin_a, chLatin_n, chLatin_n, chLatin_o, chLatin_t, chLatin_a, chLatin_t + , chLatin_i, chLatin_o, chLatin_n, chNull +}; + +const XMLCh fgDocumentation[] = +{ + chLatin_d, chLatin_o, chLatin_c, chLatin_u, chLatin_m, chLatin_e + , chLatin_n, chLatin_t, chLatin_a, chLatin_t + , chLatin_i, chLatin_o, chLatin_n, chNull +}; + +const XMLCh fgSynthetic_Annotation[] = +{ + chLatin_S, chLatin_y, chLatin_n, chLatin_t, chLatin_h, chLatin_e, chLatin_t + , chLatin_i, chLatin_c, chUnderscore + , chLatin_A, chLatin_n, chLatin_n, chLatin_o, chLatin_t, chLatin_a, chLatin_t + , chLatin_i, chLatin_o, chLatin_n, chNull +}; + + // Flags for global declaration enum { ENUM_ELT_SIMPLETYPE, @@ -535,7 +557,7 @@ void TraverseSchema::preprocessInclude(const DOMElement* const elem) { // Check attributes // ----------------------------------------------------------------------- fAttributeCheck.checkAttributes( - elem, GeneralAttributeCheck::E_Include, this, true); + elem, GeneralAttributeCheck::E_Include, this, true, fNonXSAttList); // ----------------------------------------------------------------------- // First, handle any ANNOTATION declaration @@ -545,6 +567,11 @@ void TraverseSchema::preprocessInclude(const DOMElement* const elem) { if (fAnnotation) fSchemaGrammar->addAnnotation(fAnnotation); + else if (fScanner->getGenerateSyntheticAnnotations() && fNonXSAttList->size()) + { + fAnnotation = generateSyntheticAnnotation(elem, fNonXSAttList); + fSchemaGrammar->addAnnotation(fAnnotation); + } // ----------------------------------------------------------------------- // Get 'schemaLocation' attribute @@ -683,7 +710,7 @@ void TraverseSchema::preprocessImport(const DOMElement* const elem) { // Check attributes // ----------------------------------------------------------------------- fAttributeCheck.checkAttributes( - elem, GeneralAttributeCheck::E_Import, this, true); + elem, GeneralAttributeCheck::E_Import, this, true, fNonXSAttList); // ----------------------------------------------------------------------- // First, handle any ANNOTATION declaration @@ -693,7 +720,11 @@ void TraverseSchema::preprocessImport(const DOMElement* const elem) { if (fAnnotation) fSchemaGrammar->addAnnotation(fAnnotation); - + else if (fScanner->getGenerateSyntheticAnnotations() && fNonXSAttList->size()) + { + fAnnotation = generateSyntheticAnnotation(elem, fNonXSAttList); + fSchemaGrammar->addAnnotation(fAnnotation); + } // ----------------------------------------------------------------------- // Handle 'namespace' attribute // ----------------------------------------------------------------------- @@ -955,7 +986,11 @@ TraverseSchema::traverseChoiceSequence(const DOMElement* const elem, // ----------------------------------------------------------------------- // Process contents // ----------------------------------------------------------------------- - DOMElement* child = checkContent(elem, XUtil::getFirstChildElement(elem), true); + DOMElement* child = checkContent(elem, XUtil::getFirstChildElement(elem), true); + if (fScanner->getGenerateSyntheticAnnotations() && !fAnnotation && fNonXSAttList->size()) + { + fAnnotation = generateSyntheticAnnotation(elem, fNonXSAttList); + } Janitor<XSAnnotation> janAnnot(fAnnotation); ContentSpecNode* left = 0; ContentSpecNode* right = 0; @@ -1143,9 +1178,12 @@ TraverseSchema::traverseSimpleTypeDecl(const DOMElement* const childElem, // annotation?,(list|restriction|union) DOMElement* content= checkContent( - childElem, XUtil::getFirstChildElement(childElem), false); + childElem, XUtil::getFirstChildElement(childElem), false); + if (fScanner->getGenerateSyntheticAnnotations() && !fAnnotation && fNonXSAttList->size()) + { + fAnnotation = generateSyntheticAnnotation(childElem, fNonXSAttList); + } Janitor<XSAnnotation> janAnnot(fAnnotation); - if (content == 0) { reportSchemaError(childElem, XMLUni::fgXMLErrDomain, XMLErrs::EmptySimpleTypeContent); @@ -1308,7 +1346,12 @@ int TraverseSchema::traverseComplexTypeDecl(const DOMElement* const elem, // ------------------------------------------------------------------ // First, handle any ANNOTATION declaration and get next child // ------------------------------------------------------------------ - DOMElement* child = checkContent(elem, XUtil::getFirstChildElement(elem), true); + DOMElement* child = checkContent(elem, XUtil::getFirstChildElement(elem), true); + + if (fScanner->getGenerateSyntheticAnnotations() && !fAnnotation && fNonXSAttList->size()) + { + fAnnotation = generateSyntheticAnnotation(elem, fNonXSAttList); + } Janitor<XSAnnotation> janAnnot(fAnnotation); // ------------------------------------------------------------------ @@ -1480,9 +1523,12 @@ TraverseSchema::traverseGroupDecl(const DOMElement* const elem, // ------------------------------------------------------------------ // Check for annotations // ------------------------------------------------------------------ - DOMElement* content = checkContent(elem, XUtil::getFirstChildElement(elem), true); + DOMElement* content = checkContent(elem, XUtil::getFirstChildElement(elem), true); + if (fScanner->getGenerateSyntheticAnnotations() && !fAnnotation && fNonXSAttList->size()) + { + fAnnotation = generateSyntheticAnnotation(elem, fNonXSAttList); + } Janitor<XSAnnotation> janAnnot(fAnnotation); - // ------------------------------------------------------------------ // Process contents of global groups // ------------------------------------------------------------------ @@ -1667,6 +1713,10 @@ TraverseSchema::traverseAttributeGroupDecl(const DOMElement* const elem, // Check for annotations DOMElement* content = checkContent(elem, XUtil::getFirstChildElement(elem), true); + if (fScanner->getGenerateSyntheticAnnotations() && !fAnnotation && fNonXSAttList->size()) + { + fAnnotation = generateSyntheticAnnotation(elem, fNonXSAttList); + } Janitor<XSAnnotation> janAnnot(fAnnotation); // Process contents of global attributeGroups @@ -1808,6 +1858,10 @@ TraverseSchema::traverseAny(const DOMElement* const elem) { // ------------------------------------------------------------------ if (checkContent(elem, XUtil::getFirstChildElement(elem), true) != 0) { reportSchemaError(elem, XMLUni::fgXMLErrDomain, XMLErrs::OnlyAnnotationExpected); + } + if (fScanner->getGenerateSyntheticAnnotations() && !fAnnotation && fNonXSAttList->size()) + { + fAnnotation = generateSyntheticAnnotation(elem, fNonXSAttList); } Janitor<XSAnnotation> janAnnot(fAnnotation); @@ -1979,7 +2033,11 @@ TraverseSchema::traverseAll(const DOMElement* const elem) { // ----------------------------------------------------------------------- // Process contents // ----------------------------------------------------------------------- - DOMElement* child = checkContent(elem, XUtil::getFirstChildElement(elem), true); + DOMElement* child = checkContent(elem, XUtil::getFirstChildElement(elem), true); + if (fScanner->getGenerateSyntheticAnnotations() && !fAnnotation && fNonXSAttList->size()) + { + fAnnotation = generateSyntheticAnnotation(elem, fNonXSAttList); + } Janitor<XSAnnotation> janAnnot(fAnnotation); if (child == 0) { @@ -2165,6 +2223,12 @@ void TraverseSchema::traverseAttributeDecl(const DOMElement* const elem, processAttributeDeclRef(elem, typeInfo, ref, useVal, defaultVal, fixedVal); return; } + + if (fScanner->getGenerateSyntheticAnnotations() && !fAnnotation && fNonXSAttList->size()) + { + fAnnotation = generateSyntheticAnnotation(elem, fNonXSAttList); + janAnnot.reset(fAnnotation); + } // processing 'name' if (!XMLString::isValidNCName(name) @@ -2490,7 +2554,11 @@ TraverseSchema::traverseElementDecl(const DOMElement* const elem, fAttributeCheck.checkAttributes(elem, scope, this, topLevel, fNonXSAttList); // check annotation - const DOMElement* content = checkContent(elem, XUtil::getFirstChildElement(elem), true); + const DOMElement* content = checkContent(elem, XUtil::getFirstChildElement(elem), true); + if (fScanner->getGenerateSyntheticAnnotations() && !fAnnotation && fNonXSAttList->size()) + { + fAnnotation = generateSyntheticAnnotation(elem, fNonXSAttList); + } Janitor<XSAnnotation> janAnnot(fAnnotation); // Create element decl @@ -2732,7 +2800,11 @@ const XMLCh* TraverseSchema::traverseNotationDecl(const DOMElement* const elem) checkContent(elem, XUtil::getFirstChildElement(elem), true); if (fAnnotation) fSchemaGrammar->putAnnotation(decl, fAnnotation); - + else if (fScanner->getGenerateSyntheticAnnotations() && fNonXSAttList->size()) + { + fAnnotation = generateSyntheticAnnotation(elem, fNonXSAttList); + fSchemaGrammar->putAnnotation(decl, fAnnotation); + } return name; } @@ -2817,7 +2889,10 @@ TraverseSchema::traverseByList(const DOMElement* const rootElem, if (!baseTypeName || !*baseTypeName) { // must 'see' <simpleType> content = checkContent(rootElem, XUtil::getFirstChildElement(contentElem), false); - + if (fScanner->getGenerateSyntheticAnnotations() && !fAnnotation && fNonXSAttList->size()) + { + fAnnotation = generateSyntheticAnnotation(contentElem, fNonXSAttList); + } if (fAnnotation) { if (janAnnot->isDataNull()) @@ -2849,7 +2924,10 @@ TraverseSchema::traverseByList(const DOMElement* const rootElem, baseValidator = findDTValidator(contentElem, typeName, baseTypeName, SchemaSymbols::XSD_LIST); content = checkContent(rootElem, XUtil::getFirstChildElement(contentElem), true); - + if (fScanner->getGenerateSyntheticAnnotations() && !fAnnotation && fNonXSAttList->size()) + { + fAnnotation = generateSyntheticAnnotation(contentElem, fNonXSAttList); + } if (fAnnotation) { if (janAnnot->isDataNull()) @@ -2924,7 +3002,10 @@ TraverseSchema::traverseByRestriction(const DOMElement* const rootElem, if (!baseTypeName || !*baseTypeName) { // must 'see' <simpleType> content = checkContent(rootElem, XUtil::getFirstChildElement(contentElem), false); - + if (fScanner->getGenerateSyntheticAnnotations() && !fAnnotation && fNonXSAttList->size()) + { + fAnnotation = generateSyntheticAnnotation(contentElem, fNonXSAttList); + } if (fAnnotation) { if (janAnnot->isDataNull()) @@ -2957,6 +3038,10 @@ TraverseSchema::traverseByRestriction(const DOMElement* const rootElem, baseValidator = findDTValidator(contentElem, typeName, baseTypeName, SchemaSymbols::XSD_RESTRICTION); content = checkContent(rootElem, XUtil::getFirstChildElement(contentElem), true); + if (fScanner->getGenerateSyntheticAnnotations() && !fAnnotation && fNonXSAttList->size()) + { + fAnnotation = generateSyntheticAnnotation(contentElem, fNonXSAttList); + } if (fAnnotation) { if (janAnnot->isDataNull()) @@ -3013,7 +3098,10 @@ TraverseSchema::traverseByRestriction(const DOMElement* const rootElem, } if (XMLString::equals(facetName, SchemaSymbols::fgELT_ENUMERATION)) { - + if (fScanner->getGenerateSyntheticAnnotations() && !fAnnotation && fNonXSAttList->size()) + { + fAnnotation = generateSyntheticAnnotation(content, fNonXSAttList); + } if (fAnnotation) { if (janEnumAnnot.isDataNull()) janEnumAnnot.reset(fAnnotation); @@ -3050,7 +3138,10 @@ TraverseSchema::traverseByRestriction(const DOMElement* const rootElem, } } else if (XMLString::equals(facetName, SchemaSymbols::fgELT_PATTERN)) { - + if (fScanner->getGenerateSyntheticAnnotations() && !fAnnotation && fNonXSAttList->size()) + { + fAnnotation = generateSyntheticAnnotation(content, fNonXSAttList); + } if (fAnnotation) { if (janPatternAnnot.isDataNull()) janPatternAnnot.reset(fAnnotation); @@ -3091,7 +3182,10 @@ TraverseSchema::traverseByRestriction(const DOMElement* const rootElem, const XMLCh* facetStr = fStringPool->getValueForId(fStringPool->addOrFind(facetName)); KVStringPair* kv = new (fGrammarPoolMemoryManager) KVStringPair(facetStr, attValue, fGrammarPoolMemoryManager); - + if (fScanner->getGenerateSyntheticAnnotations() && !fAnnotation && fNonXSAttList->size()) + { + fAnnotation = generateSyntheticAnnotation(content, fNonXSAttList); + } if (fAnnotation) fSchemaGrammar->putAnnotation(kv, fAnnotation); @@ -3188,6 +3282,10 @@ TraverseSchema::traverseByUnion(const DOMElement* const rootElem, } content = checkContent(rootElem, XUtil::getFirstChildElement(contentElem), true); + if (fScanner->getGenerateSyntheticAnnotations() && !fAnnotation && fNonXSAttList->size()) + { + fAnnotation = generateSyntheticAnnotation(contentElem, fNonXSAttList); + } if (fAnnotation) { if (janAnnot->isDataNull()) @@ -3199,6 +3297,10 @@ TraverseSchema::traverseByUnion(const DOMElement* const rootElem, else { // must 'see' <simpleType> content = checkContent(rootElem, XUtil::getFirstChildElement(contentElem), false); + if (fScanner->getGenerateSyntheticAnnotations() && !fAnnotation && fNonXSAttList->size()) + { + fAnnotation = generateSyntheticAnnotation(contentElem, fNonXSAttList); + } if (fAnnotation) { if (janAnnot->isDataNull()) @@ -3321,6 +3423,10 @@ void TraverseSchema::traverseSimpleContentDecl(const XMLCh* const typeName, // Process annotation if any // ----------------------------------------------------------------------- DOMElement* simpleContent = checkContent(contentDecl, XUtil::getFirstChildElement(contentDecl), false); + if (fScanner->getGenerateSyntheticAnnotations() && !fAnnotation && fNonXSAttList->size()) + { + fAnnotation = generateSyntheticAnnotation(contentDecl, fNonXSAttList); + } if (fAnnotation) { if (janAnnot->isDataNull()) @@ -3437,6 +3543,10 @@ void TraverseSchema::traverseSimpleContentDecl(const XMLCh* const typeName, // ----------------------------------------------------------------------- //Skip over any annotations in the restriction or extension elements DOMElement* content = checkContent(simpleContent, XUtil::getFirstChildElement(simpleContent), true); + if (fScanner->getGenerateSyntheticAnnotations() && !fAnnotation && fNonXSAttList->size()) + { + fAnnotation = generateSyntheticAnnotation(simpleContent, fNonXSAttList); + } if (fAnnotation) { if (janAnnot->isDataNull()) @@ -3725,6 +3835,10 @@ void TraverseSchema::traverseComplexContentDecl(const XMLCh* const typeName, typeInfo->setBaseDatatypeValidator(0); DOMElement* complexContent = checkContent(contentDecl,XUtil::getFirstChildElement(contentDecl),false); + if (fScanner->getGenerateSyntheticAnnotations() && !fAnnotation && fNonXSAttList->size()) + { + fAnnotation = generateSyntheticAnnotation(contentDecl, fNonXSAttList); + } if (fAnnotation) { if (janAnnot->isDataNull()) @@ -3797,7 +3911,7 @@ void TraverseSchema::traverseComplexContentDecl(const XMLCh* const typeName, // Process the content of the derivation // ----------------------------------------------------------------------- //Skip over any annotations in the restriction or extension elements - DOMElement* content = checkContent(complexContent, XUtil::getFirstChildElement(complexContent), true); + DOMElement* content = checkContent(complexContent, XUtil::getFirstChildElement(complexContent), true); if (fAnnotation) { if (janAnnot->isDataNull()) @@ -3837,9 +3951,12 @@ SchemaAttDef* TraverseSchema::traverseAnyAttribute(const DOMElement* const elem) // ------------------------------------------------------------------ if (checkContent(elem, XUtil::getFirstChildElement(elem), true) != 0) { reportSchemaError(elem, XMLUni::fgXMLErrDomain, XMLErrs::AnyAttributeContentError); + } + if (fScanner->getGenerateSyntheticAnnotations() && !fAnnotation && fNonXSAttList->size()) + { + fAnnotation = generateSyntheticAnnotation(elem, fNonXSAttList); } Janitor<XSAnnotation> janAnnot(fAnnotation); - // ------------------------------------------------------------------ // Get attributes // ------------------------------------------------------------------ @@ -4156,6 +4273,10 @@ bool TraverseSchema::traverseIdentityConstraint(IdentityConstraint* const ic, // First, handle any ANNOTATION declaration // ------------------------------------------------------------------ DOMElement* elem = checkContent(icElem, XUtil::getFirstChildElement(icElem), false); + if (fScanner->getGenerateSyntheticAnnotations() && !fAnnotation && fNonXSAttList->size()) + { + fAnnotation = generateSyntheticAnnotation(icElem, fNonXSAttList); + } Janitor<XSAnnotation> janAnnot(fAnnotation); // ------------------------------------------------------------------ @@ -4177,6 +4298,10 @@ bool TraverseSchema::traverseIdentityConstraint(IdentityConstraint* const ic, elem, GeneralAttributeCheck::E_Selector, this, false, fNonXSAttList ); checkContent(icElem, XUtil::getFirstChildElement(elem), true); + if (fScanner->getGenerateSyntheticAnnotations() && !fAnnotation && fNonXSAttList->size()) + { + fAnnotation = generateSyntheticAnnotation(elem, fNonXSAttList); + } if (fAnnotation) { if (janAnnot.isDataNull()) @@ -4257,6 +4382,10 @@ bool TraverseSchema::traverseIdentityConstraint(IdentityConstraint* const ic, elem, GeneralAttributeCheck::E_Field, this, false, fNonXSAttList ); checkContent(icElem, XUtil::getFirstChildElement(elem), true); + if (fScanner->getGenerateSyntheticAnnotations() && !fAnnotation && fNonXSAttList->size()) + { + fAnnotation = generateSyntheticAnnotation(elem, fNonXSAttList); + } if (fAnnotation) { if (janAnnot.isDataNull()) @@ -4363,6 +4492,7 @@ void TraverseSchema::retrieveNamespaceMapping(const DOMElement* const schemaRoot void TraverseSchema::processChildren(const DOMElement* const root) { + bool sawAnnotation = false; // process <redefine>, <include> and <import> info items. DOMElement* child = XUtil::getFirstChildElement(root); @@ -4375,6 +4505,7 @@ void TraverseSchema::processChildren(const DOMElement* const root) { traverseAnnotationDecl( child, fSchemaInfo->getNonXSAttList(), true) ); + sawAnnotation = true; } else if (XMLString::equals(name, SchemaSymbols::fgELT_INCLUDE)) { traverseInclude(child); @@ -4410,6 +4541,7 @@ void TraverseSchema::processChildren(const DOMElement* const root) { traverseAnnotationDecl( child, fSchemaInfo->getNonXSAttList(), true) ); + sawAnnotation = true; } else if (XMLString::equals(name, SchemaSymbols::fgELT_SIMPLETYPE)) { @@ -4522,6 +4654,15 @@ void TraverseSchema::processChildren(const DOMElement* const root) { } } // for each child node + + if (fSchemaInfo->getNonXSAttList()->size() && !sawAnnotation) + { + // synthesize a global annotation here. + fSchemaGrammar->addAnnotation( + generateSyntheticAnnotation(root, fSchemaInfo->getNonXSAttList()) + ); + } + // Handle recursing elements - if any ValueVectorOf<const DOMElement*>* recursingAnonTypes = fSchemaInfo->getRecursingAnonTypes(); @@ -4784,6 +4925,8 @@ TraverseSchema::processElementDeclRef(const DOMElement* const elem, DOMElement* content = checkContent(elem, XUtil::getFirstChildElement(elem), true); Janitor<XSAnnotation> janAnnot(fAnnotation); + // do not generate synthetic annotation for element reference... + if (content != 0) reportSchemaError(elem, XMLUni::fgValidityDomain, XMLValid::NoContentForRef, SchemaSymbols::fgELT_ELEMENT); @@ -8586,6 +8729,148 @@ void TraverseSchema::processAttValue(const XMLCh* const attVal, } } +XSAnnotation* TraverseSchema::generateSyntheticAnnotation(const DOMElement* const elem + , ValueVectorOf<DOMNode*>* nonXSAttList) +{ + const XMLCh* prefix = elem->getPrefix(); + ValueVectorOf<unsigned int>* listOfURIs = new (fMemoryManager) ValueVectorOf<unsigned int>(16, fMemoryManager); + bool sawXMLNS = false; + + fBuffer.reset(); + fBuffer.append(chOpenAngle); + if (prefix) + { + fBuffer.append(prefix); + fBuffer.append(chColon); + } + fBuffer.append(fgAnnotation); + + // next is the nonXSAttList names & values + unsigned int nonXSAttSize = nonXSAttList->size(); + + for (unsigned int i=0; i<nonXSAttSize; i++) + { + DOMNode* attNode = nonXSAttList->elementAt(i); + + fBuffer.append(chSpace); + fBuffer.append(attNode->getNodeName()); + fBuffer.append(chEqual); + fBuffer.append(chDoubleQuote); + processAttValue(attNode->getNodeValue(), fBuffer); + fBuffer.append(chDoubleQuote); + } + + // next is the namespaces on the elem + DOMNamedNodeMap* eltAttrs = elem->getAttributes(); + int attrCount = eltAttrs->getLength(); + + for (int j = 0; j < attrCount; j++) + { + DOMNode* attribute = eltAttrs->item(j); + const XMLCh* attName = attribute->getNodeName(); + + if (XMLString::startsWith(attName, XMLUni::fgXMLNSColonString)) + { + fBuffer.append(chSpace); + fBuffer.append(attName); + fBuffer.append(chEqual); + fBuffer.append(chDoubleQuote); + processAttValue(attribute->getNodeValue(), fBuffer); + fBuffer.append(chDoubleQuote); + + int offsetIndex = XMLString::indexOf(attName, chColon); + int prefixId = fNamespaceScope->getNamespaceForPrefix(attName + offsetIndex + 1, fSchemaInfo->getNamespaceScopeLevel()); + if (prefixId) + listOfURIs->addElement(prefixId); + } + else if (XMLString::equals(attName, XMLUni::fgXMLNSString)) + { + fBuffer.append(chSpace); + fBuffer.append(attName); + fBuffer.append(chEqual); + fBuffer.append(chDoubleQuote); + processAttValue(attribute->getNodeValue(), fBuffer); + fBuffer.append(chDoubleQuote); + sawXMLNS = true; + } + } + + // next is the namespaces on the fSchemaRoot + eltAttrs = fSchemaInfo->getRoot()->getAttributes(); + attrCount = eltAttrs->getLength(); + + for (int j = 0; j < attrCount; j++) + { + DOMNode* attribute = eltAttrs->item(j); + if (!attribute) { + break; + } + const XMLCh* attName = attribute->getNodeName(); + + if (XMLString::startsWith(attName, XMLUni::fgXMLNSColonString)) + { + int offsetIndex = XMLString::indexOf(attName, chColon); + int prefixId = fNamespaceScope->getNamespaceForPrefix(attName + offsetIndex + 1, fSchemaInfo->getNamespaceScopeLevel()); + + if (!listOfURIs->containsElement(prefixId)) { + fBuffer.append(chSpace); + fBuffer.append(attName); + fBuffer.append(chEqual); + fBuffer.append(chDoubleQuote); + processAttValue(attribute->getNodeValue(), fBuffer); + fBuffer.append(chDoubleQuote); + } + } + else if (!sawXMLNS && XMLString::equals(attName, XMLUni::fgXMLNSString)) + { + fBuffer.append(chSpace); + fBuffer.append(attName); + fBuffer.append(chEqual); + fBuffer.append(chDoubleQuote); + processAttValue(attribute->getNodeValue(), fBuffer); + fBuffer.append(chDoubleQuote); + } + } + delete listOfURIs; + + fBuffer.append(chCloseAngle); + fBuffer.append(chLF); + fBuffer.append(chOpenAngle); + if (prefix) + { + fBuffer.append(prefix); + fBuffer.append(chColon); + } + fBuffer.append(fgDocumentation); + fBuffer.append(chCloseAngle); + fBuffer.append(fgSynthetic_Annotation); + fBuffer.append(chOpenAngle); + fBuffer.append(chForwardSlash); + if (prefix) + { + fBuffer.append(prefix); + fBuffer.append(chColon); + } + fBuffer.append(fgDocumentation); + fBuffer.append(chCloseAngle); + fBuffer.append(chLF); + fBuffer.append(chOpenAngle); + fBuffer.append(chForwardSlash); + if (prefix) + { + fBuffer.append(prefix); + fBuffer.append(chColon); + } + fBuffer.append(fgAnnotation); + fBuffer.append(chCloseAngle); + + XSAnnotation* annot = new (fGrammarPoolMemoryManager) XSAnnotation(fBuffer.getRawBuffer(), fGrammarPoolMemoryManager); + annot->setLineCol( ((XSDElementNSImpl*)elem)->getLineNo() + , ((XSDElementNSImpl*)elem)->getColumnNo() ); + annot->setSystemId(fSchemaInfo->getCurrentSchemaURL()); + return annot; +} + XERCES_CPP_NAMESPACE_END /** diff --git a/src/xercesc/validators/schema/TraverseSchema.hpp b/src/xercesc/validators/schema/TraverseSchema.hpp index 76bc08d02d4c2d3f3d5ca0a0355390933625db5e..551351677d62ec28e2781a422a873950f3ccf857 100644 --- a/src/xercesc/validators/schema/TraverseSchema.hpp +++ b/src/xercesc/validators/schema/TraverseSchema.hpp @@ -683,6 +683,9 @@ private: void processAttValue(const XMLCh* const attVal, XMLBuffer& aBuf); + // routine to generate synthetic annotations + XSAnnotation* generateSyntheticAnnotation(const DOMElement* const elem + , ValueVectorOf<DOMNode*>* nonXSAttList); // ----------------------------------------------------------------------- // Private constants // -----------------------------------------------------------------------